On Thu, Dec 10, 2009 at 9:15 AM, ngocdaothanh <ngocdaoth...@gmail.com> wrote:
>
> My Clojure code:
> (let [x 1]
>  ...
>  (f x)
>  ...
>  (let [y (+ x 2)]
>    ...
>    (g y)))
>
> It is very difficult to capture the "algorithm" behind the Clojure
> code because things of the same "abstractness" level do not have the
> same indent level.

Note, however, that in this example only the value of (g y) will
be returned.  Granted, if the ... includes conditionals (with
more levels of indenting that aren't shown) there may be other
possible results.  But with the structure given, (f x) for
example must be producing side-effects or it wouldn't be there at
all.  That pushes this code over into the "less than perfectly
idiomatic" category and gets us a little off the topic of why
idiomatic Clojure is written in one particular way or another.

So let's imagine a more complex example, with multiple 'if's and
therefore multiple tail positions, each computing the return
value a different way:

  (let [x 1]
    (if ...
      (let [y (+ x 1)]
        (if ...
          y
          (f x)))
      (let [y (+ x 2)]
        (if ...
          (if ...
            x
            y)
          (g y)))))

Let's set aside for the moment questions about weather all this
really belongs in a single function or if y should be defined in
multiple places.  If we're trying to understand this code we're
going to be repeatedly confronted with the question "where is the
value of foo computed" where foo is x or y.

In almost all languages our eyes would wander up the screen
looking for hints.  In imperative code, we would have to be alert
for any variable assignments like "x = y + 1", regardless of
where they show up -- being in some unrelated "then" clause is no
guarantee you can ignore it if there's any chance it might have
executed before reaching the code in question.  We'd also need to
be alert to any procedure calls that might name x as a parameter
if there's any chance the procedure might modify x.

In Clojure we still need to look farther up the screen, but only
to find out-dented 'let's.  When x is a local holding an
immutable value like an Integer, there is simply no way any code
can muck with it except a 'let' that is directly in the parentage
of the code in question.  This does mean you need to look as
different levels of indentation to find the definition, but it is
a good deal less code and fewer kinds of code than in an
imperative language.

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