If you're on Arch Linux, you can install the `lisp` package from AUR, then type `lispi` and then `(+ 1 2)` for adding 1 and 2. Don't type in the backtick quotes. Press `ctrl-c` to quit.
If you install `clojure` you can start the interpreter with `clj` and also type in similar expressions, like:
(* 3 7)
There are a couple of differences to Common Lisp, though.
The fun thing about Lisp is that you can pass any number of parameters to functions, like "+", so that expressions like this also works fine:
(* 1 2 3 4 5 6 7)
The next thing to know is that the first element within () is interpreted as the function, while the rest are interpreted as parameters. Then how do you represent a list like (1 2 3) without Lisp thinking that "1" is the function, you surely ask? You prefix it with ', like this: '(1 2 3). If you type '(1 2 3) into the `lispi` or `clj` prompt, they will print (1 2 3) right back at you.
A fundamental concept in Lisp is to get the first element of a list (the head) or the rest of the elements (the tail). For historical reasons the head is called CAR and the tail is called CDR in lisp. Everyone has just accepted that this is the way of Common Lisp by now. In Clojure, "first" and "rest" are used instead of CAR and CDR, as the heathens they are.
Since regular for loops are for wimps and snowflakes, iterating in traditional Lisp mainly centers around how to do the same thing using CAR, CDR and recursion.
Before we can do that, let's define a function that adds 2 to the given number:
(defun addtwo (x) (+ x 2))
Note that "defun" is the function for creating functions that takes, roughly speaking, three parameters: the function name, the function parameters and the function expression.
If you type it into "lispi" you can use the function afterwards, and get the result 42:
(addtwo 40)
Also, all lists in lisp are really just the head and the rest, so creating lists can be done by combining a head with the rest of a list, using cons, like this:
(cons 1 ())
Which is equivalent to this (but signifies that quoting was intended):
(cons 1 '())
And this:
(cons 1 nil)
All three of the above expressions returns a list with one element (1), which means a head of 1 combined with an empty tail. Lists are constructed by appending heads to existing (or empty) tails.
Creating a function that takes apart a list into a head and a tail and then combines them again can be done like this:
(defun combine (xs) (cons (car xs) (cdr xs)))
"xs" is the name of the function parameter, which is a list.
The combine function can be called like this:
(combine '(1 2 3))
And will return:
(1 2 3)
If you wish to edit code in a file instead of interactively, where the arrow keys may not always work, try putting this in a file named "main.lsp":
(defun hello ()
(write-line "Hello, World!"))
Then run the desired function with:
lisp main.lsp hello
Now to create a for-loop replacement in Common Lisp, for people with hair under their arms, using CAR and CDR and recursion. This program will print each number in the given list, with an axe emoji after each number (HN removed it, please insert an appropriate unicode emoji instead of the x):
"unless" takes a condition and a list of statements. "null" checks if a list is empty. "write" outputs the given argument, but not a newline. "write-line" outputs the given argument and also a newline.
This should be enough to get you started. Then read SICP and draw the rest of the owl.
For systems other than Arch, here are the wrapper scripts for SBCL that provides the `lisp` and `lispi` commands mentioned above.
lisp:
#!/bin/sh
#
# SBCL wrapper script
#
filename="$1"
mainfunction="${2:-main}"
if [ -z $filename ]; then
echo 'Please provide a filename as the first argument'
exit 1
fi
if [ ! -f $filename ]; then
echo "Could not find the file named \"$filename\""
exit 1
fi
sbcl_path=$(which sbcl)
if [ -z $sbcl_path ]; then
echo 'sbcl is not in the PATH environment variable'
exit 1
fi
if [ ! -x $sbcl_path ]; then
echo "$sbcl_path is not executable"
exit 1
fi
"$sbcl_path" \
--noinform \
--noprint \
--no-userinit \
--no-sysinit \
--disable-debugger \
--quit \
--load "$filename" \
--eval "($mainfunction)" \
--end-toplevel-options
lispi:
#!/bin/sh
#
# SBCL wrapper script
#
filename="$1"
flag=""
if [ ! -z $filename ]; then
if [ ! -f $filename ]; then
echo "Could not find $filename"
exit 1
fi
flag="--load $filename"
fi
sbcl_path=$(which sbcl)
if [ -z $sbcl_path ]; then
echo 'sbcl is not in the PATH environment variable'
exit 1
fi
if [ ! -x $sbcl_path ]; then
echo "$sbcl_path is not executable"
exit 1
fi
"$sbcl_path" --noinform $flag
If you install `clojure` you can start the interpreter with `clj` and also type in similar expressions, like:
There are a couple of differences to Common Lisp, though.The fun thing about Lisp is that you can pass any number of parameters to functions, like "+", so that expressions like this also works fine:
The next thing to know is that the first element within () is interpreted as the function, while the rest are interpreted as parameters. Then how do you represent a list like (1 2 3) without Lisp thinking that "1" is the function, you surely ask? You prefix it with ', like this: '(1 2 3). If you type '(1 2 3) into the `lispi` or `clj` prompt, they will print (1 2 3) right back at you.A fundamental concept in Lisp is to get the first element of a list (the head) or the rest of the elements (the tail). For historical reasons the head is called CAR and the tail is called CDR in lisp. Everyone has just accepted that this is the way of Common Lisp by now. In Clojure, "first" and "rest" are used instead of CAR and CDR, as the heathens they are.
Since regular for loops are for wimps and snowflakes, iterating in traditional Lisp mainly centers around how to do the same thing using CAR, CDR and recursion.
Before we can do that, let's define a function that adds 2 to the given number:
Note that "defun" is the function for creating functions that takes, roughly speaking, three parameters: the function name, the function parameters and the function expression.If you type it into "lispi" you can use the function afterwards, and get the result 42:
Also, all lists in lisp are really just the head and the rest, so creating lists can be done by combining a head with the rest of a list, using cons, like this: Which is equivalent to this (but signifies that quoting was intended): And this: All three of the above expressions returns a list with one element (1), which means a head of 1 combined with an empty tail. Lists are constructed by appending heads to existing (or empty) tails.Creating a function that takes apart a list into a head and a tail and then combines them again can be done like this:
"xs" is the name of the function parameter, which is a list.The combine function can be called like this:
And will return: If you wish to edit code in a file instead of interactively, where the arrow keys may not always work, try putting this in a file named "main.lsp": Then run the desired function with:lisp main.lsp hello
Now to create a for-loop replacement in Common Lisp, for people with hair under their arms, using CAR and CDR and recursion. This program will print each number in the given list, with an axe emoji after each number (HN removed it, please insert an appropriate unicode emoji instead of the x):
Save as "main.lsp" and run with "lisp main.lsp"."unless" takes a condition and a list of statements. "null" checks if a list is empty. "write" outputs the given argument, but not a newline. "write-line" outputs the given argument and also a newline.
This should be enough to get you started. Then read SICP and draw the rest of the owl.
Best of luck!