Hi Jon,

> : (car ((list 1 2 3) 4))
> !? (car ((list 1 2 3) 4))
> 3 -- Variable expected
> Why is a variable expected in this position?

((list 1 2 3) 4) is a highly illegal expression :-/

When PicoLisp tries to evaluate it, it finds that the CAR is a list

   (list 1 2 3)

This CAR is evaluated, to obtain a function to be applied to '4'. This
evaluation gives (1 2 3) which is _not_ a legal function, but the
interpreter does not check it that far.

BTW, (list 'A 2 3) _would_ be a legal function.

So (1 2 3) is executed as a function, "binding" the argument '4' to the
"formal parameter" '1' (this is the illegal part). For some lucky
reason, it did not crash, so that "function" returns '3' (the last
expression in the "body" (2 3) of that function).

Now 'car' in the original expression gets '3', which is rejected because
'car' can only be applied to a variable (i.e. a symbol or a cell).

   : (car 3)
   !? (car 3)
   3 -- Variable expected

Calling ((list 1 2 3) 4) does not crash immediately, but will surely
crash later if used in a real program, because "binding" '4' to the
"parameter" 1 destroys the bignum structure of '1'. In the 64-bit
version, it crashes immediately because '1' is a short number which is
then used as a pointer.

The actual fault of PicoLisp is that it doesn't fully investigate
whether what it tries to apply to '4' is really a function or not. It
doesn't do so for performance reasons, because a complete detection
whether a given data structure might be a function or not can be
arbitrarily complex.

The built-in function 'fun?' does this to a certain level. It says
whether a given item "looks" like a function:

   : (fun? '(1 2 3))
   -> NIL

   : (fun? '(A B))            
   -> A

But it would be too expensive to use it in every possible situation.

- Alex
UNSUBSCRIBE: mailto:picol...@software-lab.de?subject=unsubscribe

Reply via email to