I'm in a grumpy mood today, so I decided to take out my frustrations on the ANS for CL, or implementations thereof. Consider carefully what the following form should return:
(let ((v (make-array 10 :initial-contents '(0 1 2 3 4 5 6 7 8 9) :fill-pointer 5))) (loop for x across v when (eql x 2) do (incf (fill-pointer v)) collect x))
ACL and SBCL both return (0 1 2 3 4). Probably every other implementation does too. I believe the ANS requires the return to be (0 1 2 3 4 5), although the definition in *6.1.2.1.5 The for-as-across subclause* uses various undefined terminology. (We of X3J13 understood that the loop specification was not our best work.)
Steve Haflich shaflich@gmail.com writes:
I'm in a grumpy mood today, so I decided to take out my frustrations on the ANS for CL, or implementations thereof. Consider carefully what the following form should return:
(let ((v (make-array 10 :initial-contents '(0 1 2 3 4 5 6 7 8 9) :fill-pointer 5))) (loop for x across v when (eql x 2) do (incf (fill-pointer v)) collect x))
ACL and SBCL both return (0 1 2 3 4). Probably every other implementation does too. I believe the ANS requires the return to be (0 1 2 3 4 5), although the definition in 6.1.2.1.5 The for-as-across subclause uses various undefined terminology. (We of X3J13 understood that the loop specification was not our best work.)
http://www.lispworks.com/documentation/HyperSpec/Body/03_f.htm
Array traversal
For array traversal operations, the array is not allowed to be adjusted and its fill pointer, if any, is not allowed to be changed.
So ISTM your code is not conforming, and the result (0 1 2 3 4) seems reasonable to me, similarly to:
(loop :with max = 10 :for i :from 0 :below max :do (incf max) :collect i) --> (0 1 2 3 4 5 6 7 8 9)
Now, while we have:
(loop :with l = (list 0 1 2 3 4 5 6 7 8 9) :for x :in l :when (eql x 2) do (setf (cdr (last l)) (list 10)) :collect x) --> (0 1 2 3 4 5 6 7 8 9 10)
this is also clearly in contradiction to 3.6 therefore non-conforming too.
On 29 Jan 2014, at 02:03, Steve Haflich shaflich@gmail.com wrote:
I'm in a grumpy mood today, so I decided to take out my frustrations on the ANS for CL, or implementations thereof. Consider carefully what the following form should return:
(let ((v (make-array 10 :initial-contents '(0 1 2 3 4 5 6 7 8 9) :fill-pointer 5))) (loop for x across v when (eql x 2) do (incf (fill-pointer v)) collect x))
ACL and SBCL both return (0 1 2 3 4). Probably every other implementation does too. I believe the ANS requires the return to be (0 1 2 3 4 5), although the definition in 6.1.2.1.5 The for-as-across subclause uses various undefined terminology. (We of X3J13 understood that the loop specification was not our best work.)
Don’t write such code. ;)
I recall reading Niklaus Wirth’s explanation why he dropped the FOR statement when moving from Modula-2 to Oberon (“FOR i FROM 0 to n DO …”), the reason being that it’s unclear when the boundaries are reached, and also that it’s unclear what happens when the boundaries have already been reached before the first iteration. He kept only WHILE and REPEAT/UNTIL, because with those statements, it is never ambiguous what you mean.
This is also how I try to use LOOP: If it’s unambiguous what a high-level form could mean, I use it, but otherwise, I switch to a lower-level form, even if the high-level form happens to give me the correct result. I prefer my code to be understandable just from reading it. (I don’t always succeed... ;)
Pascal
-- Pascal Costanza The views expressed in this email are my own, and not those of my employer.
There is 6.1.1.8 Restrictions on Side-Effectshttp://www.lispworks.com/documentation/HyperSpec/Body/06_aah.htmthat seems to pretty clearly support the opinion of pjb.
On Jan 29, 2014, at 02:03 , Steve Haflich shaflich@gmail.com wrote:
(We of X3J13 understood that the loop specification was not our best work.)
Shall I utter the P-word? 3:) 3:) 3:) (Or the C-word, and I am sure you agree on this one! :) )
Cheers — MA
On Wed, Jan 29, 2014 at 3:52 AM, Antoniotti Marco antoniotti.marco@disco.unimib.it wrote:
On Jan 29, 2014, at 02:03 , Steve Haflich shaflich@gmail.com wrote:
(We of X3J13 understood that the loop specification was not our best work.)
Shall I utter the P-word? 3:) 3:) 3:) (Or the C-word, and I am sure you agree on this one! :) )
I'll take the bait. PATHNAME sounds to me like the obvious horror starting with P — and I recommend Lispers to give a look at UIOP/PATHNAME to see why.
C, I'm not sure. Looking at the symbol index and glossary, I'll venture a guess: COMPILER-MACRO?
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org For every complex problem, there is a solution that is simple, neat, and wrong. — H. L. Mencken
On Jan 29, 2014, at 21:32 , Faré fahree@gmail.com wrote:
On Wed, Jan 29, 2014 at 3:52 AM, Antoniotti Marco antoniotti.marco@disco.unimib.it wrote:
On Jan 29, 2014, at 02:03 , Steve Haflich shaflich@gmail.com wrote:
(We of X3J13 understood that the loop specification was not our best work.)
Shall I utter the P-word? 3:) 3:) 3:) (Or the C-word, and I am sure you agree on this one! :) )
I'll take the bait. PATHNAME sounds to me like the obvious horror starting with P — and I recommend Lispers to give a look at UIOP/PATHNAME to see why.
+1 :-)
C, I'm not sure. Looking at the symbol index and glossary, I'll venture a guess: COMPILER-MACRO?
Nope. You missed this one!
Does “modern mode" ring a bell? :)
Cheers — MA
C, I'm not sure. Looking at the symbol index and glossary, I'll venture a guess: COMPILER-MACRO?
Nope. You missed this one!
Does “modern mode" ring a bell? :)
case sensitive case conversion? Yeah, it's mighty quirky, but it's a finite amount of brokenness that can be patched over easily and relatively portably, quite unlike the pathname horror, that reminds me at a much smaller scale of that description of PHP: "A fractal of bad design".
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Schemer: "Buddha is small, clean, and serious." Lispnik: "Buddha is big, has hairy armpits, and laughs." — Nikodemus Siivola
On Jan 29, 2014, at 21:51 , Faré fahree@gmail.com wrote:
C, I'm not sure. Looking at the symbol index and glossary, I'll venture a guess: COMPILER-MACRO?
Nope. You missed this one!
Does “modern mode" ring a bell? :)
case sensitive case conversion? Yeah, it's mighty quirky, but it's a finite amount of brokenness that can be patched over easily and relatively portably,
Yeah. But go back and check the CLL thread on the introduction of “modern mode” by Franz :)
quite unlike the pathname horror, that reminds me at a much smaller scale of that description of PHP: "A fractal of bad design”.
This I hadn’t heard :) Very nice.
Cheers -- MA
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org Schemer: "Buddha is small, clean, and serious." Lispnik: "Buddha is big, has hairy armpits, and laughs." — Nikodemus Siivola
-- Marco Antoniotti, Associate Professor tel. +39 - 02 64 48 79 01 DISCo, Università Milano Bicocca U14 2043 http://bimib.disco.unimib.it Viale Sarca 336 I-20126 Milan (MI) ITALY
Please note that I am not checking my Spam-box anymore. Please do not forward this email without asking me first.
Ya gotta love a language and its denizens where the spec is so complete it either covers feature abuse (see "moving fill pointer during loop-across") or documents that such abuse is undefined and then said denizens sit around in pubs ignoring the redhead sitting under the moosehead bemoaning its inadequacy (the spec, not the moosehead) when it is hard to find a langue du jour that even has a spec.
If they had not screwed up and called prog0 prog1 I would consider using the damn thing.
-hp
ps. Are we going to leave Steve off the hook for misreading the spec he wrote?
On Wed, Jan 29, 2014 at 3:32 PM, Faré fahree@gmail.com wrote:
On Wed, Jan 29, 2014 at 3:52 AM, Antoniotti Marco antoniotti.marco@disco.unimib.it wrote:
On Jan 29, 2014, at 02:03 , Steve Haflich shaflich@gmail.com wrote:
(We of X3J13 understood that the loop specification was not our best
work.)
Shall I utter the P-word? 3:) 3:) 3:) (Or the C-word, and I am sure you
agree on this one! :) )
I'll take the bait. PATHNAME sounds to me like the obvious horror starting with P — and I recommend Lispers to give a look at UIOP/PATHNAME to see why.
C, I'm not sure. Looking at the symbol index and glossary, I'll venture a guess: COMPILER-MACRO?
—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org For every complex problem, there is a solution that is simple, neat, and wrong. — H. L. Mencken
Kenneth Tilton ken@tiltontec.com writes:
If they had not screwed up and called prog0 prog1 I would consider using the damn thing.
They didn't screw up:
(defpackage "KTLISP" (:use "CL") (:shadow "PROG1" "PROG2" "PROGN") (:export "PROG0" "PROGN-1") (:export . #.(let ((l '())) (do-external-symbols (s "CL") (push (symbol-name s) l)) l))) (in-package "KTLISP") (defmacro prog0 (&rest body) `(cl:prog1 ,@body)) (defmacro prog1 (&rest body) `(cl:prog2 ,@body)) (defmacro progn-1 (&rest body) `(cl:progn ,@body)) (defmacro progn (&rest body) `(cl:progn ,@body (values)))
(defpackage "KTLISP-USER" (:use "KTLISP"))
(in-package "KTLISP-USER")
(prog1 'hi '(hello world)) --> (HELLO WORLD)