Re: A tale of cond, clauses, and the docs

2009-12-20 Thread Michael Wood
2009/12/20 Mike K :
> On Dec 19, 8:27 pm, Sean Devlin  wrote:
>>  :else was chose because it is simply not nil, and therefor always true.
>
> I suspected something along these lines soon after I posted.  I did
> some more experimenting and discovered that :foo will work just as
> well as :else.  So if I understand correctly, :else is not even
> defined in the language anywhere.  Like :foo, it springs into
> existence when I first mention it, and it evaluates to true by virtue
> of being a keyword.  Cond exploits this behavior for free.

Right.  :else is just a convention.  I believe it's borrowed from
Scheme.  As pointed out by ataggart, anything that's logically true
would work just as well.

> This is in contrast with, e.g., the ns macro, which presumably would
> have to explicitly match against keywords such as :use or :require to
> implement the proper semantics.

Yes, because the ns macro treats them as tokens in its mini-language
instead of just something that's logically true.  i.e. their value
matters.  Not just whether or not they can be treated as "true".

-- 
Michael Wood 

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: A tale of cond, clauses, and the docs

2009-12-20 Thread Laurent PETIT
2009/12/20 ataggart 

>
>
> On Dec 19, 8:02 pm, Mike K  wrote:
> > [:foo] evaluates to true by virtue of being a keyword.
>
> To be precise, it evaluates to true by virtue of it not being nil nor
> boolean false; being a keyword doesn't really have anything to do with
> it.
>

To be even more precise, it evaluates to :else. And since :else is neither
the value false neither the value nil, it is considered "logically true".


>
> user=> (cond nil :n false :f (Object.) :t)
> :t
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> 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 clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Re: A tale of cond, clauses, and the docs

2009-12-20 Thread ataggart


On Dec 19, 8:02 pm, Mike K  wrote:
> [:foo] evaluates to true by virtue of being a keyword.

To be precise, it evaluates to true by virtue of it not being nil nor
boolean false; being a keyword doesn't really have anything to do with
it.

user=> (cond nil :n false :f (Object.) :t)
:t

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: A tale of cond, clauses, and the docs

2009-12-19 Thread Mike K
On Dec 19, 8:27 pm, Sean Devlin  wrote:
>  :else was chose because it is simply not nil, and therefor always true.

I suspected something along these lines soon after I posted.  I did
some more experimenting and discovered that :foo will work just as
well as :else.  So if I understand correctly, :else is not even
defined in the language anywhere.  Like :foo, it springs into
existence when I first mention it, and it evaluates to true by virtue
of being a keyword.  Cond exploits this behavior for free.

This is in contrast with, e.g., the ns macro, which presumably would
have to explicitly match against keywords such as :use or :require to
implement the proper semantics.

   Mike

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: A tale of cond, clauses, and the docs

2009-12-19 Thread Sean Devlin
Ah, :else is an unfortunate choice.  The cond macro keeps testing
clauses until it finds one that is true.  :else was chose because it
is simply not nil, and therefor always true.

I would re-write your fn like so:

(defn sign [x] (cond (> x 0) "Positive" (< x 0) "Negative" true
"Zero"))

Sean

On Dec 19, 10:22 pm, Mike K  wrote:
> What, exactly, is a "clause" in clojure?  From seeing the term used in
> context, I inferred that it meant something along the lines of "a
> keyword which can optionally be used to change the semantics of a
> form".  Apparently, it means more than that.
>
> This is valid clojure:
>
> (defn sign [x] (cond (> x 0) "Positive" (< x 0) "Negative" :else
> "Zero"))
>
> I had no idea that I could use :else for the fallthrough case of a
> "cond", so I looked it up in the docs:
>
> user> (doc cond)
> -
> clojure.core/cond
> ([& clauses])
> Macro
>   Takes a set of test/expr pairs. It evaluates each test one at a
>   time.  If a test returns logical true, cond evaluates and returns
>   the value of the corresponding expr and doesn't evaluate any of the
>   other tests or exprs. (cond) returns nil.
>
> Apparently, each "test/expr pair" is a clause, or perhaps each test
> and each expression is a clause.  No mention of supporting an :else
> "clause" though.  Let's check out the source code:
>
> (defmacro cond
>   "Takes a set of test/expr pairs. It evaluates each test one at a
>   time.  If a test returns logical true, cond evaluates and returns
>   the value of the corresponding expr and doesn't evaluate any of the
>   other tests or exprs. (cond) returns nil."
>   [& clauses]
>     (when clauses
>       (list 'if (first clauses)
>             (if (next clauses)
>                 (second clauses)
>                 (throw (IllegalArgumentException.
>                          "cond requires an even number of forms")))
>             (cons 'clojure.core/cond (next (next clauses))
>
> I don't know much about macros, but it is clear that "cond" builds on
> "if".  However, the documentation for "if" mentions nothing
> about :else, and the source for "if" is not available, presumably
> because it's implemented in java.
>
> Is there a way to have discovered the existence of :else from the
> documentation alone?  Is this just an oversight in the docs, or is
> there a more general point concerning clauses that I'm missing?
>
>    Mike

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


A tale of cond, clauses, and the docs

2009-12-19 Thread Mike K
What, exactly, is a "clause" in clojure?  From seeing the term used in
context, I inferred that it meant something along the lines of "a
keyword which can optionally be used to change the semantics of a
form".  Apparently, it means more than that.

This is valid clojure:

(defn sign [x] (cond (> x 0) "Positive" (< x 0) "Negative" :else
"Zero"))

I had no idea that I could use :else for the fallthrough case of a
"cond", so I looked it up in the docs:

user> (doc cond)
-
clojure.core/cond
([& clauses])
Macro
  Takes a set of test/expr pairs. It evaluates each test one at a
  time.  If a test returns logical true, cond evaluates and returns
  the value of the corresponding expr and doesn't evaluate any of the
  other tests or exprs. (cond) returns nil.


Apparently, each "test/expr pair" is a clause, or perhaps each test
and each expression is a clause.  No mention of supporting an :else
"clause" though.  Let's check out the source code:

(defmacro cond
  "Takes a set of test/expr pairs. It evaluates each test one at a
  time.  If a test returns logical true, cond evaluates and returns
  the value of the corresponding expr and doesn't evaluate any of the
  other tests or exprs. (cond) returns nil."
  [& clauses]
(when clauses
  (list 'if (first clauses)
(if (next clauses)
(second clauses)
(throw (IllegalArgumentException.
 "cond requires an even number of forms")))
(cons 'clojure.core/cond (next (next clauses))

I don't know much about macros, but it is clear that "cond" builds on
"if".  However, the documentation for "if" mentions nothing
about :else, and the source for "if" is not available, presumably
because it's implemented in java.

Is there a way to have discovered the existence of :else from the
documentation alone?  Is this just an oversight in the docs, or is
there a more general point concerning clauses that I'm missing?

   Mike

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en