lazy-mapcan: Should fun really return a lazy value?

25 views
Skip to first unread message

Daniel Lundsgaard Skovenborg

unread,
Jan 12, 2017, 4:37:04 PM1/12/17
to Land of Lisp
It seems to me that it is unnecessary for lazy-mapcan (p. 383) to require that the given function (fun) returns a lazy list. The inner function f forces the return value of fun (with lazy-null) and f is only called when items from lazy-mapcan are forced. Thus, the car from the lazy list returned by fun is immediately forced, then the cadr is forced when the next item is forced from lazy-mapcan and so on.
For this reason, the extra level of laziness does not seem to provide anything but forcing (no pun intended) one to use the wrapper functions which seems a bit cumbersome.

I believe that lazy-mapcan can be implemented like this instead:

(defun lazy-mapcan (fun lst)
  (labels ((f (lst-cur)
              (if lst-cur
                (cons (car lst-cur) (lazy (f (cdr lst-cur))))
                (force (lazy-mapcan fun (lazy-cdr lst))))))
          (lazy (unless (lazy-null lst)
                     (f (funcall fun (lazy-car lst)))))))

And the example from the same page in the book can thus be written like this instead:

(take 10 (lazy-mapcan (lambda (x)
                        (if (evenp x)
                            (list x)
                          nil))
                      *integers*))


Have I missed something?

Daniel Lundsgaard Skovenborg

unread,
Jan 12, 2017, 5:30:07 PM1/12/17
to Land of Lisp
Of course I missed that one might want to combine finite lazy lists not created by conversion with make-lazy; there's a lazy-mapcan in a lazy-mapcan on p. 385.
Reply all
Reply to author
Forward
0 new messages