Re: A tale of cond, clauses, and the docs
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 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
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
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
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
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