Lush/Beginning Lush

This chapter covers the basic syntax of lush. For discussion of classes, see Classes and Objects.

Getting Started
Like most interpreted languages, lush commands can be run interactively from the lush prompt, or as a batch of statements from a text file.

Hello World
To begin, start lush by typing "lush" or "lush.exe" (for windows) in a terminal: This will print a copyright notice, then put you in interactive mode with a lush prompt: The following line will print the familiar first words: Result: Like its parent language lisp, lush calls commands using a space-separated list of items within a pair of parentheses: Also notice that entering  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. 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  function which does just that: Result:

Interactive mode features
There are some usability features built into the lush shell:

Online help
The following command will bring up a GUI interface to a reference dictionary of all things lush. That is the first thing to try when looking for a particular function that you know must exist. Alternately, if you already know the function name, you can enter the following on the lush prompt:

Tab completion
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  and hitting tab twice will display the following:

Command history
Hitting the up-arrow key will cycle through previously entered statements.

UNIX shell commands
A few common shell commands familiar to UNIX/Linux weenies are available within lush, in the form of functions. For example:

Control-key shortcuts
Several keyboard shortcuts will be familiar to users of the bash shell or emacs:
 * ctrl-a, ctrl-e: Go to the beginning/end of the line.
 * ctrl-left, Ctrl-right: skip words.

Caret shortcuts
Some functions have shortcuts of the form _. These include: Remember not to put a space between the  and its argument.
 * ^Afunction_name: Prints help about the function.
 * ^Lsource_file.lsh : Loads and runs a source file (see "Running a source file" section below).

Running a source file
A series of lush statements constitutes a lush program, and can be saved in a text file and run in batch mode: hello-world.lsh To run hello-world.lsh from your shell, type: Alternately, you can run it from within the lush shell, using the  function: The ".lsh" suffix is optional. Alternately, you can use 's caret shortcut  : These filenames may also be tab-completed.

Just enough lisp to get by
Lush takes its list-based syntax straight from lisp. This section is for those with no lisp experience.

How lisp works
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). In the above example, the innermost lists (the ones starting with the  functions) evaluate out to homework and exam grades: Their enclosing lists (starting with  evaluate out to these grades scaled by some factor: The next enclosing list (starting with   sums these scaled grades: And the outermost list  takes this sum and assigns it to the variable " ". It too returns a value, in this case the value of the assigned variable:

Creating lists
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: Result: The problem is that we never intended the string  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: 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: Result: 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-constructor: Result:

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

List manipulation
Discuss car, cdr, cons and append

More
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 global variables
Declaring and setting a global variable can be done using the  or   command: The two are identical except for one important detail: if a previous  statement has already set the value of a symbol, a second   on the same symbol name will do nothing. , on the other hand, will always set the value as told: should therefore be used with caution, especially when running lush programs from within the lush shell. If you run a program with a  statement, Edit the file to change the variable's value, then re-run the program, the variable will remain unchanged.

Declaring local variables
The  and   statements can be used to declare local variables. It consists of a list of  pairs, followed by a body of code that may use the declared variables: The following example declares four local variables, then uses them to make curry: defines the variables in the order they're listed, while  makes no such guarantees, allowing for possible parallelism. Unless you're sure that this is what you want, you should stick to. / 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:

Setting values
Once declared, variable values can be changed using  from lisp. The following shows a numerical variable  being set to equal another variable. 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.

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

The dreaded
Lush inherits some historical baggage from lisp in the form of the "true" literal. 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, a local variable named   will likely cause subtle and silent errors.

Booleans in compiled Lush
Unlike in C/C++, the integer value of 0 or pointer value of  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  function:

Loops
Lush provides the traditional for and while loops, and more specialized functions for iterating over arrays.

For loops
Syntax:

Here is an example of printing the number from 0 through 10 using a for loop:

The counter  iterates through all values between 0 and 10 including 10. The loop expression returns the last expression evaluated within the loop.

You can specify the step size with an optional third argument:

While loops
Syntax: While loops are useful for iterating through lists: Like the for loop, the while loop returns the last expression evaluated in body.

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

idx-bloop
iterates through successive sub-arrays of an array by iterating through its first dimension. For example, the rows of a matrix can be printed as follows: Output:

You can iterate over multiple arrays simultaneously, so long as their first dimensions contain the same number of elements:

idx-gloop
is an extension of  that provides a counter variable, as in a   loop. Here is an  version of the row-printing example: Output:

idx-eloop
is simply an  that iterates over the last index rather than the first. For example, when applied to matrices, an  would iterate over its columns, not its rows.

Array iteration gotchas

 * Unlike the  or   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.