Command Expressions

A number of commands in the editor use command expressions, or 
exprs, to compute results that are then processed by the command 
in some manner.  For example, the editor's Set command evaluates 
exprs to return new slot values for the referenced objects.  The 
editor's Map command evaluates exprs in the context of each 
referenced object to compute statistics that are displayed in an 
information table.  A value expression may be as simple as a 
variable or slot name, or may involve complicated parenthetical 
expressions.  Though exprs are evaluated and may involve Lisp's 
prefix notation, they are not strictly Lisp.  Exprs implement a 
number of changes and additions to basic Lisp syntax in order to 
support a comfortable yet terse input style.  For example, the 
simple command expression:

	$rhythm

is roughly equivalent to the Lisp expression: 

	(or (and (slot-exists-p (mapped-object) 'rhythm)
	         (slot-boundp (mapped-object) 'rhythm)
	         (slot-value (mapped-object) 'rhythm))
	    0)

Since command expressions are not strictly Lisp, they are only 
meaningful in conjunction with commands that understand their 
syntax and evaluation rules.   These commands are: MAP, SET,
INCREMENT, SCALE, TRANSPOSE, INVERT. These commands are 
called mapping commands because they all map expressions over 
the references supplied to the command, and evaluate each 
expr in the context of each object mapped in the reference.  The 
token $rhythm, then, really means: "the value of the slot named 
rhythm in the currently mapped object, or 0 if that object has 
no rhythm."  Note that when referencing by group there is no 
"currently mapped object" to speak of, since all members of a 
group are mapped in parallel.  To access slot values and so 
fourth of an object within the currently mapped group, the 
access must be qualified with the object's index into the group. 
This index ranges from 1 to the width of the group, and is 
specified inside brackets after the basic name.  For example:

	map :::2 find (= $rhythm[1] $rhythm[2])

would perform a pairwise examination of all the objects in * and 
return the index of each pair of objects that have the same value 
in their rhythm slots.

Command expression syntax and evaluation rules

Here is a brief summary of the syntax and evaluation rules for 
command expressions.

1) A constant (string, number, defconstant or any quoted form) 
may appear anywhere in an expr and evaluates to its constant 
value.

2) An unquoted list may appear anywhere in an expr. If the first 
element is a valid function, the list is treated as a function 
call.  Arguments to the function themselves treated as exprs.  
If the first element is not a function, the list is treated as 
constant data.

3) An unbound symbol (a symbol that does not have a value) may 
appear anywhere in an expr and is considered constant data.

4) A token whose first character is $, for example $ or $rhythm 
or $rhythm[1], may appear anywhere in an expr to reference an 
object or slot value in an object.  If $ appears without a 
qualifying name it references the currently mapped object itself, 
or the $[nth] object if referencing by groups.  When $ appears in 
conjunction with a name, for example $freq or $amp[2], it 
references the value of the named slot, or 0 if the slot is 
unbound or does not exist. (If the token ? is substituted for $, 
the slot expression will return a value or nil instead of 0.)  
In addition to slot names, the dollar notation also support the 
token class, which returns the class name of the currently mapped 
object.  For example:

	map * count (eq $class Rest)

would return the number of rests found in all the objects in *.  
The $ and ? notation is admittedly crufty, but it serves to 
distinguish between slot value references and normal Lisp 
variable references, which are also legal in exprs.

5) An expr that is an item stream description is pre-evaluated 
to produce the item stream, and the stream object is 
automatically read using the item function.  For example:

	set * note (pitches c4 d e in random)

would set the note slot of each object in * to successive 
pitches read from a random pitch stream.

5) An expr directly preceded by a comma is pre-evaluated before 
the command starts, and the result of this evaluation is used as 
the expr specification for the mapping.  This allows, in effect, 
the computation of the mapping expression.

There are also several variables that are useful when working 
with value expressions.

1) The expr variables @ and @+1 may appear anywhere in an expr 
and are bound to the container position (zero and one based, 
respectively) of the currently mapped object.  @ and @+1 are 
useful in conjunction with interpolating envelopes, for example:

	set * freq (interpl @ 0 220.0 40 440.0)

would set the freq slot of the (presumably forty) objects in * to 
an interpolated value between 200.0 and 400.0 Hz.  It is also 
possible to qualify @ and @+1 by a group index, for example, @[1] 
would mean the container position of the first element in the 
currently mapped group. 

2) The expr variable % may appear anywhere in an expr and is 
bound to the the container position of the currently mapped 
element expressed as a percentage. % is particularly useful in 
conjunction with normalized interpolating envelopes, for example:

	set * freq (interpl % 0 220.0 100 440.0)

would set the freq slot of the elements in * to an interpolated 
value between 200.0 and 400.0 Hz. It is possible to qualify % by 
a group index, for example, %[1] would mean the percentage 
position of the first element in the currently mapped group.

3) The special variable $$ may appear anywhere in an expr and 
is bound to the container (if only one) whose object is 
currently being mapped.


4) The mapping variables @ @+1 and %, and the special variable ?
all have functional equivalents:

	   (@ object &optional container)
	   (@+1 object &optional container)
	   (% object &optional container)
	   (? object slot &optional value)
