The following posts will cover the very basic functions of PicoLisp. By the end of the series, we will have covered more than 60 of the most common PicoLisp functions, which will be a very solid basis for anything to come.
But first, we need to understand how to work with the REPL, in order to follow along with the examples.
The PicoLisp REPL
PicoLisp has a built-in REPL (Read–eval–print loop) that allows to instantly test some functions and syntax.
If you need to install PicoLisp first, read here.
The REPL is started with the command
$ pil +
(Note: the $ stands for the shell and does not need to be typed). After that, you will see the start of the line changing to a colon (:), where the prompt is waiting for further input. It will probably look something like this:
user@my-computer1234$ pil + :
To exit the REPL, write
If you want to type a new command, but the REPL seems still waiting for input (for example, due to wrong syntax or typing errors), you can stop the current input with
If you need to interrupt a program (for example due to a infinite loop), you can end it with
Probably the first thing you notice when you see a LISP/PicoLisp program, is that there are only parentheses. Square brackets and braces are not used. And there seem to be a lot of them - at least one per line, while the code itself is quite concise. Why is that?
When you read about LISP and its dialects, you will often come across the term S-Expression (we will come back to this in later posts when we will talk about the functional programming aspects of PicoLisp). One of the implications is that every function call follows this syntax:
: (myfunction arg1 arg2 arg3 ...)
arg3 can be data or functions, and it needs to be surrounded by parentheses. This enables nested constructions such as:
: (myfunction arg1 (myfunction2 arg2 arg3))
Indentation or new lines are not relevant for the interpreter but help to keep the code readable.
(myfunction arg1 (myfunction2 arg2 arg3) )
By convention, parentheses should always be closed on a line with statements (not on a new line). Nested functions are indented.
The comment is marked with the hash (#) Symbol.
# This is a comment.
We will highlight this now by some simple examples.
Basic arithmetics functions
The most basic functions are probably arithmetical ones: adding, substracting, multiplying, dividing. As you would expect, the symbols for these are
Now we use the REPL and type in what we just learned - operator first, followed by the arguments:
: (+ 3 3) -> 6
We see that
(+ 3 3) evaluates to 6, which is what we probably expected. Now let's try something more complicated like (4*(3+5)).
: (* 4 (+ 3 5)) -> 32
The term is evaluated from right to left starting with the inner brackets. Of course, this one works as well:
: (* (+ 3 5) 4) -> 32
For exponentation, you can use the
: (** 2 4) -> 16
% returns the modulo.
: (% 17 5) -> 2 : (% -17 5) # Sign is that of the first argument -> -2
Incrementing / decrementing
Now let's try incrementing by 1 and decrementing by 1.
: (inc 4) -> 5 : (inc (* (+ 3 5) 4)) -> 33 : (dec( inc (* (+ 3 5) 4))) -> 32
To compare numbers, the "standard" symbols are used:
>= (greater equal),
<= (less equal). The return value is
T if the condition is fulfilled and
NIL if it is not.
: (< 3 4) -> T : (< 4 3) -> NIL
Also you can check if a number is less than zero (
lt0), less or equal zero (
le0), greater than zero (
gt0), greater or equal zero (
ge0), or equal zero (
: (ge0 3) -> T : (le0 3) -> NIL
abs returns the absolute value:
: (abs -3) -> 3
rand returns a pseudo-random number. A range can optionally be defined:
: (rand) -> -1669437588 # Random number between 1 and 10 : (rand 1 10) -> 7
Note: If you play around with the functions you will notice that all values are integers. The reason is that PicoLisp is calculating in Fixed Point Arithmetics. What this implies and how to handle it will be topic in one of the next posts.