I finally gave the LOOP for Black Belts chapter in Practical Common Lisp a read.  As such I started playing with loops. 
I decided to do a quick test.  One using mapcar and one using loop.  The goal was to turn numeric values from 1-6 into string values containing the numbers 1-6.
'(1 2 3 4 5 6)
into
'("1" "2" "3" "4" "5" "6")
I first tried with mapcar:
(mapcar (lambda (x) (format nil "~a" x)) '(1 2 3 4 5 6))
Then with loop:
(loop for i in '(1 2 3 4 5 6) collect (format nil "~a" i))
Both get the exact same thing done, but there is a difference.  Mapcar doesn't expand with macroexpand-1.  However, when you try to expand the loop you get this:
(MACROLET ((LOOP-FINISH NIL (SYSTEM::LOOP-FINISH-ERROR)))
 (BLOCK NIL
  (LET ((#:G13088 '(1 2 3 4 5 6)))
   (PROGN
    (LET ((I NIL))
     (LET ((#:ACCULIST-VAR-13089 NIL))
      (MACROLET ((LOOP-FINISH NIL '(GO SYSTEM::END-LOOP)))
       (TAGBODY SYSTEM::BEGIN-LOOP (WHEN (ENDP #:G13088) (LOOP-FINISH))
        (SETQ I (CAR #:G13088))
        (PROGN
         (SETQ #:ACCULIST-VAR-13089
          (CONS (FORMAT NIL "~a" I) #:ACCULIST-VAR-13089)))
        (PSETQ #:G13088 (CDR #:G13088)) (GO SYSTEM::BEGIN-LOOP)
        SYSTEM::END-LOOP
        (MACROLET
         ((LOOP-FINISH NIL (SYSTEM::LOOP-FINISH-WARN) '(GO SYSTEM::END-LOOP)))
         (RETURN-FROM NIL
          (SYSTEM::LIST-NREVERSE #:ACCULIST-VAR-13089))))))))))) ;
Loop may be easier to read, but mapcar probably executes less code to get it done.  One other difference is that loop doesn't need to use a lambda.  I'll have to think about that next time I just want to iterate through a list. 
Shaun
Saturday, July 01, 2006
Subscribe to:
Post Comments (Atom)

1 comment:
MAPCAR is a function, LOOP is a (complicated) macro.
(mapcar #'princ-to-string '(1 2 3 4 5 6)) would avoid the lambda with mapcar.
Post a Comment