This message is not specifically in reply to Tim, but to the thread in general.
It can be very difficult to enumerate (or even remember :) all of the
contending tradeoffs around something like Clojure's nil handling.
The is no doubt nil punning is a form of complecting. But you don't completely
remove all issues merely by using empty collections and empty?, you need
something like Maybe and then things get really gross (IMO, for a concise
dynamic language).
I like nil punning, and find it to be a great source of generalization and
reduction of edge cases overall, while admitting the introduction of edges in
specific cases. I am with Tim in preferring CL's approach over Scheme's, and
will admit to personal bias and a certain comfort level with its (albeit small)
complexity.
However, it couldn't be retained everywhere. In particular, two things conspire
against it. One is laziness. You can't actually return nil on rest without
forcing ahead. Clojure old timers will remember when this was different and the
problems it caused. I disagree with Mark that this is remains significantly
complected, nil is not an empty collection, nil is nothing.
Second, unlike in CL where the only 'type' of empty collection is nil and cons
is not polymorphic, in Clojure conj *is* polymorphic and there can only be one
data type created for (conj nil ...), thus we have [], {}, and empty?. Were
data structures to collapse to nil on emptying, they could not be refilled and
retain type.
At this point, this discussion is academic as nothing could possibly change in
this area.
The easiest way to think about is is that nil means nothing, and an empty
collection is not nothing. The sequence functions are functions of collection
to (possibly lazy) collection, and seq/next is forcing out of laziness. No one
is stopping you from using rest and empty?, nor your friend from using next and
conditionals. Peace!
Rich
On Oct 21, 2011, at 4:25 PM, daly wrote:
> On Fri, 2011-10-21 at 15:41 -0400, David Nolen wrote:
>> Just because we have dynamic types does not give us the freedom to not
>> consider them.
>
> If all of these dynamics types and all of the tests "respected nil"
> in its many meanings then
> (when s ...,
> (when (seq s)...,
> (when (empty? s)...,
> would not be an issue. (when s...) would "just work".
>
>>
>>
>> Clearly express a consideration about the types at play.
>
> Clojure was supposed to transparently substitute things like sequences
> and vectors everywhere that lisp used lists. That would be true if nil
> was respected but is not true now and this complicates the code without
> apparent benefit, in my opinion.
>
> In lisp you can ask what the type is (e.g. by calling consp, vectorp,
> etc) but these type-specific predicates are relatively rarely used.
> In fact, when they are used then you are struggling with data-level
> issue that could probably be abstracted away (e.g. a code smell).
>
> Clojure is a great language but the nil handling is, in my opinion,
> a design flaw. It forces the introduction of (empty?...) and an
> awareness of the data types into view unnecessarily.
>
> Tim Daly
> Literate Software
>
>
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to [email protected]
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> [email protected]
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en