Welcome back, let's continue our 60 most common PicoLisp functions series!
Today we will talk about Input and Output functions and how to print the notorious "Hello World" string we have all been waiting for.
To print output in PicoLisp, there are a number of functions depending on the need: With or without spaces between the arguments, with or without new lines...
Let's start with a simple low-level text output:
prin prints all arguments without adding any spaces or new lines.
prinl works the same way, except that a new line is added to the end (the "l" stands for "line").
Let's call each function two times in a row to see the difference:
: (prin "Hello World") (prin ( 1 "abc" (d e (f)) 999 ghi)) Hello World1abcdef999ghi : (prinl "Hello World") (prinl (1 "abc" (d e (f)) 999 ghi)) Hello World 1abcdef999ghi
As you can see, the printout of the list
(1 "abc" (d e (f)) 999 ghi)) is returned without any spaces or parentheses:
1abcdef999ghi. The inner structure of the list is lost. By looking at the output, we have no idea where one list item ends and the next one begins, and if the structure is linear or nested.
If we want to keep this information, i. e. if we need to print complete Lisp expressions that can be passed over to other functions, use
printsp, for new-line use
Notice the differences:
: (print "Hello World") (print (1 "abc" (d e (f)) 999 ghi)) "Hello World"(1 "abc" (d e (f)) 999 ghi) : (printsp "Hello World") (printsp (1 "abc" (d e (f)) 999 ghi)) "Hello World" (1 "abc" (d e (f)) 999 ghi : (println "Hello World") (println (1 "abc" (d e (f)) 999 ghi)) "Hello World" (1 "abc" (d e (f)) 999 ghi)
This time the list structure is maintained during the printing process.
Reading from console and files
The read function is called
read. According to the documentation, it reads from the current input channel. But what is our current input channel?
If we use the REPL, then the current input channel is the console. However, if we call a PicoLisp script, then the current input channel is the script's file. Thus, if we want to write a script that reads from the console, we need to change the current input channel.
We will come back to this point later when we talk about scripts. For now, let's stick with the REPL.
See the following example of the
: (list (read) (read) (read)) 123 abcd hello -> (123 abcd hello) : (list (read) (read) (read)) A B C -> (A B C)
As you can see, we take three parameters from the console and make a list out of them using the
list function. Space and new line both are recognized as delimitors.
To read only a single character, use
: (char) # Read character from console A # (typed 'A' and a space/return) -> "A"
To read in a line, use
line. You can additionally hand over a
T flag. If the flag is
NIL a list of single-character strings is returned, otherwise it is returned as one string.
: (line) # equivalent to (line NIL) abcdefghijkl -> ("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l") : (line T) abcdefghijkl -> "abcdefghijkl"
Additionally, you can add
cnt arguments that specify how the input should be grouped. If the
NIL flag is used, the input is grouped the single-character sublists, while the
T flag groups to substrings:
: (line NIL 1 2 3) abcdefghijkl -> (("a") ("b" "c") ("d" "e" "f") "g" "h" "i" "j" "k" "l") : (line T 1 2 3) abcdefghijkl -> ("a" "bc" "def" "g" "h" "i" "j" "k" "l")
Next let's check how to read from a file in the REPL. Create a file "test.txt" and write some arbitrary content inside, such as:
<test.txt> hello world this is a test 1234567890
Now we change the input channel to the file by
(in <filename>) and repeat the example from above - i.e., read in the first three items and make a list:
: (in "input.txt" (list (read)(read)(read)(read))) -> (hello world this is)
We get the first four words back. Like in the console example above, space, and new-line worked as delimitors.
Writing Output to a File
Similarily, we can write to a file "output.txt" by using
: (out "output.txt" (println 123 '(a b c) 'def)) -> def
Now we will find a file called "output.txt" in our current folder. Let's check its content:
$ cat output.txt 123 (a b c) def
An external library is basically a file with a collection of pre-defined functions bundled together. The
pil21installation comes with some library files which are located in the
lib folder of your
pil21 installation (of course you can also create your own).
To read in external library files, the function
load is used:
(load "@lib/http.l" "@lib/xhtml.l")
@ stands for the relative path to your
As an example, let's take a look into the
We see a
setq for the variables
pi/2. Now let's load
math.l into our REPL and see if we can access these:
: pi # pi is not known -> NIL : (load "@lib/math.l") -> atan2 : pi # pi is known -> 3141593
You probably expected
pi to be 3.141593 instead of 3141593. As briefly mentioned in the Arithmetic Functions post, PicoLisp calculates internally with fixed point integers and a defined scale. We will come back to that point in one of the next posts.
These were the basics of input and output functions in PicoLisp. We will continue with conditionals and loops in the next section.