Better then loop/iterate?

Discussion of Common Lisp

Re: Better then loop/iterate?

Postby Jasper » Thu Mar 19, 2009 5:42 am

@gugamilare: Imbarrassed i didn't find that myself, but at least you forgot to check (collect i i)

I guess loop is alright, but it is so damn ugly. It is a stranger in s-expression land. That, in itself is fine by me, but it is also unclear how to convert the thing into s-expressions.

The only thing that minorly annoys about iterate at this point that it uses stuff like (for k from 0 to 100), not many macros do that afaik. However this is easily fixed:
Code: Select all
(require :iterate)
(in-package #:iterate)

(defmacro for-range (var from to)
  `(for ,var from ,from to ,to))

(iter (for-range k 0 10)
      (collect k))
...Excellent
Jasper
 
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands

Re: Better then loop/iterate?

Postby findinglisp » Thu Mar 19, 2009 9:08 am

Jasper wrote:I guess loop is alright, but it is so damn ugly. It is a stranger in s-expression land. That, in itself is fine by me, but it is also unclear how to convert the thing into s-expressions.


Well, LOOP is just one big sexpr. That is, people have always said that LOOP is annoying because it doesn't use more parentheses, but it's never been a big problem for me. I'm not sure that more parentheses would buy me much. Sure, there are definitely advantages of sexpr movement in the editor, etc., but everything in a DO subexpression is a sexpr anyway, and that's where I spend most of my time. I use LOOP in macros all the time and don't really have problems because of lack of sexprs; everything expands as it should. You might have to use PROGN forms a bit to make sure things group, but that's all doable. In other words, the complaint seems to be more of an aesthetic, but less of a practical matter. I have no doubt that somebody could show a situation where LOOP didn't do well in another large macro, but in practice, for me at least, that seems more of a theoretical argument.

IMO, the biggest pains with LOOP are remembering how multiple termination clauses interact with other clauses and such. In other words, it's that it's a whole big complex macro, whatever it's syntax. And I'm assuming ITERATE has some of the same issues since it's basically LOOP with more sexprs. That said, I'm not an ITERATE guru at this point; I have just skimmed the top-level documentation and never used it in practice.
Cheers, Dave
Slowly but surely the world is finding Lisp. http://www.findinglisp.com/blog/
findinglisp
 
Posts: 440
Joined: Sat Jun 28, 2008 7:49 am
Location: Austin, TX

Re: Better then loop/iterate?

Postby Jasper » Thu Mar 19, 2009 12:56 pm

findinglisp wrote:Well, LOOP is just one big sexpr.
Well, without messing with the reader, i would have to be at least one, no?

I agree that much of my reaction to loop is esthetic/emotional, though. And i am also a novice in iterate. I know some real advantages though:
  • Extensible via regular macros and drivers. Would've been nice if they allowed 'regular macros' but only inside the iterate construct, since many of the macros wouldn't make sense outside anyway.
  • The body of iter is a regular body. You can just write any code there if it doesn't collide with iters stuff.
  • An advantage of looking through macroexpansion output is that you can put collector anywhere, including callbacks: iter can:
    Code: Select all
    (in-package #:iterate)
    (defun repeated (n fn) (dotimes (k n) (funcall fn n)))
    (iter (repeat 1)
          (repeated 5 (lambda (x) (collect x))))
    And loop cant:
    Code: Select all
    (loop repeat 1
      do (repeated 5 (lambda (x) (collect x))))
    So iterate can be used in callbacks. Very useful, imo. (I'd even make a (iter-once ..) for it.
Hmm, weird that the manual doesn't list some of these.

umac has all these advantages, plus a bunch of disadvantages(also relative to loop) are:
  • umac macroexpansion produces a whole bunch of stuff in let, flet, macrolet etc. that are not needed. It can't scan whether they are needed.
  • Special stuff that creates toplevel stuff in flet, macrlet, etc. have to be in the list on top of the code. (Although one might not care, not going to read macroexpansion anyway.)
  • It misses some features, many of these can still be fixed, but some not through extensions. Don't know how to do this one though. (Maybe prog and go)
On the other hand, umac is a bit simpler, may be simpler to understand in some cases, and not scanning all the macroexpansions might help.

What is weird that loop is in the specification of common lisp. Didn't these guys hear of 'standard libraries'? They should've called it that and packaged it along. There is some evidence that the powers that be are not(/do not act as if they are) always the cleverest. Exhibit C, A is the credit crisis, and B is the use of many of those other computer languages.
Jasper
 
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands

Re: Better then loop/iterate?

Postby gugamilare » Thu Mar 19, 2009 3:19 pm

I agree that loop shouldn't be standard. It is a monster macro which was firstly created to make the learning process easier for beginners.

What most annoys me is that you can't write

Code: Select all
(loop for elt in list
      (if elt (collect elt)))


I am obligated to write

Code: Select all
(loop for elt in list
      if elt collect elt)


This makes it impossible to do a simple, intuitive thing like this:

Code: Select all
(loop for elt in list
      (case elt
        ((:foo :bar) (do-something-with elt)
        (nil nil)
        (t (collect elt))))


I can even use iterate with mapcar:

Code: Select all
(iter (for list in lists)
      (mapcar #'(lambda (elt) (if elt (collect elt)))
              list))


This is the thing I most miss about loop macro, and I've ran into this kind of problem many times. Good thing that iterate is there ;)
gugamilare
 
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil

Re: Better then loop/iterate?

Postby Jasper » Fri Mar 20, 2009 6:18 am

@gugamilare: I agree that is annoying. It is a problem with not having a regular body as 'body', you either have to reinvent, or leave out simple macros like that.

I made a little project on Berlios I don't expect to be pushing the git much. The dayly tarball hasn't come yet, btw. I also added :initially, :finally. (And added setting what is returned earlier.)
Jasper
 
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands

Re: Better then loop/iterate?

Postby findinglisp » Fri Mar 20, 2009 9:09 am

Jasper wrote:
findinglisp wrote:Well, LOOP is just one big sexpr.
Well, without messing with the reader, i would have to be at least one, no?


Yes, that was my point. :D Often, people talk about loop like it isn't a sexpr at all. It is, of course, just one that doesn't have as much internal structure, but it can still be easily created and manipulated in macros and such.

I agree that much of my reaction to loop is esthetic/emotional, though. And i am also a novice in iterate. I know some real advantages though:
<<lots of good stuff deleted>>


Yup, I agree with most of that. Having COLLECT and friends be "embeddable" (for lack of a better word), would be very helpful. That's also one of my interests in ITERATE.

That said, LOOP is standard and documented, and you can always count on it being there. It certainly has limitations (the extensibility of ITERATE is very interesting, too), but a flawed standard is often better than a perfect extension in terms of creating a baseline for interoperability.
Cheers, Dave
Slowly but surely the world is finding Lisp. http://www.findinglisp.com/blog/
findinglisp
 
Posts: 440
Joined: Sat Jun 28, 2008 7:49 am
Location: Austin, TX

Re: Better then loop/iterate?

Postby gugamilare » Sat Mar 21, 2009 5:39 am

findinglisp wrote:That said, LOOP is standard and documented, and you can always count on it being there. It certainly has limitations (the extensibility of ITERATE is very interesting, too), but a flawed standard is often better than a perfect extension in terms of creating a baseline for interoperability.


Well, I get your point, but don't completelly agree. Having one single implementation of iterate means it will work the same way everywhere. On the other hand, old implementations of clisp didn't support using loop keywords after do, like:

Code: Select all
(loop for elt in list
     do (print elt)
     finally (return list))


I believe one "good" thing of loop being a standard is no dependencies. When I create a small library (like storable-functions), I don't like to make the user to install a library bigger than my library itself just to be "confortable". So I just use loop itself and, whenever I need to collect inside a mapcar, I let around a "with-collectors" macro (like arnesi's).
gugamilare
 
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil

Re: Better then loop/iterate?

Postby findinglisp » Mon Mar 23, 2009 8:53 am

gugamilare wrote:
findinglisp wrote:That said, LOOP is standard and documented, and you can always count on it being there. It certainly has limitations (the extensibility of ITERATE is very interesting, too), but a flawed standard is often better than a perfect extension in terms of creating a baseline for interoperability.


Well, I get your point, but don't completelly agree. Having one single implementation of iterate means it will work the same way everywhere. On the other hand, old implementations of clisp didn't support using loop keywords after do, like:

Code: Select all
(loop for elt in list
     do (print elt)
     finally (return list))


I believe one "good" thing of loop being a standard is no dependencies. When I create a small library (like storable-functions), I don't like to make the user to install a library bigger than my library itself just to be "confortable". So I just use loop itself and, whenever I need to collect inside a mapcar, I let around a "with-collectors" macro (like arnesi's).


I generally agree. I'd caution you on using the clisp experience as anything more than an indication that multiple implementations can read the same spec and simply implement things slightly differently. That is, it's really an example of the issues with a single-spec, multiple-implementation language than any issue with LOOP. If CL was a single-implementation language like Python (largely) or Perl or Ruby, then LOOP would just be LOOP and it would act however it acts.
Cheers, Dave
Slowly but surely the world is finding Lisp. http://www.findinglisp.com/blog/
findinglisp
 
Posts: 440
Joined: Sat Jun 28, 2008 7:49 am
Location: Austin, TX

Re: Better then loop/iterate?

Postby nuntius » Wed Mar 25, 2009 3:21 pm

LOOP came up in a couple interesting talks at ILC09. In fact, the last ILC09 talk was on a semantically (and syntactically) improved descendent of LOOP.

"The Anatomy of a Loop: A Story of Scope and Control" by Olin Shivers
http://www.international-lisp-conferenc ... ivers_olin

The paper can be found at
http://www.ccs.neu.edu/home/shivers/citations.html

The ensuing discussion contained some interesting tidbits from "the old guard". Basically it sounded like "doing it right" would have prevented them from getting it accepted/done. So LOOP was accepted as-is, warts and all. In retrospect, that was the right decision -- Scheme still doesn't have a standard loop construct, and the CL standard was never revised.

In closing, if I were implementing a LOOP-killer (maybe called FROOT or TOGO), I'd start by implementing intermediate languages like LTK and CFG (see the paper). Then play around with the surface interface to see what suits your needs.

- Daniel
User avatar
nuntius
 
Posts: 500
Joined: Sat Aug 09, 2008 10:44 am
Location: Burlington, MA

Re: Better then loop/iterate?

Postby Jasper » Thu Mar 26, 2009 9:20 am

Those look like a good read, i will later.

As for iterate, i have read the code a little. Not sure if the codes approach is the best. (I'd have to read deeper to really make anything of judgement) Also why do people drown their code in comments :? use other files for documentation :(.. Not like we are all programming with only a text editor, we got browsers and all that shit on.. use it! For documentation how it works too. I usually only use single lines of documentations, unless where there are documentation-strings from which i want a good explanation.(I should check how to add/change doc-string after the function is defined.)

Another thing that struck me is this tidbit of the manual. From here.
what iterate doc about higher order functions wrote:One problem with higher-order functions is that they are inefficient, requiring multiple calls on their argument function. While the the built-ins, like map and mapcar, can be open-coded, that cannot be so easily done for user-written functions. Also, using higher-order functions often results in the creation of intermediate sequences that could be avoided if the iteration were written out explicitly.
Isn't that just untrue? If the functions are constant or based on higher-order functions on constants, you should be able to expand them just as macros, with similar results. What i actually consider to be the use for iterate, is that it is more convenient. Especially in iterating while accumulating/collecting it can be very handy.
Jasper
 
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands

PreviousNext

Return to Common Lisp

Who is online

Users browsing this forum: No registered users and 4 guests