Hacker News new | past | comments | ask | show | jobs | submit login

There are others who don't hate LOOP.

Me for example. The by far best looping construct is Jonathan Amsterdam's ITERATE. But that is LOOP on steroids. LOOP is surprisingly practical. ITERATE is even more practical and has more parentheses. ;-) But since LOOP is there, it's good enough for a lot of purposes...

There are several objections against LOOP:

* another language. Don't use Common Lisp is embedded languages are a problem. ;-)

* the syntax. Okay.

* Spec is not good enough. For me it is good enough.

* Not enough parentheses -> ITERATE.

* non-extensible -> LOOP variants or ITERATE

I've used all kinds of stuff when it comes to loops and iterations.

Bad: tail recursion. Worse: RECUR in Clojure. Both lead to hard to maintain and hard to read code. I've one believes in Functional Programming, it might look attractive. But I don't buy that. Having read and refactored a lot of these constructs, I find them hard to maintain.

LOOP: very useful in many cases.

Series: hard to extend

ITERATE: cool, everything I want.

Btw., LOOP comes from Interlisp from the 70s and was called FOR. The idea was to have english-like embedded languages. It was then moved and extended to Maclisp, and from there to Lisp Machine Lisp and then Common Lisp.




The common-lisp.net page for ITERATE has this example for finding the longest list in a list of lists:

  (iterate (for elt in list-of-lists)
           (finding elt maximizing (length elt)))
But what's wrong with this?

  (reduce (lambda (a b) (if (> (length b) (length a)) b a))
          list-of-lists)
Okay, you have to do a little more work if you only want to take the length of each list once instead of twice. But if you don't care about that, this is quite elegant and introduces no new vocabulary. (Unless the lists are very long, calling LENGTH twice isn't anywhere near twice the cost of calling it once, because of cache effects.)


The reduce code is just not very declarative. I have to inspect the code and i need to have a mental model of REDUCE (which is not trivial). What is b and what is a? I need a mental model of ITERATE too, but the declarative wording gives hints what it is supposed to do.

Code like above is simply less readable. There are lots of uses of REDUCE which are simple to understand. Code like above, less so - where I need to write a special purpose function.

Another problem is that you need to think about the corner cases:

    (reduce (lambda (a b) (if (> (length b) (length a)) b a))
            '())
-> Error

Also you can see that the REDUCE version is slower. Usually there will be a function call overhead - unless the compiler has some optimization for that in some optimize level. Also 'LENGTH' is called multiple times on the longest list so far. You could work around that in REDUCE ... In ITERATE this is not needed: it calls LENGTH only once per list item.


You always need to think about the corner cases. What is the longest element in an empty list of lists? It might be better to get an error in such a case than to have an empty list returned, since that's not an element of the input list, in violation of one possible interpretation of the function's specification.

> Code like above is simply less readable.

I write code like this all the time, and have for 35 years. I think it's perfectly readable.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: