> > Only functions which evaluate all of their arguments should be passed
> > to 'apply'. For other functions the result is undefined.
> I still wonder whether this restriction is necessary?
I think it is. This is a consequence of how 'apply' behaves (not only in
picoLisp): It takes a list, and passes it to another function. This list
contains the final arguments, suitable for that function. That is, all
items in the list are already "evaluated". If a function wants to
evaluate its arguments individually by itself, or perhaps some of them
not at all, it cannot control this because 'apply' already did the whole
> > - If it is a Lisp function with a single symbolic parameter
> > (non-evaluating), that parameter is simply bound to NIL (as you
> > observed).
> Why cannot it be bound to the argument list being applied similar to the
> evaluating case but without evaluation?
It would be possible, but rather inefficient. For technical reasons,
'apply' would have to built a new list in the heap for that. This would
create lots of overhead just for this case where the behavior is
"undefined" anyway (see above).
For built-in functions, 'apply' creates such a list, too, but in a more
efficient way without additional garbage. This should not be done for
Lisp level functions, as the access to these internal structures cannot
be controlled for Lisp functions.
> >> : (and 1 2 3)
> >> -> 3
> >> : (apply and (1 2) 3)
> >> -> 2
> > Note, here too, that 'and' is not really suited for 'apply', as it does
> > not always evaluate all of its arguments. But, ok for now ...
> Well, I don't see anything suspicious here, it behaves as I expect.
Yes, in this simple case. But what if one of the args to 'and' has
: (and (foo) (bye))
This will exit the interpreter when 'foo' returns Non-NIL. If you want
to handle this case with 'apply', it will always exit because all
arguments are evaluated.
> 13-> NIL
> : (apply and (list a (print 1)) (print 3))
> 13-> NIL
> I see here that 'apply' evaluates the arguments before 'and'. So maybe
> here is where it gets evaluated twice as you mentioned it in other
> What if 'apply' did not evaluate the arguments and just passed the
> argument list to the function being applied? The native functions would
Then 'apply' would be rather useless. Without evaluation, 'apply' can
only pass constant values to other functions, so there is no point in
using 'apply', and the functions can be called directly with these
> As applying native and lisp 'and' behaves differently so there seems to
> be limit in what can be implemented in picolisp.
True. So this is different from what I told you at our meeting in
Berlin. Didn't think about that. It would be possible, however, to
implement 'apply' in a way that behaves identical, but with the above
> > Probably the fact that Lisp functions do not receive the full runtime
> > expression, but only the arguments.
> Yes. But the full runtime expression is just convenience for error
Not only that. It is needed for example for method invocations, to know
the message symbol (in the CAR), to be able to search for it in the
object and classes hierarchy.
There may be other reasons that I don't remember now.