Language reference

Summary

Symbols

nil, t, nothing

List functions

cons, car, first, cdr, rest, caar, cadr, second, cdar, cddr, caaar, caadr, cadar, caddr, third, cdaar, cdadr, cddar, cdddr, length, reverse, nth, sort

Defining variables and functions

lambda, defun, defvar, setq, let, let*

Arithmetic functions

+, -, *, /, mod, 1+, 1-, abs, random, max, min

Arithmetic comparisons

=, <, <=, >, >=, /=, plusp, minusp, zerop, oddp, evenp

Bitwise operations

logand, logior, logxor, lognot, ash, logbitp

Conditionals

if, cond, when, unless, and, or, not

Tests

null, atom, listp, consp, numberp, streamp, eq

Characters

charchar-codecode-charcharacterp

Strings

subseqstring<string=string>, stringp, stringconcatenate, read-from-string, prin1-to-string, princ-to-string,

Iteration and mapping

loop, return, dolist, dotimes, mapc, mapcar, progn, assoc, member, funcall, apply, eval

In-place operations

setfpush, pop, incf, decf

System functions

globals, makunbound, break, gc, save-image, load-image, editroom, trace, untrace

Input/output

readprintprincprin1pprintterpriread-bytewrite-byteread-line, write-line, write-string

Arduino interface

millisfor-millis, with-i2c, with-serialwith-spirestart-i2c, pinmode, digitalread, digitalwrite, analogread, analogwrite, delay, note


#b, #o, #x

Allow you to enter numbers in binary, octal, or hexadecimal notation.

For example:

> #xFFFF
-1

> #b0101010101010101
21845

> #o777
511

#\

Allows you to enter a character.

The sequence #\ can be followed by a single character, or one of the following control codes:

Null, SOH, STX, ETX, EOT, ENQ, ACK, Bell, Backspace, Tab, Newline, VT, Page, Return, SO, SI,
DLE, DC1, DC2, DC3, DC4, NAK, SYN, ETB, CAN, EM, SUB, Escape, FS, GS, RS, US, Space

special form

Syntax: 'item

Quotes the argument.

'(+ 1 2)

is a shorthand for:

(quote (+ 1 2))

function

Syntax: (* number*)

Multiplies its arguments together.

function

Syntax: (+ number*)

Adds its arguments together.

function

Syntax: (- number*)

If there is one argument, negates the argument.

If there are two or more arguments, subtracts the second and subsequent arguments from the first argument.

function

Syntax: (/ number*)

Divides the first argument by the second and subsequent arguments.

For example:

> (/ 60 2 3)
10 

/= function

Syntax: (/= number*)

Not equal. Returns t if none of the arguments are equal, and nil if two or more arguments are equal.

A potential source of confusion is that this function is called "!=" in C.

1+ function

Syntax: (1+ number)

Adds one to its argument and returns it.

> (1+ (* 3 3))
10 

(1+ x) is a shorter way of writing (+ x 1).

1- function

Syntax: (1- number)

Subtracts one from its argument and returns it.

> (11 (* 3 3))

(1- x) is a shorter way of writing (- x 1).

; (semicolon)

Introduces a comment line, which will be ignored.

Because the Arduino Serial Monitor removes line terminators, uLisp ignores all characters after a semicolon up to the next opening bracket. This will have an equivalent effect; however, note that comments should therefore not include brackets.

For example:

; Factorial function
(defun f (n) (if (= n 0) 1 (* n (f (- n 1)))))

function

Syntax: (< number*)

Returns t if each argument is less than the next argument, and nil otherwise.

<= function

Syntax: (<= number*)

Returns t if each argument is less than or equal to the next argument, and nil otherwise.

function

Syntax: (= number*)

Returns t if the arguments are numerically equal, and nil otherwise.

For example:

> (= (* 4 3) (* 2 6) (* 1 12))

function

Syntax: (> number*)

Returns t if each argument is greater than the next argument, and nil otherwise.

>= function

Syntax: (>= number*)

Returns t if each argument is greater than or equal to the next argument, and nil otherwise.

abs function

Syntax: (abs number)

Returns the absolute, positive value of its argument.

analogread Arduino function

Syntax: (analogread pin)

Reads the specified Arduino analogue pin number and returns the value. The following pins can be used:

Platform Arduino pin Processor
Arduino Uno, Arduino Nano 0 (A0) to 5 (A5) ATmega328
Arduino Mega 2560 0 (A0) to 15 (A15) ATmega2560
Tiny Lisp Computer 0 (A0) to 7 (A7) ATmega1284
Arduino Due 54 (A0) to 65 (A11) SAM3X8E
Arduino Zero 15 (A0) to 19 (A5) SAMD21
Arduino MKZero 15 (A0) to 21 (A6) SAMD21
MSP430 F5529 LaunchPad 2, 6, 23 to 28 MSP430F5529
MSP430 FR5969 LaunchPad 5, 11 to 13, 18, 19, 23, 24 MSP430FR5969

On the ATmega processors the analogue inputs are 10 bits, so the value is a number between 0 and 1023.

On the MSP430 processors the analogue inputs are 12 bits, so the value is a number between 0 and 4095.

If you prefer to use the pin labels A0, A1, etc you can define appropriate variables; for example, for the Arduino Zero:

(defvar A0 15)

analogwrite Arduino function

Syntax: (analogwrite pin value)

Writes the value to the specified Arduino pin number:

Platform Arduino pin Processor
Arduino Uno, Arduino Nano 3, 5, 6, 9, 10, 11 ATmega328
Arduino Mega 2560 2 to 13, 44 to 46 ATmega2560
Tiny Lisp Computer 3, 4, 6, 7, 12 to 15 ATmega1284
Arduino Due 2 to 13, 66 (DAC0), 67 (DAC1) SAM3X8E
Arduino Zero 3 to 6, 8 to 13, 14 (DAC0) SAMD21
Arduino MKZero 0 to 8, 10, 18, 19 SAMD21
MSP430 F5529 LaunchPad 12, 19, 35 to 40 MSP430F5529
MSP430 FR5969 LaunchPad 3, 4, 6 to 15, 18, 19, 21, 22, 26 MSP430FR596

On most processors the analogue outputs are 8 bits, so the value is a number between 0 and 255.

On the Arduino Due the DAC outputs are 12 bits.

On the Arduino Zero the DAC output is 10 bits.

and special form

Syntax: (and item*)

Evaluates its arguments until one returns nil, and returns the last value. It's usually used to combine conditions. For example, pos tests whether something is a positive number:

(defun pos (a) (and (numberp a) (> a 0)))

append function

Syntax: (append list*)

Joins its arguments, which should be lists, into a single list.

For example:

> (append '(1 2 3) '(4 5 6) '(7 8 9))
(1 2 3 4 5 6 7 8 9) 

apply function

Syntax: (apply function list)

Returns the result of evaluating the function specified by the first argument with the list of arguments specified by the second parameter. So, for example:

> (apply cons '(a b))
(a . b)

This is equivalent to (cons 'a 'b). 

ash function

Syntax: (ash value shift)

Returns the result of bitwise shifting value by shift bits. If shift is positive, value is shifted to the left. For example:

> (ash 7 3)
56

If shift is negative, value is shifted to the right. For example:

> (ash 15 -2)
3

assoc function

Syntax: (assoc key list)

Looks up a key in an association list of (key . value) pairs, and returns the matching pair, or nil if no pair is found.

Example:

> (assoc 'c '((a . 1) (b . 2) (c . 3) (d . 4)))
(c . 3)

Association lists are useful for storing complex data; for example you could use an association list to specify the colour of an RGB LED:

(setq col '((r . 127) (g . 63) (b . 255)))

You could then get one colour component using assoc:

> (cdr (assoc 'g col))
63 

atom function

Syntax: (atom item)

Returns t if its argument is a single number, symbol, or nil.

Example:

> (atom 'b)
t

> (atom '(a b))
nil 

The function atom is the inverse of consp.

break function

Syntax: (break)

Inserts a breakpoint in your uLisp program.

When the (break) function is evaluated you will be returned to the uLisp prompt, and you can then examine the values of parameters and local variables.

The uLisp prompt is preceded by a number giving the break level. Type nil to exit from break and continue execution.

For example:

> (let* (lis) (dolist (x '(a b c)) (setq lis (cons x lis)) (break)))

Break!
: 1> lis

(a)

: 1> nil

Break!
: 1> lis

(b a)

caaar, caadr, caar, cadar, caddr, cadr, cdaar, cdadr, cdar, cddar, cdddr, cddr

Syntax: (caaar list)

These are all equivalent to the corresponding sequence of car and cdr functions. For example,

(cdaar list)

is equivalent to:

(cdr (car (car list)))

car function

Syntax: (car list)

Returns the first item in a list. 

> (car '(a b c d e f))
a

Equivalent to first.

char function

Syntax: (char string n)

Returns the nth character in a string, counting from zero.

Example:

> (char "uLisp" 1)
#\L

char-code function

Syntax: (char-code character)

Returns the ASCII code for a character, as an integer.

For example:

> (char-code #\return)
13

characterp function

Syntax: (characterp item)

Returns t if the argument is a character and nil otherwise.

cdr function

Syntax: (cdr list)

Returns a list with the first item removed. 

> (cdr '(a b c d e f))
(b c d e f)

Equivalent to rest.

code-char function

Syntax: (code-char integer)

Returns the character for the specified ASCII code.

For example:

> (code-char 126)
#\~

concatenate function

Syntax: (concatenate 'string string*)

Joins together the strings given in the second and subsequent arguments, and returns a single string. The second argument specifies the type of the result; uLisp only supports string.

Example:

> (concatenate 'string "One" "Two" "Three")
"OneTwoThree"

cond special form

Syntax: (cond ((test form*) (test form*) … ))

The cond special form provides a more flexible conditional structure than the simpler functions if, while, and unless.

Each argument is a list consisting of a test optionally followed by one or more forms.

If the test evaluates to non-nil the forms are evaluated, and the last value is returned as the result of the cond.

If the test evaluates to nil, none of the forms are evaluated, and the next argument is processed in the same way.

The following example reads an analogue input and sets one of four outputs high depending on the value of the input:

(let* ((a (analogread 0)))
  (cond
   ((< a 64) (digitalwrite 2 t))
   ((< a 128) (digitalwrite 3 t))
   ((< a 192) (digitalwrite 4 t))
   (t (digitalwrite 5 t))))

As in this example, the last test in a cond is usually t to provide the action to be performed when all the previous tests fail.

cons function

Syntax: (cons item item)

If the second argument is a list, cons returns a new list with item added to the front of the list. For example:

> (cons 'a '(b c d e))
(a b c d e)

If the second argument isn't a list cons returns a dotted pair:

> (cons 'a 'b)
(a . b) 

consp function

Syntax: (consp item)

Returns t if its argument is a non-null list.

Example:

> (consp 'b)
nil

> (consp '(a b))

The function consp is the inverse of atom.

decf special form

Syntax(decf place [number])

Subtracts one from the value of place, and returns the new value. The second argument place can be one of the forms:

symbol
(car form)
(cdr form)
(nth n form

For more information see setf.

For example:

> (defvar a 123)
a

> (decf a)
122

> a
122 

You can include an optional second argument to specify the decrement.

defun special form

Syntax: (defun name (parameters) form*)

Allows you to define a function. For example:

(defun sq (x) (* x x))

This creates a function called sq with one parameter, x. When the function is called, the body is evaluated with x bound to the argument. For example:

> (sq 7)
49

This is equivalent to:

(defvar sq '(lambda (x) (* x x))

Variable number of arguments

You can define a function that takes a variable number of arguments by giving the &rest keyword in the list of parameters, followed by a single parameter; this parameter is bound to a list of the remaining arguments.

For example, this defines a function out that defines any number of Arduino pins as outputs:

(defun out (&rest x) (mapc (lambda (p) (pinmode p t)) x))

You could call it with:

(out 4 5 6 7)

defvar special form

Syntax: (defvar variable form)

Defines a global variable. For example:

(defvar x 1000)

delay function

Syntax: (delay number)

Delays for a specified number of milliseconds. For example:

(delay 1000)

gives a one-second delay.

On the 16-bit platforms the maximum delay is 32767, or approximately 32 seconds. On the 32-bit platforms the maximum delay is 2147483647, or approximately 24 days.

See also for-millis.

digitalread Arduino function

Syntax: (digitalread pin)

Reads the state of the specified Arduino pin number and returns t (high) or nil (low). The following digital pins can be used:

Platform Digital pins Processor
Arduino Uno, Arduino Nano 0 to 21 ATmega328
Arduino Mega 2560 0 to 69 ATmega2560
Tiny Lisp Computer 0 to 31 ATmega1284
Arduino Due 0 to 53 SAM3X8E
Arduino Zero 0 to 19 SAMD21
Arduino MKZero 0 to 21 SAMD21
MSP430 F5529 LaunchPad 2 to 15, 17 to 19, 23 to 40 MSP430F5529
MSP430 FR5969 LaunchPad 2 to 15, 18 to 19, 21 to 32 MSP430FR5969

digitalwrite Arduino function

Syntax: (digitalwrite pin state)

Sets the state of the specified Arduino pin number. The pins are the same as for digitalread above.

The state can be one of the following:

State Effect
nil LOW
t HIGH

dolist special form

Syntax: (dolist (var list [result]) form*)

Sets the local variable var to each element of list in turn, and executes the forms. It then returns result, or nil if result is omitted.

dotimes special form

Syntax: (dotimes (var number [result]) form*)

Executes the forms number times, with the local variable var set to each integer from 0 to number-1 in turn. It then returns result, or nil if result is omitted.

For example, to flash an LED ten times:

(defun ten ()
  (pinmode 13 t)
  (dotimes (x 10)
    (digitalwrite 13 t)
    (delay 500)
    (digitalwrite 13 nil)
    (delay 500)))

edit function

Syntax: (edit 'function)

Lets you step through a function definition, editing it a bit at a time, using the following single-key editing commands:

Command Name Description
Enter enter Prettyprints the current form.
a car Takes the car of the current form.
d cdr Takes the cdr of the current form.
r replace Replaces the current form with what you type in.
c cons Conses what you type in onto the front of the current form.
x delete Deletes the car of the current form.
b back Backs up the tree.
q quit Quits from the editor.

To edit the function you type a series of a or d commands to step through the function to the part you want to edit, use r, c, or x to make changes, type b to go back, or type q to exit from the editor.

At any stage you can press Enter to print the current part of the function you've reached.

If you type an invalid key the editor prints ?, and if you reach the end of the tree with a or d the editor prints !. For more information see Using the program editor.

Note that for the editor to work properly you need to have the line ending option set to Newline on the pop-up menu at the bottom of the Serial Monitor window.

eq function

Syntax: (eq item item)

Tests whether the two arguments are the same symbol, same character, equal numbers, or point to the same cons, and returns t or nil as appropriate.

eval function

Syntax: (eval form*)

Evaluates its argument an extra time.

For example:

> (eval (list '* 7 8))
56 

evenp function

Syntax: (evenp number)

Returns t if the argument is even, or nil otherwise.

first function

Syntax: (first list)

Returns the first item in a list. 

> (first '(a b c d e f))
a

Equivalent to car.

for-millis Arduino function

Syntax: (for-millis ([number]) form*)

Executes body and then waits until a total of millis milliseconds have elapsed. It returns the total number of milliseconds taken.

It can be used to define the duration of an event. For example, to play a one-second tone:

(defun bep () (for-millis (1000) (note 3 0 4)) (note))

Alternatively, if the number parameter is zero or omitted, for-millis can be used to time the execution of a function:

>  (for-millis () (fib 15))
493

On the 16-bit platforms the maximum delay is approximately 32 seconds. On the 32-bit platforms the maximum delay is approximately 24 days. If the execution of the body takes longer than this for-millis returns nil.

funcall function

Syntax: (funcall function argument*)

Calls the function with the specified arguments.

gc function

Syntax: (gc)

Forces a garbage collection and shows the number of objects collected, and the time taken.

globals function

Syntax: (globals)

Returns a list of the global variables and functions that are currently defined. For example:

> (globals)
(blu grn red)

if special form

Syntax: (if test then [else])

Evaluates test. If it's non-nil the form then is evaluated and returned; otherwise the form else is evaluated and returned.

The else form is optional.

For example:

> (if (digitalread 3) (digitalwrite 4 t) (digitalwrite 5 t))

This reads input D3. If it's high the LED on D4 is lit; otherwise the LED on D5 is lit.

incf special form

Syntax: (incf place [number])

Adds one to the value of place, and returns the new value. The second argument place can be one of the forms:

symbol
(car form)
(cdr form)
(nth n form

For more information see setf.

For example:

> (defvar a 123)
a

> (incf a)
124

> a
124

You can include an optional second argument to specify the increment.

lambda special form

Syntax: (lambda (parameter*) form*)

Creates an unnamed function with parameters. The body is evaluated with the parameters as local variables whose initial values are defined by the values of the forms after the lambda form.

For example, you could write:

((lambda (x y) (+ x y)) 4 3)

This would assign 4 to x and 3 to y, evaluate (+ x y), and return the result.

Functions are usually defined with a specified name using defun. The usual use of lambda is to create an unnamed function as the argument for a function such as mapc or mapcar. The following example uses mapcar to square every number in a list:

> (mapcar (lambda (x) (* x x)) '(0 1 2 3 4 5 6))
(0 1 4 9 16 25 36)

It is also used when you want to create a function that returns a function. The following example defines a function do2 that takes a function of one argument, and returns a function that performs that function twice:

> (defun sq (x) (* x x))
sq

> (defun do2 (fun) (lambda (arg) (fun (fun arg))))
do2

> ((do2 sq) 3)
81

length function

Syntax: (length item)

Returns the number of items in a list, or the length of a string.

Examples:

> (length '(a b c d))
> (length "hello")

let special form

Syntax: (let ((var value) … ) forms*)

Declares local variables, and evaluates forms with those local variables.

In its simplest form you can declare a list of one or more variables which will be initialised to nil, and these can then be used in the subsequent forms:

(let (a b)
  (setq a 1)
  (setq b 2)
  (* a a b))

For each variable you can specify an initial value by specifying it as a list of (variable value), so the above example is equivalent to:

(let ((a 1) (b 2)) 
  (* a a b))

let* special form

Syntax: (let* ((var value) … ) form*)

Like let, but each declaration can refer to local variables that have already been defined.

For example, defining:

(defun tst ()
  (let ((a 7)
        (b a))
    (print a) (print b)))

and evaluating (tst) will give the error:

Error: 'a' undefined

whereas defining:
(defun tst (a)
  (let* ((a 7)
         (b a))
    (print a) (print b)))

and evaluating (tst) will print 7 7.

list function

Syntax: (list item*)

Returns a list of the values of its arguments.

Example:

> (list (* 1 1) (* 2 2) (* 3 3) (* 4 4))
(1 4 9 16) 

listp function

Syntax: (listp item)

Returns t if its argument is a list.

Example:

> (listp 'b)
nil

> (listp '(a b))

The function listp differs from consp because (listp nil) is t whereas (consp nil) is nil.

load-image function

Syntax: (load-image)

Loads a saved uLisp image from EEPROM or SD card. The ATSAM and ATSAMD platforms support saving uLisp images to an SD card using an appropriate card reader; by default the image is saved to a file ULISP.IMG, but you can specify a string parameter to load the image from a file of that name.

Like save-image, the function returns the size of the image, in objects.

logand function

Syntax: (logand [value*])

Returns the bitwise logical AND of the values.

logbitp function

Syntax: (logbitp bit value)

Returns t if bit number bit in value is a '1', and nil if it is a '0'.

For example:

> (logbitp 0 1)

logior function

Syntax: (logior [value*])

Returns the bitwise logical OR of the values.

lognot function

Syntax: (lognot value)

Returns the bitwise logical NOT of the value.

logxor function

Syntax: (logxor [value*])

Returns the bitwise logical EXCLUSIVE-OR of the values.

loop special form

Syntax: (loop forms*)

The loop special form executes its arguments repeatedly until one of them reaches a return form, which exits from the loop.

For example, the following function b blinks an LED on I/O line 10 a specified number of times:

(defun b (x)
  (loop
   (digitalwrite 10 t)
   (delay 1000)
   (digitalwrite 10 nil) 
   (delay 1000) 
   (setq x (- x 1))
   (if (= x 0) (return))))

To blink the light 5 times execute:

> (b 5)
nil

makunbound function

Syntax: (makunbound symbol)

Removes the definition of a function created with defun, or a global variable created with defvar, freeing up the space.

For example:

> (makunbound 'rgb)
rgb

An error will be displayed if the symbol was undefined. 

mapc function

Syntax: (mapc function list1 [list2])

Applies the function to each element in a list or a pair of lists, ignoring the results. It returns the first list argument.

For example:

> (mapc print '(1 2 3))
1
2
3
(1 2 3) 

The function mapc is like mapcar, but it doesn't accumulate a list of results, and so is used for its side-effects. For example, if you had an RGB LED connected to I/O pins 9, 10, and 11 you could set the colour of the LED to yellow with:

(mapc digitalwrite '(9 10 11) '(255 255 0))

For examples of using mapc and mapcar see Processing items in a list.

mapcar function

Syntax: (mapcar function list1 [list2])

Applies the function to each element in a list or a pair of lists, and returns the resulting list.

The function can be a built-in function; for example:

> (mapcar * '(1 2 3) '(4 5 6))
(4 10 18) 

Alternatively it can be a user-defined function or a lambda expression; for example:

> (mapcar (lambda (x) (* x x)) '(1 2 3 4 5))
(1 4 9 16 25)

For examples of using mapc and mapcar see Processing items in a list.

max function

Syntax: (max number*)

Returns the maximum of one or more arguments. For example:

> (max 3 1 4 1 5 9 1 6)

member function

Syntax: (member item list)

Searches for an item in a list, using eq, and returns the list starting from the first occurrence of the item, or nil if it is not found.

For example:

> (member 's '(u l i s p))
(s p)

> (member 'x '(u l i s p))
nil 

millis Arduino function

Syntax: (millis)

Returns the time in milliseconds that uLisp has been running. This is a signed 16-bit number, so after 32.767 seconds the number will wrap around from 32767 to -32768.

See also for-millis.

min function

Syntax: (min numbers)

Returns the minimum of one or more arguments. For example:

> (min 3 1 4 1 5 9 1 6)

minusp function

Syntax: (minusp number)

Returns t if the argument is less than zero, or nil otherwise.

mod function

Syntax: (mod number number)

Returns its first argument modulo the second argument.

For example:

> (mod 127 10)

nil symbol

Syntax: nil

A symbol equivalent to the empty list ().

not function

Syntax: (not item)

Returns t if its argument is nil, or nil otherwise. Equivalent to null.

note Arduino function

Syntax: (note [pin] [note] [octave])

This is a lightweight replacement for the Arduino function tone. It generates a square wave on a digital pin; the following table shows which pin it uses for output on different boards:

Processor Arduino pin Typical Boards
ATmega328 3, 11 Arduino Uno, Arduino Nano
ATmega2560 9, 10 Arduino Mega 2560
ATmega1284 14, 15  
MSP430F5529 12, 19, 35 to 40 MSP430F5529 LaunchPad
MSP430FR5969 3, 4, 6 to 15, 18, 19, 21, 22 MSP430FR5969 LaunchPad

It takes three arguments:

  • A pin number, which can be one of the options shown in the above table.
  • A note number, from 0 to 11, representing the note in the well-tempered scale, where 0 represents C, 1 represents C#, and so on.
  • The octave, which can be from 3 to 6. If omitted it defaults to 0.

So to play middle C, C4, on pin 3 use:

(note 3 0 4)

To stop the note playing call note with no arguments:

(note)

The note number can be greater than 11 as an alternative way of representing notes in higher octaves. For example, the following function sca (scale) plays the scale of C on pin 3:

(defun sca () 
  (mapc 
   (lambda (n) (note 3 n 4) (delay 500))
   '(0 2 4 5 7 9 11 12)) 
  (note))

The following function wow uses the voltage on analogue input A0 to change the note:

(defun wow () (loop (let ((x (analogread 0))) (note 3 (/ x 22) 3))))

On each processor note uses Timer/Counter2, so the pins it supports are the ones assigned to OC2A and OC2B.

nothing symbol

Syntax: nothing

A symbol with no value. It is useful if you want to suppress printing the result of evaluating a function.

It is equivalent to (values) in Common Lisp.

nth function

Syntax: (nth number list)

Returns the nth item in a list, counting from zero.

Example:

> (nth 2 '(a b c d))
c

You could use nth to write a function end which returns the last item in a list:

(defun end (lis)
  (nth (- (length lis) 1) lis))

For example:

> (end '(a b c d))
d

null function

Syntax: (null item)

Returns t if its argument is nil, or nil otherwise. Equivalent to not.

numberp function

Syntax: (numberp item)

Returns t if its argument is a number.

Example:

> (numberp 'b)
nil

> (numberp (+ 1 2))
t

oddp function

Syntax: (oddp number)

Returns t if the argument is odd, or nil otherwise.

or special form

Syntax: (or item*)

Evaluates its arguments until one returns non-nil, and returns its value.

pinmode Arduino function

Syntax: (pinmode pin mode)

Sets the input/output mode of an Arduino pin number, and returns nil. The mode parameter can be one of the following:

Mode Effect
0 or nil INPUT
1 or t OUTPUT
2 INPUT_PULLUP

The MSP430 processors provide an additional INPUT_PULLDOWN option which can be selected by specifying the value of mode as 4.

plusp function

Syntax: (plusp number)

Returns t if the argument is greater than zero, or nil otherwise. Note that (plusp 0) is nil.

pop special form

Syntax: (pop place)

Modifies the value of place, which should be a list, to remove its first item, and returns that item. The second argument place can be one of the forms:

symbol
(car form)
(cdr form)
(nth n form

For more information see setf.

For example:

> (defvar a '(1 2 3 4))
a
> (pop a) 1 > a (2 3 4) 

pprint function

Syntax: (pprint item)

Prints its argument, using the pretty printer, to display it formatted in a structured way. It returns no value. For example, after defining the function var as follows:

(defun var () (loop (let* ((v (analogread 0))) (mapc analogwrite '(10 9 11)
(list (red v) (grn v) (blu v))))))
you could print it formatted using:
> (pprint var)

(lambda nil
  (loop
    (let* ((v (analogread 0)))
      (mapc analogwrite '(10 9 11) (list (red v) (grn v) (blu v))))))

The following function pp pretty-prints the definition of every function you've defined:

(defun pp ()
  (mapc 
   (lambda (x)
     (let ((v (eval x)))
       (unless (eq x 'pp)
         (when (eq (car v) 'lambda)
           (pprint (cons 'defun (cons x (cdr v)))))
         (terpri))))
   (globals))
  nothing)

prin1 function

Syntax: (prin1 item)

Prints its argument, and returns its value. Strings are printed with quotation marks and escape characters; for example:

(prin1 "He said \"hello\"")
would print:
"He said \"hello\""

prin1-to-string function

Syntax: (prin1-to-string item)

Prints its argument to a string, and returns the string. Characters and strings are printed with quotation marks and escape characters, in a format that will be suitable for read-from-string. For example:

> (prin1-to-string #\")
"#\\\""

In general,

(read-from-string (princ-to-string 'item))

will give item.

princ function

Syntax: (princ item)

Prints its argument, and returns its value. Characters and strings are printed without quotation marks or escape characters; for example:

(princ "He said \"hello\"")
would print:
He said "hello"

princ-to-string function

Syntax: (princ-to-string item)

Prints its argument, and returns its value. Characters and strings are printed without quotation marks or escape characters.

For example:

> (concatenate 'string "The result is " (princ-to-string (* 12 34 56)))
"The result is 22848"

print function

Syntax: (print item)

Prints its argument like prin1, but on a new line and followed by a space.

progn special form

Syntax: (progn form*)

Evaluates several forms grouped together into a block, and returns the result of evaluating the last form.

push special form

Syntax: (push item place)

Modifies the value of place, which should be a list, to add item onto the front of the list, and returns the new list. The second argument place can be one of the forms:

symbol
(car form)
(cdr form)
(nth n form

For more information see setf.

For example:

> (defvar a '(2 3 4))
a
> (push 1 a) (1 2 3 4) > a (1 2 3 4) 

quote special form

Syntax: (quote item)

Prevents its argument from being evaluated. Can be abbreviated to a single quote mark.

For example:

> '(+ 2 3)
(+ 2 3) 

random function

Syntax: (random number)

Returns a random number between 0 and one less than its argument. For example, to simulate a dice throw:

(+ (random 6) 1)

read function

Syntax: (read)

Reads an atom or list from the serial input and returns it.

read-byte function

Syntax: (read-byte stream)

Reads a byte from a stream and returns it.

read-from-string function

Syntax: (read-from-string string)

Reads an atom or list from the specified string and returns it.

For example:

> (eval (read-from-string "(* 7 8)"))
56

Any additional characters after the atom or list are ignored; for example:

> (read-from-string "(+ 1 2) (+ 3 4)")
(+ 1 2)

read-line function

Syntax: (read-line [stream])

Reads characters from the serial input up to a newline character, and returns them as a string, excluding the newline.

If stream is specified the line is read from the specified stream.

rest function

Syntax: (rest list)

Returns a list with the first item removed.

> (rest '(a b c d e f))
(b c d e f)

Equivalent to cdr.

restart-i2c function

Syntax: (restart-i2c stream [read-p])

Restarts an i2c-stream.

If read-p is nil or omitted the stream is written to.

If read-p is an integer it specifies the number of bytes to be read from the stream.

return special form

Syntax: (return [value])

Returns the optional value from a loop clause.

reverse function

Syntax: (reverse list)

Returns a list with the elements of list in reverse order. For example:

> (reverse '(1 2 3 4 5))
(5 4 3 2 1) 

The function reverse is useful if you have been using cons to add elements onto the front of a list, but you want to return the list with the earliest elements at the front. For example, the following function log reads x values on analogue input A0 once a second, and returns the list of values:

(defun log (x)
  (let ((lst nil))
    (dotimes (j x (reverse lst))
      (setq lst (cons (analogread 0) lst))
      (delay 1000))))

If the voltage was slowly rising on A0 you might get:

> (log 10)
(14 16 27 38 49 79 102 134 156 178)

room function

Syntax: (room)

Returns the number of free Lisp cells remaining.

> (room)
280

save-image function

Syntax: (save-image [symbol])

Saves the current uLisp image to EEPROM or SD card so it can be loaded using load-image.

To save the current image give the command:

(save-image)

The command will return the size of the image, in objects. For example, since each object is four bytes, an ATmega328 with 1 Kbytes of EEPROM has room for an image containing 256 objects.

The ATSAM and ATSAMD platforms support saving uLisp images to an SD card using an appropriate card reader; by default the image is saved to a file ULISP.IMG, but you can specify a string parameter to load the image from a file of that name.

To save the current image, and make it automatically load the image on reset and run a specified function, give the command:

(save-image 'function)

This allows you to make a stand-alone uLisp application. For example, define b as follows:

(defun b ()
  (pinmode 13 t) 
  (loop
   (digitalwrite 13 t) 
   (delay 1000) 
   (digitalwrite 13 nil) 
   (delay 1000)))

Then save the image by entering:

(save-image 'b)

If you now reset the Arduino the image will load automatically, and the function b will be run, flashing the LED on pin 13, even if the Arduino is not connected to a computer.

If there isn't enough EEPROM space to save the image, the following error will be displayed;

Error: Image size too large: 258

You should then free some space with makunbound, and try again.

second function

Syntax: (second list)

Returns the second item in a list. 

> (second '(a b c d e f))
b

A more memorable name for cadr.

setf special form

Syntax: (setf place value)

Modifies an existing list by setting the position in the list specified by place to the result of evaluating value. The second argument place can be one of the forms:

symbol
(car form)
(cdr form)
(nth n form

first and rest can also be used as synonyms for car and cdr.

The following examples illustrate each of these options.

variable

(setf symbol value)

This is equivalent to:

(setq symbol value)

car

(setf (car form) value)

Replaces the car of the value of form with value. For example:

> (defvar a '(b c))
a

> (setf (car a) 'e)
e

> a
(e c) 

cdr

(setf (cdr form) value)

Replaces the cdr of the value of form with value. This is particularly useful in conjunction with assoc, to change the value associated with a key in an association list. For example:

> (defvar col '((red . 23) (blu . 34) (grn . 45)))
col

> (setf (cdr (assoc 'grn col)) 100)
100

> col
((red . 23) (blu . 34) (grn . 100))

nth

(setf (nth n form) value)

Replaces the nth value of the list form with value. This allows you to use a list of items as an array, accessed by the index of each item. The following example uses xyz as an array of coordinates in three dimensions:

> (defvar xyz '(0 0 0))
xyz

> (setf (nth 0 xyz) 90)
90

> (setf (nth 1 xyz) 45)
45

> xyz
(90 45 0)

setq special form

Syntax: (setq symbol value)

Sets the value of the second argument to the variable specified in the first argument:

> (setq a (+ 1 2 3))

sort function

Syntax: (sort list test)

Sorts the list according to the test function, and returns the sorted list. Note that for efficiency the sort is destructive, meaning that the value of list may be changed by the operation.

For example:

>  (sort '(3 1 4 1 5 9) <)
(1 1 3 4 5 9)
>  (sort '("dog" "cat" "ant" "eel" "owl" "mouse") string<)
("ant" "cat" "dog" "eel" "mouse" "owl")

The test function could be a lambda expression; for example, to sort strings into ascending order of length:

> (sort '("giraffe" "lion" "ape" "rhino") (lambda (x y) (< (length x) (length y))))
("ape" "lion" "rhino" "giraffe")

string function

Syntax: (string item)

Converts its argument, which should be a character or a symbol, to a string.

For example:

> (string #\*)
"*"

> (string 'cons)
"cons"

string< function

Syntax: (string< string string)

Returns t if the first string is alphabetically less than the second string, and nil otherwise. For example:

> (string< "cat" "cats")
t

string= function

Syntax: (string= string string)

Tests whether two strings are the same.

string> function

Syntax: (string> string string)

Returns t if the first string is alphabetically greater than the second string, and nil otherwise. For example:

> (string> "mouse" "mice")
t

stringp function

Syntax: (stringp item)

Returns t if the argument is a string and nil otherwise.

subseq function

Syntax: (subseq string start [end])

Returns a substring from a string, from character start to character end-1:

> (subseq "hello" 0 3)
"hel"

If the third argument is omitted subseq returns from start to the end of the string:

> (subseq "hello" 3)
"lo"

The following example day returns a three-letter day string for the day number 0 to 6:

(defun day (d)
  (subseq "MonTueWedThuFriSatSun" (* 3 d) (* 3 (1+ d))))

symbol

Syntax: t

A symbol representing true.

terpri function

Syntax: (terpri)

Prints a new line, and returns nil. 

third function

Syntax: (third list)

Returns the third item in a list. 

> (third '(a b c d e f))
c

A more memorable name for caddr.

trace special form

Syntax: (trace [function]*)

Turns on tracing of up to three user-defined functions. It returns a list of the functions currently being traced; for example:

> (trace fac)
(fac sq)

Giving (trace) with no arguments returns a list of the functions currently being traced.

Tracing a function prints out the call depth, and a list of the arguments each time the function is called, and the call depth and result each time the function returns.

For example, if you defined:

(defun fac (n)
  (if (= n 1) 1
    (* n (fac (- n 1)))))

you can turn on tracing of fac by typing:

> (trace fac)

Calling fac as follows:

> (fac 4)

will print this trace output:

0: (fac 4)
  1: (fac 3)
    2: (fac 2)
      3: (fac 1)
      3: fac returned 1
    2: fac returned 2
  1: fac returned 6
0: fac returned 24
24

Note that trace will not show calls to functions supplied as an argument to another function, such as apply, funcall, mapc, or mapcar, because in these cases only the body of the function is passed. For example:

(defun sq (x) (* x x))
(trace sq)
(mapcar sq '(1 2 3))

The solution is to wrap the function call in a lambda:

(mapcar (lambda (x) (sq x)) '(1 2 3))

unless special form

Syntax: (unless test form*)

Evaluates the test. If it's nil the forms are evaluated and the last value is returned.

For example:

> (unless (digitalread 3) (digitalwrite 4 t))

This reads input D3. If it's low the LED on D4 is lit.

untrace special form

Syntax: (untrace [function]*)

Turns off tracing of the specified user-defined functions.

To turn off tracing for all functions type:

> (untrace)

This returns a list of the functions that have been untraced.

when special form

Syntax: (when test form*)

Evaluates the test. If it's non-nil the forms are evaluated and the last value is returned.

For example:

> (when (digitalread 3) (digitalwrite 4 t))

This reads input D3. If it's high the LED on D4 is lit.

with-i2c special form

Syntax: (with-i2c (stream address [read-p]form*)

Evaluates the forms with stream bound to an i2c-stream defined by address.

The I2C interface works with the following pins on different processors:

Processor SDA pin SCL pin
ATmega328 18 (A4) 19 (A5)
ATmega2560 20 21
ATmega1284 17 16
MSP430F5529 10 9
MSP430FR5969 10 9

If read-p is nil or omitted the stream is written to.

If read-p is an integer it specifies the number of bytes to be read from the stream.

If the start operation succeeds the stream is bound to an i2c-stream:

> (with-i2c (str #x70) str)
<i2c-stream #x70>

If the start operation fails the stream variable is bound to nil:

> (with-i2c (str #x71) str)
nil

This allows you to write a very simple port scanner to find all the I2C devices on the bus:

(defun scn () 
  (dotimes (p 127)
    (with-i2c (str p)
      (when str (print p)))))

On the MSP430 versions the port scanner needs to be written:

(defun scn ()
  (dotimes (p 127)
    (with-i2c (str p)
      (when (restart-i2c str) (print p)))))

with-serial special form

Syntax: (with-serial (stream port [baud]form*)

Evaluates the forms with stream bound to a serial-stream using serial port port.

The serial interface works with the following pins on different processors:

Processor Port 0 (RX, TX) Port 1 (RX, TX) Port 2 (RX, TX) Port 3 (RX, TX)
ATmega328 0, 1      
ATmega2560 0, 1 19, 18 17, 16 15, 14
ATmega1284 14, 15 16, 17    
MSP430F5529 45, 46 3, 4    
MSP430FR5969 21, 22 3, 4    

By default the baud rate is 9600. You can specify the following baud rates by specifying the third baud parameter as one of the following values:

3, 6, 12, 24, 48, 96, 144, 192, 288, 384, 576, or 1152.

Note that the baud rate is the baud parameter times 100; for example, for 38400 baud specify 384.

For example, if you define:

(defun listen ()
  (with-serial (str 1 96)
    (loop
     (print (read-line str)))))

and then connect the Port 1 RX pin to the TX pin of a GPS module, running the listen program by typing:

(listen)

will display output from the GPS module; for example:

"$GPRMC,183534.000,A,5213.1091,N,00008.2271,E,0.39,248.14,201117,,,A*61
"$GPVTG,248.14,T,,M,0.39,N,0.72,K,A*39

with-spi special form

Syntax: (with-spi (stream pin [divider] [lsbfirst] [mode]form*)

Evaluates the forms with stream bound to an spi-stream using pin as the enable pin.

The SPI interface works with the following pins on different processors:

Processor MOSI pin MISO pin SCK pin
ATmega328 11 12 13
ATmega2560 5 6 7
ATmega1284 51 50 52
MSP430F5529 15 14 7
MSP430FR5969 15 14 7

By default the system clock is divided by 4, giving a speed of 4 MHz with a 16 MHz clock. Alternatively you can specify a divider parameter as follows:

Parameter Divider
1 2
2 4
3 8
4 16
5 32
6 64
7 128

By default the bit order is MSB first. Alternatively set the lsbfirst parameter to t for LSB first.

By default the mode is SPI Mode 0. Alternatively set the mode parameter to a number from 0 to 3 to specify the mode.

write-byte function

Syntax: (write-byte number [stream])

Writes a byte to a stream.

write-line function

Syntax: (write-line string [stream])

Writes a string terminated by a newline character. If stream is specified the string is written to the stream.

write-string function

Syntax: (write-string string [stream])

Writes a string. If stream is specified the string is written to the stream.

zerop function

Syntax: (zerop number)

Returns t if the argument is zero, or nil otherwise.