From: Bruno H. <br...@cl...> - 2012-04-13 00:40:24
|
Hi Sam, Moving the discussion from the bug tracker https://sourceforge.net/tracker/?func=detail&atid=101355&aid=3517196&group_id=1355 to the list. I wrote: > Confirmed: > > > (defun something (a b &rest pieces) (type-of pieces)) > > (apply #'something 5 6 (append NIL "X")) > NULL > > (compile 'something) > SOMETHING ; > 2 ; > NIL > > (apply #'something 5 6 (append NIL "X")) > (SIMPLE-BASE-STRING 1) > > SBCL yields an error in this situation. > > In CLHS > http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/glo_f.html#function > a function is supposed to be "called with zero or more arguments". A dotted > argument list is not foreseen. > > Also, in > http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/fun_apply.html#apply > the arguments list is defined to be a "spreadable argument list > designator", "whose last element is a list L2 of length m". This does not > allow a dotted list. > > See also CLHS > http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/sec_3-4-1-3.html > "The value of a rest parameter is permitted, but not required, to share > structure with the last argument to apply." > > From a user's perspective, I think it would be good if clisp would be > changed to emit an error in this case as well, in interpreted mode only. > In compiled mode, which is not designed to do maximum error checking, I > would not change anything. You replied: > 1. I don't think you can separate compiled from interpreted here: both are > done by apply_closure The compiled closure is handled in the first part of apply_closure, the interpreted one in the last 20 lines of apply_closure. This one-liner should produce an error in the interpreted case: --- eval.d 2011-08-02 00:53:00.000000000 +0200 +++ eval.d.mod 2012-04-13 02:29:07.000000000 +0200 @@ -4827,6 +4827,7 @@ if (((uintL)~(uintL)0 > ca_limit_1) && (args_on_stack > ca_limit_1)) goto error_toomany; } + if (!nullp(args)) goto error_dotted; var gcv_object_t* args_pointer = args_end_pointer STACKop args_on_stack; with_saved_back_trace_iclosure(closure,args_pointer,args_on_stack, funcall_iclosure(closure,args_pointer,args_on_stack); ); > 2. I don't think adding an explicit list check to the evaluator makes much > sense. Why? I think it does: Any useful error message that occurs while a user is testing his program in interpreted mode is useful. > 3. Bruno, why do you have error_apply_dotted signal a program-error and > error_apply_toofew signal an argument-list-dotted error? these look weird: > > > (apply #'cons 1) > *** - APPLY: dotted argument list given to CONS : 1 > > (apply #'read-from-string "a" 2) > *** - APPLY: argument list given to READ-FROM-STRING is dotted (terminated > by 2) > > I think the messages (and errors) should be identical. I agree that the messages are unnecessarily different. About the error types: Since PROGRAM-ERROR is defined as errors relating to "program syntax" <http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/contyp_program-error.html> but here we don't have a wrong program (that could be caught at compile-time), just wrong data (at runtime), I think that PROGRAM-ERROR is wrong here, in both cases. But in the first case, CLHS section 3.5.1.2 <http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/sec_3-5-1-2.html> forces us to signal a PROGRAM-ERROR (or subtype thereof), even though it's nonsense. In the second case, CLHS does not specify which error is signaled (see <http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/fun_apply.html#apply>: "Exceptional Situations: None."). Why should we repeat the same nonsense here? Bruno |