I'm new to Picolisp.
I tried this, and obtained a segfault:
: ('(1 2) 6)
Segmentation fault
But, if i try:
: ('(a b c) 6)
-> NIL
I mostly understand why, but it was a surprise that PicoLisp responded with a segfault instead of an error. Does this means that Picolisp doesn't check if a number is a function but it does when it is a symbol?
(Lifted from picolisp mailing list.)
Yes, this is the expected behavior.
PicoLisp evaluates the CAR of a list, perhaps repeatedly, until it hits upon a function. A function is either a list (then it is a Lisp-level function) or a short number (then it is a built-in function, written in either asm or C). If that number does not point to executable code (which is difficult to check at runtime), a crash happens.
I would consider such a crash an "extended error message": Why not let the hardware (MMU) do the runtime check?
In general, it is not possible to have the interpreter catch any possible error (think of infinite loops, for example), so PicoLisp takes the stand of giving some responsibility to the programmer.
In practice, an error like the above one will be detected at the first test run of your program.
BTW, an exception to the above rule is only a list that directly has a number in its CAR. Such a list auto-evaluates:
: (1 2 3)
-> (1 2 3)
Is just a convenient feature, not having to quote such constant lists.
: ('(a b c) 6)
-> NIL
I mostly understand why, but it was a surprise that Picolisp responded with a segfault instead of an error. Does this means that Picolisp doesn't check if a number is a function but it does when it is a symbol?
In that case, (a b c) is in fact a legal function definition: It is a function with a single symbolic parameter 'a' (so that function does not evaluate its arguments), and a body of two symbols. This is equivalent to
: (de foo a
b
c )
-> foo
When this function is executed, it binds the argument list (3) to that symbol 'a', then executes 'b' and 'c'. This function returns the value of 'c', which was NIL in your example.
When you do:
: (de foo H H) : (foo 1 2 3) -> (1 2 3) : foo -> (H H)
so you can also do:
: ('(H H) 1 2 3) -> (1 2 3)
Correct.
I bet you know what happens here; you are trying to use a number as a variable, which is illegal -> crash (besides it does not make sense anyway)
It is correct what you said. The interpreter hits upon '1' in the place of an expected function parameter.
: (setq 7 5)
!? (setq 7 5)
7 -- Variable expected
?