Closed jpellegrini closed 2 months ago
Ah, here's why!
(macro-expand '(dolist (x '(0 1 2) (- x)) (print x)))
(begin
(for-each
(lambda (x1)
(let ((x x1))
(print x)))
'(0 1 2))
(- x))
This probably should have an external LET
for x
, and a set!
instead of let
inside the lambda...
The Common Lisp spec says:
At the time result-form is processed, var is bound to nil.
The Common Lisp spec says:
Ok, I see! The inconsistency comes from Common Lisp. And I see that Gauche does keep the same behavior as CL...
So - this is a non-issue. Sorry for the noise!
There is no obviously correct value for var to have at the end. If the dolist
list is empty (or the dotimes
number is zero), should it be #f
? In Common Lisp, nil
is the usual "uninteresting value". That's why they use it.
Huh. Common Lisp really is inconsistent as you say. For dotimes
:
At the time result-form is processed, var is bound to the number of times the body was executed.
Thank you for teaching me this :)
I have hesitated for the value that must be returned by dolist
. Gauche returns ()
to be similar to CL (and it is coherent with the cdr
of the last cons
). As @lassik said, probably #f
could be a good value for Scheme.
However, I choose to return a void value to avoid the printing of a final value when used in a REPL as:
stklos> (dolist (x '(1 2 3)) (print x))
1
2
3
stklos>
But, having a result sometimes can be useful:
stklos> (let ((sum 0))
(dolist (x '(1 2 3 4 5) sum)
(inc! sum (square x))))
55
stklos>
So, (dolist (x lst result) body)
returns result
if provided (and if result
is not x
); otherwise, its result is undefined. The special case when the result is explicitly the iteration variable is probably not a good idea (return #f
or '()
in this case?).
Imho, this form is practical to use, but I find it not too "pretty", and I really prefer a good old for-each :smile:
With
dotimes
I can putx
in the binding and use it in the expression result:But for
dolist
it doesn't work: