One would expect prog2
to differ from prog1
and progn
in returning the result of evaluating the second expression instead of the first and last, respectively.
However, the HyperSpec says something different (emphasis mine):
prog2 evaluates first-form, then second-form, and then forms, yielding as its only value the primary value yielded by first-form.
That would mean that prog2
would return the same (and, in fact, behave much) like prog1
!
Interestingly, the examples in the HyperSpec confirm the expected rather than the specified behaviour:
(setq temp 1) => 1 (prog2 (incf temp) (incf temp) (incf temp)) => 3 temp => 4 (prog2 1 (values 2 3 4) 5) => 2
Is this a typo in the standard or am I missing something deeper?
This seems to be a known issue with the ANSI standard (the full list can be found on CLiki).
I have tested it with SBCL 2.0.1 as well as with a recent version of Allegro and in both cases it behaves as expected (rather than as specified):
CL-USER> (prog2
(print "1st")
(print "2nd")
(print "3rd"))
"1st"
"2nd"
"3rd"
"2nd"
Come to think of it, even the indentation seems to suggest so.