2009/7/28 David Miller <dmiller2...@gmail.com>

>
> (let [ x (or nil 4)
>        y (or 2 6)
>        z (or nil 10)]
>  (+ x y z))
>
> => 16
>
> This use of 'or' is fairly idiomatic, and not just in Lispish.  Less
> typing than 'if'.  And you can use it or not, unlike i-let, which
> forces you to put in a default for all bindings.
>

Unless you want the default value for a non initialized boolean value to be
true ...

(let [x (or false true)] => whooops



>
> Regarding the implementation of i-let, if the intention is as above,
> then I'm guessing the macroexpansion of
>
> (i-let [ x *something* 4] (* x x))
>
> should be equivalent to
>
> (let [x (or *something* 4)] (* x x))
>
> However, in the given implementation, the decision is made at
> macroexpansion time whether to expand to
>
> (let [ x *something*] (* x x))    ;; expansion A
>
> or
>
> (let [x 4] (* x x))           ;; expansion B
>
> and the decision is not made on the _value_ of *something* but on the
> literal source code.  Since in this case (binding 1) is *something*, a
> Symbol and definitely not nil, expansion A will be chosen, independent
> of the value of *something*.  Easily fixed by embedding the if test
> inside the let rather than the other way around.  (And if I have
> missed the point of i-let, please ignore all I've said.)
>
> David
>
> On Jul 27, 7:33 pm, nchubrich <nicholas.chubr...@gmail.com> wrote:
> > I've been learning Clojure.  I just wrote a macro to be used like so:
> > (i-let [x nil 4
> >          y 2 6
> >          z nil 10]
> >   (+ x y z))
> > => 16
> >
> > I.E. if the first value in the triple is nil, bind it to the second
> > value in the triple.  This is useful when you want to let something
> > that might be nil and has a sensible default.  (In practice I only see
> > the need to do this \once, but I wrote it for multiple bindings for
> > generality.  And yes, I'm too lazy to type an if statement every
> > time.)
> >    Here's the code:
> >
> > (defmacro i-let [bindings body]
> >   (assert-args i-let
> >     (vector? bindings) "a vector for its bindings"
> >     (= 0 (mod (count bindings) 3)) "forms by three in binding vector")
> >   (if (empty? bindings)
> >     `(let ~bindings ~body)
> >   (let [nom (bindings 0)
> >          attempted-val (bindings 1)
> >          nil-val (bindings 2)]
> >     (if (nil? attempted-val)
> >     `(let [~nom ~nil-val] (i-let ~(vec (drop 3 bindings)) ~body))
> >     `(let [~nom ~attempted-val] (i-let ~(vec (drop 3 bindings))
> > ~body))))))
> >
> > Note that I've stolen the private code for assert-args----why, by the
> > way, is this private?
> >    Anyway I'd appreciate any critiques of the implementation; whether
> > it's a useful thing or not; if there are more idiomatic ways of doing
> > the same thing; and, if yes-no to the aforetwo, where's the best place
> > to add this functionality?
> >    I've really been enjoying this language (I come from a Scheme
> > background).  One stumbling block for me is the seq functions.  I'd
> > really like versions of them that preserve the underlying type (so
> > that, for instance, in the above macro I could just write "(drop 3
> > bindings)" instead of "(vec (drop 3 bindings))".  What is the reason
> > for them only returning a common type?
> >
> > Thanks,
> >
> > Nick Chubrich.
> >
>

--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to