Fully lazy sequences are here!

23 views
Skip to first unread message

Rich Hickey

unread,
Feb 17, 2009, 2:43:18 PM2/17/09
to Clojure
I've merged the lazy branch into trunk, SVN rev 1287

Please do not rush to this version unless you are a library/tool
developer. Let them do their ports and chime in on their progress.
Move only when the libs/tools you depend upon have been ported.

Thanks to all for your feedback and input!

Rich

Chouser

unread,
Feb 17, 2009, 3:47:05 PM2/17/09
to clo...@googlegroups.com
On Tue, Feb 17, 2009 at 2:43 PM, Rich Hickey <richh...@gmail.com> wrote:
>
> I've merged the lazy branch into trunk, SVN rev 1287
>
> Please do not rush to this version unless you are a library/tool
> developer. Let them do their ports and chime in on their progress.
> Move only when the libs/tools you depend upon have been ported.

I've just merged contrib's lazy branch into trunk, since I couldn't
think of any reason not to -- contrib svn 478

So nobody should upgrade contrib now either, unless you're working on
fixing it for Clojure svn rev 1287.

Contrib authors: the lazy branch is still there, but it's probably
best to ignore it now and make all further lazy changes to trunk. If
it seems to be working, we can delete the lazy branch later. Thanks
Stuart for setting that up and getting a bunch of key changes in.

--Chouser

Frantisek Sodomka

unread,
Feb 17, 2009, 4:16:02 PM2/17/09
to Clojure
That was fast! ;-)

Rich, I am porting test_clojure and old 'cycle' worked as:
(cycle []) => nil

Currently:
(cycle []) => java.lang.StackOverflowError

Frantisek

Rich Hickey

unread,
Feb 17, 2009, 9:54:20 PM2/17/09
to Clojure


On Feb 17, 4:16 pm, Frantisek Sodomka <fsodo...@gmail.com> wrote:
> That was fast! ;-)
>
> Rich, I am porting test_clojure and old 'cycle' worked as:
> (cycle []) => nil
>
> Currently:
> (cycle []) => java.lang.StackOverflowError
>

Fixed in svn 1290 - thanks for the report.

Rich

Chouser

unread,
Feb 17, 2009, 10:47:25 PM2/17/09
to clo...@googlegroups.com
On Tue, Feb 17, 2009 at 3:47 PM, Chouser <cho...@gmail.com> wrote:
> On Tue, Feb 17, 2009 at 2:43 PM, Rich Hickey <richh...@gmail.com> wrote:
>>
>> Please do not rush to this version unless you are a library/tool
>> developer. Let them do their ports and chime in on their progress.
>> Move only when the libs/tools you depend upon have been ported.

Clojure-contrib svn rev 482 can now be compiled and built into a .jar
with Clojure svn rev 1291. This includes patches to several contrib
libs from several authors, but I assume not all of the contrib libs
have been throughly tested yet.

--Chouser

Frantisek Sodomka

unread,
Feb 18, 2009, 5:22:29 AM2/18/09
to Clojure
There is something that confuses me:
user=> (cycle [])
()

user=> (= (cycle []) ())
true
user=> (= (cycle []) nil)
true
user=> (= () nil)
false

Thanks for answering, Frantisek

Mark Volkmann

unread,
Feb 18, 2009, 6:39:33 AM2/18/09
to clo...@googlegroups.com
Now that next is recommended over rest, should nthrest be renamed to nthnext?

--
R. Mark Volkmann
Object Computing, Inc.

Frantisek Sodomka

unread,
Feb 18, 2009, 7:12:16 AM2/18/09
to Clojure
I believe it's already done.

Frantisek

Rich Hickey

unread,
Feb 18, 2009, 11:18:42 AM2/18/09
to Clojure


On Feb 18, 5:22 am, Frantisek Sodomka <fsodo...@gmail.com> wrote:
> There is something that confuses me:
> user=> (cycle [])
> ()
>
> user=> (= (cycle []) ())
> true
> user=> (= (cycle []) nil)
> true
> user=> (= () nil)
> false
>

Fixed in svn 1292 - thanks for the report.

Rich

Frantisek Sodomka

unread,
Feb 18, 2009, 11:46:18 AM2/18/09
to Clojure
What about 'conj'? Documentation says:
(conj nil item) returns (item).

Currently:
user=> (conj nil 1)
(1)
user=> (conj () 1)
(1)

Idiom "conj nil" is used in 'reverse': (reduce conj nil coll)
Currently:
user=> (reverse [1 2])
(2 1)
user=> (reverse [1])
(1)
user=> (reverse [])
nil

It looks that now all sequence functions return () instead of nil. Is
'reverse' correct?

Thank you, Frantisek


On Feb 17, 8:43 pm, Rich Hickey <richhic...@gmail.com> wrote:

Frantisek Sodomka

unread,
Feb 18, 2009, 11:54:53 AM2/18/09
to Clojure
Or maybe more general question: Is there any function in Clojure which
when returning empty sequence, returns nil instead of () ???

user=> (butlast [1 2 3])
(1 2)
user=> (butlast [1])
nil
user=> (butlast [])
nil

Thanks, Frantisek

Chouser

unread,
Feb 18, 2009, 11:58:35 AM2/18/09
to clo...@googlegroups.com
On Wed, Feb 18, 2009 at 11:46 AM, Frantisek Sodomka <fsod...@gmail.com> wrote:
>
> What about 'conj'? Documentation says:
> (conj nil item) returns (item).
>
> Currently:
> user=> (conj nil 1)
> (1)
> user=> (conj () 1)
> (1)

Is there something wrong with that? It looks right and like it
matches the docs to me.

> Idiom "conj nil" is used in 'reverse': (reduce conj nil coll)
> Currently:
> user=> (reverse [1 2])
> (2 1)
> user=> (reverse [1])
> (1)
> user=> (reverse [])
> nil
>
> It looks that now all sequence functions return () instead of nil. Is
> 'reverse' correct?

Things that return lazy seqs now return an empty lazy seq, which
prints as (), instead of nil. However, 'reverse' is not lazy and
normally returns a PersistentList. I don't know that it'd be more
correct to return an empty PersistentList than to return nil as it
does now.

--Chouser

Frantisek Sodomka

unread,
Feb 18, 2009, 12:20:32 PM2/18/09
to Clojure
How should I say it... It just didn't look "symmetrical" to me.

So, basically, there is a difference between functions returning
sequences - depending on if they are lazy or eager. Hmm...

user=> (reverse [])
nil
user=> (if (reverse []) true false)
false
user=> (if (seq (reverse [])) true false)
false

user=> (lazy-seq nil)
()
user=> (seq (lazy-seq nil))
nil
user=> (if (lazy-seq nil) true false)
true
user=> (if (seq (lazy-seq nil)) true false)
false

As long as I remember which function is lazy and which one is eager, I
should be fine then.

Just wanted to really understand it.

Thanks, Frantisek


On Feb 18, 5:58 pm, Chouser <chou...@gmail.com> wrote:

Rich Hickey

unread,
Feb 18, 2009, 2:02:57 PM2/18/09
to Clojure


On Feb 18, 12:20 pm, Frantisek Sodomka <fsodo...@gmail.com> wrote:
> How should I say it... It just didn't look "symmetrical" to me.
>
> So, basically, there is a difference between functions returning
> sequences - depending on if they are lazy or eager. Hmm...
>
> user=> (reverse [])
> nil
> user=> (if (reverse []) true false)
> false
> user=> (if (seq (reverse [])) true false)
> false
>
> user=> (lazy-seq nil)
> ()
> user=> (seq (lazy-seq nil))
> nil
> user=> (if (lazy-seq nil) true false)
> true
> user=> (if (seq (lazy-seq nil)) true false)
> false
>
> As long as I remember which function is lazy and which one is eager, I
> should be fine then.
>
> Just wanted to really understand it.
>

It shouldn't be that subtle. Sequence functions shouldn't return nil
unless they are variants of seq/next. I've fixed reverse and sort to
return () when passed empty colls - SVN 1294.

Rich.

Stefan Rusek

unread,
Feb 18, 2009, 2:09:15 PM2/18/09
to clo...@googlegroups.com

Wouldn't it make more sense to to return an empty version of the same
collection type? That way the following would work more like someone
would expect.

(conj (rest [1]) 2) -> [2] instead of (2)

--Stefan

Rich Hickey

unread,
Feb 18, 2009, 2:23:45 PM2/18/09
to Clojure


On Feb 18, 2:09 pm, Stefan Rusek <sru...@gmail.com> wrote:
That's not what I would expect. rest returns a sequence in O(1). It
can't efficiently do otherwise for all collections.

Rich

Frantisek Sodomka

unread,
Feb 18, 2009, 4:50:24 PM2/18/09
to Clojure
At this point test-clojure doesn't generate any new failures or errors
(except the old 'mod' function failures). Coverage is still relatively
small, but (cycle []) bug and case of (reverse []) were caught with
its help when rewriting tests :-)

Thanks for all the fixes!

Frantisek

mifrai

unread,
Feb 18, 2009, 11:49:28 PM2/18/09
to Clojure
Thanks Rich!

Do you think it's worthwhile to add `not-empty?' in the core?

It just feels more natural to go:
(when (not-empty? (filter even? [1 2]))
...)
over
(when (seq (filter ..)) ..)

What do you think?

- Mike

Arthur Ulfeldt

unread,
Feb 19, 2009, 1:27:43 PM2/19/09
to clo...@googlegroups.com
I would like to second this :) it just looks good!
Reply all
Reply to author
Forward
0 new messages