Like its parent language lisp, lush calls commands using a space-separated list of items within a pair of parentheses:

(function_nameargument_1 ... argument_n)

Also notice that entering (print "Hello world") not only printed "Hello world", but also returned a "Hello world" string. You can see this in the output above, where the terminal shows the result of the entered expression as being = "Hello world". This brings us to an important point: All lush statements have a return value. The closest equivalent to "void functions" in C/C++/Java are functions that return the empty list (). Lush has a C-like printf function which does just that:

If you can't remember the exact name of the function or variable, you can type the first few letters of its name and hit tab. If there is an unambiguous completion, lush will fill in the rest of the letters for you. If there are more than one symbols that fit the bill, hitting tab again will display a list of possible completions. For example, typing (prin and hitting tab twice will display the following:

All lisp programs are a series of lists within lists, and the program proceeds by evaluating each list from left to right. This means that the first element in each list is treated as a function, and the rest of the elements are treated as the arguments. Once evaluated, a list returns a value (possibly (), the empty list).

As shown above, all lists in lisp are evaluated. This can be unwelcome when you want to make a variable that is itself a list. Here's an example of a naive attempt at list creation:

(defparameter possible-baby-names ("Grendel" "Greta" "Garbanzo"))

Result:

*** "Grendel" : can't evaluate this list
Debug toplevel [y/N] ?

The problem is that we never intended the string "Grendel" to be treated as a function, but lisp doesn't know that. There are two ways around this. One is to use the quote operator by putting a single ' before the list:

(defparameter my-list '("Grendel" "Greta" "Garbanzo"))

This works well enough in this case, where all the list elements are "literals", or expressions that can be used as-is, in a cut-and-paste manner. Sometimes, however, we want to put the results of calculations in our lists. In such a case, the above technique will produce the following undesired result:

(defparameter my-list '(1 2 (+ 1 2)))
(print my-list)

Result:

(1 2 (+ 1 2))

So the quote operator not only prevents the first element from being used as a function, it prevents all list items from being evaluated. Thus, the quote operator is useful primarily for moving around unevaluated code snippets rather than constructing lists as variables (see Macros).

What we want instead is to use the (list list-constructor:

(defparamter my-list (list 1 2 (+ 1 2)))
(print my-list)

Result:

(1 2 3)

To summarize, use (list ...) to construct lists, and use the quote operator to manipulate unevaluated snippets of code. You'll probably use (list ...) most of the time.

For the interested, there's more in the Lisp tricks section. These include things like passing around functions like variables, creating anonymous functions on the fly ("lambda functions"), and links to helpful lisp references.

Declaring and setting a global variable can be done using the defvar or defparameter command:

(defvar pi 3.14)
(defparameter time 20)

The two are identical except for one important detail: if a previous defvar statement has already set the value of a symbol, a second defvar on the same symbol name will do nothing. defparameter, on the other hand, will always set the value as told:

(defvar pi "three point one four") ; does nothing!
(defparameter time 100000) ; time set to 100000

defvar should therefore be used with caution, especially when running lush programs from within the lush shell. If you run a program with a defvar statement, Edit the file to change the variable's value, then re-run the program, the variable will remain unchanged.

let* defines the variables in the order they're listed, while let makes no such guarantees, allowing for possible parallelism. Unless you're sure that this is what you want, you should stick to let*. let*/let statements return the last expression evaluated, making them handy for setting up function calls with lots of arguments without cluttering the current scope with the argument variables. The following example creates a list for dinner, consisting of milk, rice, and curry:

Once declared, variable values can be changed using setq from lisp. The following shows a numerical variable theta being set to equal another variable pi.

$ (setq theta pi)

As shown above, applying setq on numerical values sets the first variable to be an equal but separate copy of the second variable. As in lisp, this is also true for variables containing lists. Variables pointing to objects are another story; the variables themselves are like pointers in C/C++, where assignment just changes the value of the pointer.

In lush, as in lisp, empty and non-empty lists represent the boolean "true" and "false". You can also use the literals t and nil. Unlike lisp, lush has many objects other than lists, and these all evaluate to "true".

Lush inherits some historical baggage from lisp in the form of the "true" literal t. Such a short literal name is bound to be used by the occasional careless newbie as a local variable, to represent time for example. While lush will prevent a user from creating a global variable named t, a local variable named t will likely cause subtle and silent errors.

Unlike in C/C++, the integer value of 0 or pointer value of NULL will not be considered 'false' in a lush conditional. To make a lush conditional understand an integer or C boolean expression, one must use the to-bool function:

Most iterations will be done over elements of numerical arrays (vectors, matrices, or tensors). While one could do so using for or while loops, the following iterator functions provide a more convenient alternative.

Unlike the for or while loops, array loop expressions return the first array in the array list, not any of the expressions evaluated in the body.

The sub-arrays are allocated on the heap and should not be expected to persist outside of the loop, even when you assign them to an external symbol. Doing so can lead to fatal and mysterious memory errors.