There is an interesting thread in the Clozure Common Lisp development mailing list about argument evaluation in #'<. Until now, CCL was implementing shortcircuiting when evaluating the arguments of #'<. This essentially means that when calling (< 1 3 2 4 5) it would stop before evaluating all the arguments since it wold know it would be false. Just like and. However, as reported in the initial message by Eric Marsden, it violates the Hyperspec (section 188.8.131.52.2.3 Function Forms) since it does not allow this behaviour for functions. The thread got interesting because a small discussion followed if the correct behaviour should be the one shown by CCL and not the one demanded by the Hyperspec. I must say, while reading, my initial reaction was also to consider shortcircuiting as the desired functionality but soon afterwards, you realize that you really don’t want that. The simplest argument is that you don’t want (< x y z) to have a different semantic from (funcall #'< x y z) as Tim Bradshaw rightly pointed out. Consistency is something very good to have and in the end, if you wish lazy semantics, you can always add them yourself in the true Lisp spirit. However, this shows once more how the writers of the Hyperspec got so many things right even if for a moment you might think otherwise. It was an interesting thread to read.
5 thoughts on “A note on shortcircuiting of argument evaluation in #'<”
I don’t understand your argument about funcall. The semantics wouldn’t be different. You simply CANNOT have a function which doesn’t evaluate all of its arguments. So if < is short-circuiting, it's not an argument and simply cannot be used in funcall. Just like 'and'. You simply can't use #'and with funcall.
I think I was not clear enough on my post. The problem is that CCL had a bug (now corrected) that implemented shortcircuiting in <. So, CCL had a function that didn't evaluated all of its arguments as required. In the thread it was suggested that this was actually desired. However, the hypersec only allows shortcircuting for special forms/macros. That's why "and" can shortcircuit, because it's macro, and thus, it cannot be used with funcall.
Perhaps I am missing something but to the best of my knowledge lisp functions always evaluate all their arguments pretty much by specification. Only with macros and special forms is their a choice as to whether to evaluate all the arguments. That is part of what macros are for as I understand it. If < is implemented as a function but somehow hacked to short-circuit anyway then that would be bad. If it is implement as a macro then no problem except of course you could not do funcall on #'<.
Thanks for you comment Samantha. I was not clear enough in my post I think. CCL had a bug in <, since it's a function and was using shortcircuting on it's arguments (the bug is now corrected). As you well said, only special forms and macros can do that, however, < must be a function.
Glad this was fixed. Could have bitten me!