hi,
At the moment i'm reading the book Successful Lisp and read this:
"When a list form is a function call, its arguments are always evaluated
in order, from left to right. As in other programming languages, it's in
poor taste to rely on this, but if you absolutely have to rely on the
order, it's good to know that Lisp defines it for you."
Ok. It's bad to rely on this. My question is what's better Lisp style:
(do-something (get-user-input-with-prompt "Name: ")
(get-user-input-with-prompt "Age: "))
or this:
(let ((name (get-user-input-with-prompt "Name: "))
(age (get-user-input-with-prompt "Age: ")))
(do-something name age))
What's better lisp style? The first looks better to me but relies on
evaluation order of arguments. If it would be right-to-left (for some
reason, maybe not in Common Lisp where it is defined to be left-to-right
but say in other lisp dialects...) the user is first asked for his age
and then for his name. The second is more secure...
What would you do? Is the first acceptable to rely on evaluation order
or should I avoid it and use the second?
ciao,
chrizel
Christian Zeller wrote:
> What's better lisp style? The first looks better to me but relies on
> evaluation order of arguments. If it would be right-to-left (for some
> reason, maybe not in Common Lisp where it is defined to be left-to-right
> but say in other lisp dialects...) the user is first asked for his age
> and then for his name. The second is more secure...
Neither is more secure, as I doubt there are *any* implementations of common
lisp that get function argument evaluation order, or let form evaluation
order, wrong. If there are, it'd be a simple fix and a big embarrassment.
> What would you do? Is the first acceptable to rely on evaluation order
> or should I avoid it and use the second?
Actually, if you were concerned about clarity, and I were you, I'd go a
third route. Declare this macro:
(defun group (n args)
"(group 2 '(1 2 3 4)) yields ((1 2) (3 4))"
(let ((start (cons nil nil)))
(do ((cur start (cdr cur))
(args args (nthcdr n args)))
((null args) (cdr start))
(setf (cdr cur)
(cons (subseq args 0 n)
nil))))))
(defmacro prompt-for ((args) &body body)
"Binds each even-indexed element of args to the value returned by
prompting the user with the corresponding odd-indexed argument."
(let ((args (group 2 args)))
`(let ,(mapcar (lambda (args)
`(,(first args)
(get-user-input-with-prompt ,(second args))))
args)
,@body)))
and then you can say
(prompt-for (name "Name: " age "Age: ")
(do-something-with name age))
Put it in a utility library on your hard drive and never write it again.
That might make it worth the time it takes to write it. (Well, now that
I've written it, it almost certainly will, if you do much console work.)
Alternatively, you could write a function that takes the same arguments and
returns the user input in a list. Depends on your control flow.
Chris Capel
Christian Zeller wrote:
> hi,
>
> At the moment i'm reading the book Successful Lisp and read this:
> "When a list form is a function call, its arguments are always evaluated
> in order, from left to right. As in other programming languages, it's in
> poor taste to rely on this, but if you absolutely have to rely on the
> order, it's good to know that Lisp defines it for you."
>
> Ok. It's bad to rely on this. My question is what's better Lisp style:
>
> (do-something (get-user-input-with-prompt "Name: ")
> (get-user-input-with-prompt "Age: "))
>
> or this:
>
> (let ((name (get-user-input-with-prompt "Name: "))
> (age (get-user-input-with-prompt "Age: ")))
> (do-something name age))
>
> What's better lisp style? The first looks better to me but relies on
> evaluation order of arguments. If it would be right-to-left (for some
> reason, maybe not in Common Lisp where it is defined to be left-to-right
> but say in other lisp dialects...) the user is first asked for his age
> and then for his name. The second is more secure...
>
> What would you do? Is the first acceptable to rely on evaluation order
> or should I avoid it and use the second?
>
> ciao,
> chrizel
The Common Lisp ANSI Standard specifies that function arguments are
evaluated in order from left to right:
http://www.lispworks.com/reference/HyperSpec/Body/03_ababc.htm
This may be an issue in other languages which lack a language standard
(e.g., Java, Perl), but a compliant implementation of Common Lisp must
behave this way. So relying on this behavior is not necessarily 'poor
taste'.
However, having said that, given your specific example I believe the
second version is preferable. To me it is clearer. But you will find
others here who express the opposite opinion as well.
David Sletten
David Sletten <·····@slytobias.com> wrote:
> The Common Lisp ANSI Standard specifies that function arguments are
> evaluated in order from left to right:
> http://www.lispworks.com/reference/HyperSpec/Body/03_ababc.htm
>
> This may be an issue in other languages which lack a language standard
> (e.g., Java, Perl), but a compliant implementation of Common Lisp must
> behave this way. So relying on this behavior is not necessarily 'poor
> taste'.
FYI: this is not an issue in Java:
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#23789
--
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
Frank Buss wrote:
>
> FYI: this is not an issue in Java:
>
> http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#23789
>
To the extent that Sun's documentation of Java represents a de facto
language standard I agree with you. This Java "standard" is certainly
not as stable (or mature) as Common Lisp's, but the issue of argument
evaluation order doesn't seem likely to change in the future.
David Sletten
David Sletten <·····@slytobias.com> wrote:
> To the extent that Sun's documentation of Java represents a de facto
> language standard I agree with you. This Java "standard" is certainly
> not as stable (or mature) as Common Lisp's, but the issue of argument
> evaluation order doesn't seem likely to change in the future.
it is a standard, the Java Language Standard, but you are right, it is only
a private standard by Sun, not an official standard like ANSI Common
Lisp :-)
--
Frank Bu�, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
David Sletten wrote:
> This may be an issue in other languages which lack a language standard
> (e.g., Java, Perl), but a compliant implementation of Common Lisp must
> behave this way. So relying on this behavior is not necessarily 'poor
> taste'.
It may be slightly risky, if the function being called is built-in
and the lisp implementation is trying to optimize it. There have been
several cases where these optimizations weren't done correctly
and the argument order was changed by an improper source->source
transformation.
But that's why we have test suites. :)
Paul
begin quoting Christian Zeller :
> hi,
>
> At the moment i'm reading the book Successful Lisp and read this:
> "When a list form is a function call, its arguments are always evaluated
> in order, from left to right. As in other programming languages, it's in
> poor taste to rely on this, but if you absolutely have to rely on the
> order, it's good to know that Lisp defines it for you."
>
> Ok. It's bad to rely on this. My question is what's better Lisp style:
>
> (do-something (get-user-input-with-prompt "Name: ")
> (get-user-input-with-prompt "Age: "))
>
> or this:
>
> (let ((name (get-user-input-with-prompt "Name: "))
> (age (get-user-input-with-prompt "Age: ")))
> (do-something name age))
>
> What's better lisp style? The first looks better to me but relies on
> evaluation order of arguments. If it would be right-to-left (for some
> reason, maybe not in Common Lisp where it is defined to be left-to-right
> but say in other lisp dialects...) the user is first asked for his age
> and then for his name. The second is more secure...
>
Don't even bother thinking about other Lisp dialects; your code will not be
portable to those without major porting efforts anyway, and there aren't
that many around these days.
> What would you do? Is the first acceptable to rely on evaluation order
> or should I avoid it and use the second?
>
It's acceptable to rely on evaluation order, but the second might not work
anyway; let is specified to perform its bindings in parallell. Use let*
instead.
Svein Ove Aas wrote:
> It's acceptable to rely on evaluation order, but the second might not work
> anyway; let is specified to perform its bindings in parallell. Use let*
> instead.
Yes, but it's specified to perform the evaluations of the forms in the let
sequentially, so the second *is* secure and portable.
From the LET specification:
"The form
(let ((var1 init-form-1)
(var2 init-form-2)
...
(varm init-form-m))
first evaluates the expressions init-form-1, init-form-2, and so on, in that
order, saving the resulting values."
Chris Capel
Svein Ove Aas <·········@aas.no> writes:
> > What would you do? Is the first acceptable to rely on evaluation order
> > or should I avoid it and use the second?
> >
> It's acceptable to rely on evaluation order, but the second might not work
> anyway; let is specified to perform its bindings in parallell. Use let*
> instead.
Yes it will work. The /bindings/ are performed in parallell, but the
evaluation of the forms to be bound is done in left-to-right order.
Bj�rn
Christian Zeller wrote:
> At the moment i'm reading the book Successful Lisp and read this:
> "When a list form is a function call, its arguments are always evaluated
> in order, from left to right. As in other programming languages, it's in
> poor taste to rely on this, but if you absolutely have to rely on the
> order, it's good to know that Lisp defines it for you."
>
> Ok. It's bad to rely on this. My question is what's better Lisp style:
>
> (do-something (get-user-input-with-prompt "Name: ")
> (get-user-input-with-prompt "Age: "))
>
I puzzled over this myself. After saying it's in poor taste, Seibel goes
ahead and does it himself. Perhaps he meant "although in poor taste in
other languages.. lisp defines it for you" -- of course I'm putting words
in his mouth here. Or maybe that if your code explicitly depends on order
of evaluation you should put it in a sequential form.. but by that he
purposely ignores input side-effects (since that's where he uses the order
implicitly too, as in the above example)
Anyway, it's a great book, and the 3rd (DB) chapter is amazing.
cheers,
Nandan
Nandan wrote:
> Christian Zeller wrote:
>
>
>>At the moment i'm reading the book Successful Lisp and read this:
>
> I puzzled over this myself. After saying it's in poor taste, Seibel goes
> ahead and does it himself. Perhaps he meant "although in poor taste in
> other languages.. lisp defines it for you" -- of course I'm putting words
> in his mouth here. Or maybe that if your code explicitly depends on order
> of evaluation you should put it in a sequential form.. but by that he
> purposely ignores input side-effects (since that's where he uses the order
> implicitly too, as in the above example)
>
> Anyway, it's a great book, and the 3rd (DB) chapter is amazing.
>
> cheers,
> Nandan
>
>
>
Peter has been busy but not busy enough to write _two_ books
simultaneously! _Successful Lisp_ by David Lamkins has just been
published. Peter's book, _Practical Common Lisp_, is nearing completion.
David Sletten
Nandan <············@none.com> writes:
> Christian Zeller wrote:
>
>> At the moment i'm reading the book Successful Lisp and read this:
>> "When a list form is a function call, its arguments are always evaluated
>> in order, from left to right. As in other programming languages, it's in
>> poor taste to rely on this, but if you absolutely have to rely on the
>> order, it's good to know that Lisp defines it for you."
>>
>> Ok. It's bad to rely on this. My question is what's better Lisp style:
>>
>> (do-something (get-user-input-with-prompt "Name: ")
>> (get-user-input-with-prompt "Age: "))
>>
>
> I puzzled over this myself. After saying it's in poor taste, Seibel goes
> ahead and does it himself. Perhaps he meant "although in poor taste in
> other languages.. lisp defines it for you" -- of course I'm putting words
> in his mouth here.
And I think you're putting words in the wrong author's mouth--David
Lamkins wrote _Successful Lisp_ from which the original quotation was
taken. I'm working on _Practical Common Lisp_. FWIW, I don't think
it's poor taste to rely on this documented features of the language.
If I said something to make you think that, I'd be grateful if you
could point it out since that's not what I meant to say. Now if one is
programming in Scheme or C, then it's not only poor taste but broken
to rely on any particular order since they explicitly *don't* specify.
> Anyway, it's a great book, and the 3rd (DB) chapter is amazing.
I'll assume that you are in fact talking about my book (since that is
the topic of my 3rd chapter) and say, thanks!
-Peter
--
Peter Seibel ·····@javamonkey.com
Lisp is the red pill. -- John Fraser, comp.lang.lisp
Peter Seibel wrote:
> And I think you're putting words in the wrong author's mouth--David
> Lamkins wrote _Successful Lisp_ from which the original quotation was
> taken. I'm working on _Practical Common Lisp_. FWIW, I don't think
oops!
> If I said something to make you think that, I'd be grateful if you
> could point it out since that's not what I meant to say. Now if one is
no, no mention of it in PCL
> I'll assume that you are in fact talking about my book (since that is
> the topic of my 3rd chapter) and say, thanks!
yes. great way to get going. that and using lisp-in-a-box, takes a lot of
newbie pain out of the equation.
cheers,
N