I tried to leave a comment on your blog, but it's not clear to me if
it's being held for moderation, or simply failed.  So I'll paste it
here too.

On Tue, Sep 30, 2008 at 10:06 AM, Fogus <[EMAIL PROTECTED]> wrote:
>
> In an attempt to get a feel for Clojure I have started porting Paul
> Graham's "On Lisp".

This is cool.  "On Lisp" is what convinced me Lisp was actually worth
understanding, and without that I would never have given Clojure a
chance.

> Feel free to tear my source to shreds whenever I am breaking Clojure
> idioms and/or simply incorrect in my comments.

Since you're inviting comments...

remove-if uses "regular" recursion, but because the JVM does not
optimize away tail calls the way Common Lisp (usually) does, this
could fail for very long lists.  However, if you just replace "cons"
with "lazy-cons" and the other recursive call with "recur", you'll
have a beautiful lazy sequence function that will never blow the call
stack.

I'm sure you've noticed that Graham is taking some pains to make
tail-recusive versions of his functions.  In general to take advantage
of this you'll want to use "recur" instead of the tail call.

It's more idiomatic (and more succinct!) to say (if (seq lst) ...)
than (if (nil? lst) nil ...)   Also better to use (let [tri (fn [c n]
...)] (tri 0 n)) than to have a defn nested inside another defn, since
the inner defn is still defining a namespace-global name, even though
it's nested.

Finally I noticed your clever use of Java arrays to get mutability.
This is fine, in that you'll often find yourself in Clojure working
with mutable Java objects, and you just have to deal with it.
However, Clojure also provides some very nice multi-threading features
if you use refs of immutables instead of mutable objects.

In your case, you could replace (let [counter (to-array [0])] ...)
with (def counter (ref 0)).  Then use @counter instead of aget, and
use (dosync (set-ref ...)) instead of aset.  For more details on refs,
see http://clojure.org/refs

Anyway, don't let me discourage you -- I'm sure working through On
Lisp will be a great way for you to learn Clojure, and will likely
help others too.  I'm very interested to see the DSLs of the later
chapters in Clojure.  Keep it up!

--Chouser

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

Reply via email to