Hi Tomas, > > 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 job. > > - 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 side-effects? : (and (foo) (bye)) -> NIL 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 > discussion? Yes. > 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 arguments. > 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 overhead. > > 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 > handling/messages? 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. Cheers, - Alex -- UNSUBSCRIBE: mailto:[email protected]?subject=unsubscribe
