[ANN] lazy.rb 0.2

M

MenTaLguY

--=-JYVFo2wxEgbQ6hHxPsff
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable

Now that I'm done asking stupid questions about iterators, it's time for
another release of lazy.rb!

=3D=3D WHAT IS THIS THING? =3D=3D

lazy.rb is a library which provides lazy evaluation for Ruby. It allows
you to optimistically defer computations until they are required.

These deferred computations are represented by "promises":

prom =3D promise { 2 * 3 }
p prom #=3D> #<Lazy::promise computation=3D#<Proc:[email protected]:1>>
result =3D demand prom
p result #=3D> 6
=20
A promise is only evaluated once, after which it becomes essentially
indistinguishable from its result object:

p prom #=3D> 6
p prom.class #=3D> Fixnum

In fact, you can simply use the promise directly and it will be
evaluated for you automatically:

prom =3D promise { 8 + 1 }
num =3D prom * 2
p num #=3D> 18
p prom #=3D> 9

There's one caveat; Ruby always considers promises, evaluated or not, to
be true. If you are testing a result for truth, you must unwrap the
result with demand.

prom =3D promise { false }
demand prom # force evaluation
p prom #=3D> false

puts "wait, it's true?" if prom #=3D> wait, it's true?

puts "no, false. much better." \
unless demand( prom )
#=3D> no, false. much better.

Conveniently, calling demand on an already evaluated promise (or even on
a regular object) is harmless.

p demand( 6 ) #=3D> 6

=3D=3D WHAT'S NEW THIS TIME AROUND? =3D=3D

Kernel#force has been renamed to Kernel#demand, though Kernel#force
still exists as an alias. I'm still wavering on the final name.
Feedback is welcomed.

I've also incorporated a very nice suggestion from Tom Payne, so that
Object#inspect no longer forces the evaluation of a promise. This makes
promises much easier to work with in irb.

The biggest new feature is an API for lazy streams. Lazy streams are
linked lists of deferred computations. Iterating over the list forces
its evaluation, cell by cell. They can be used for many purposes,
including a substitute for generators or threads.

As linked lists, each cell in the stream (Lazy::Cons) has two
attributes: first, and rest. first is the value in that cell, and rest
is a reference to the tail (remainder) of the list.

There is also a Lazy::Stream class, which wraps a lazy stream and
implements Enumerable.

The API tries to make both imperative and "pure" stream creation easy. =20

For example:

# create a stream of lines from stdin
stdin_lines =3D Lazy::generate_stream do |tail|
line =3D $stdin.gets
if line
[ line, tail ]
else
nil
end
end

# create a stream of Fibbonacci numbers
def make_fibs( a=3D1, b=3D0 )
Lazy::cons_stream do
sum =3D a + b
[ sum, make_fibs( b, sum ) ]
end
end
fibs =3D make_fibs

You can use them directly, as linked lists:

# echo lines from stdin
iter =3D stdin_lines
while demand( iter )
puts iter.first
iter =3D iter.rest
end

...or via the Enumerable interface:

# print the Fibbonacci numbers up through 100
enum =3D Lazy::Stream.new( fibs )
enum.each do |n|
puts n
break if n > 100
end

The lazy streams API is still experimental and missing some important
functionality (take and drop, for example), but it's already useful at
this point and I'd like to get some feedback.

=3D=3D WHERE CAN I GET IT? =3D=3D

I've got a small web site here:

http://moonbase.rydia.net/software/lazy.rb/

lazy.rb is available for download as both a tarball and a gem. This is
my first real gem, so let me know if you have any problems with it.

There's also a link to the API documentation, but sadly nothing in the
way of a tutorial yet.

I'll eventually also start publishing my git repository. I keep meaning
to get around to it...

-mental

--=-JYVFo2wxEgbQ6hHxPsff
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQBDm73lcUNIGiXCc4MRApWLAJsEr6+a7Zqv/JYyZL94/7FRSok43gCfVDwm
fR64zX0QUQP2jIgvoUkGbNo=
=bXhQ
-----END PGP SIGNATURE-----

--=-JYVFo2wxEgbQ6hHxPsff--
 
E

Ezra Zygmuntowicz

Now that I'm done asking stupid questions about iterators, it's
time for
another release of lazy.rb!


-mental


Mental-

This is very interesting stuff! Thanks you for your work on it.

Cheers-

-Ezra Zygmuntowicz
WebMaster
Yakima Herald-Republic Newspaper
(e-mail address removed)
509-577-7732
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top