Nu Syntax

Nu has a very simple syntax. On the surface, this may seem strict and conservative, but in many important ways it allows Nu to be liberal and permissive.

Elements

The basic elements of Nu are symbols, numbers, strings, characters, regular expressions, and punctuation.

Symbols

Symbols are sequences of characters that exclude punctuation and whitespace. Symbols are used as names for values. Names may be assigned values using the set operator.

Anything that can be parsed as a number is not a symbol. Numbers may not be assigned values; by definition, a number is its own value.

Symbols may include the colon character (':'), but only as the last character of the symbol. A symbol that ends with a colon is called a label. A colon forces the parser to end the current symbol and begin scanning something new. This allows us to write label:value pairs without having to include a space between the label and its associated value.

Numbers

Anything that looks like a number is a number. If a token can be converted to a long with strtol(), it's an integer, and if it can be converted to a double with strtod() then it's a floating point number. Both integer and floating point values are represented with instances of NSNumber.

Strings

Strings are represented with instances of NSString. They can be defined in two ways and have one special feature.

Double-quoted strings

Sequences of characters enclosed in double quotes are treated as strings. Double-quoted strings must be defined on a single line; these strings may not contain newlines. These strings also may not contain double quotes. Here is an example, which also illustrates the use of the set operator:

(set author "Isaac Asimov")

Here strings

Multiline strings and strings containing double quotes can be created using Nu's "here string" notation. A here string declaration begins with the three characters "<<-" or "<<+" immediately followed by an identifier that will be used to mark the end of the string. This identifier ends at a newline, after which follows the definition of the string. Here is an example.

(set poem <<-END
On Jupiter's second moon
Few of the folks are at all well to do
They work and they sweat
but they're always in debt
for their kids all attend Io U.END)

String Interpolation

A string can contain embedded Nu code which is replaced with its evaluated results whenever the string itself is evaluated. Here is an example.

% (set laws "Asimov defined #{(+ 1 1 1)} laws of Robotics")
% (puts laws)
Asimov defined 3 laws of Robotics

Character Escape Sequences

Escape sequences are supported in both double-quoted and here strings. Double-quoted strings are escaped by default. For example, "foo\nbar" is parsed as a seven-character string with a newline in the middle.

Strings that are prefixed with a minus sign (-) explicitly disable escaping. For example, -"foo\nbar" is parsed as an eight character string with a slash and 'n' in the middle. Strings that are prefixed with a plus sign (+) explicitly enable escaping. For example, +"foo\nbar" is parsed as a seven-character string with a newline in the middle.

Here strings that begin with the "<<-" notation explicitly disable escaping. The following example shows an unescaped string:

(set x <<-END
foo\nbarEND)

Here strings that begin with the "<<+" notation explicitly enable escaping. The following example shows an escaped string:

(set x <<+END
foo\nbarEND)

There is no ambiguous form for here strings.

These escape sequences are supported:

\n newline (0x0a)
\r carriage return (0x0d)
\f formfeed (0x0c)
\b backspace (0x08)
\a bell (0x07)
\e escape (0x1b)
\s space (0x20)
\nnn octal byte
\xnn hexadecimal byte
\unnnn unicode character (16 bits)
\x character x

Character Literals

Character literals are single characters or escape sequences enclosed in pairs of single quotes ('). The same escape sequences are supported for character literals and strings. Internally, a character literal is represented by an NSNumber with the appropriate unicode value. This is the same value and type that is returned by the NSString characterAtIndex: method.

Regular Expression Literals

Regular expressions may be specified with the following form:

/regex/options

Here "regex" is a regular expression and "options" is a string of lower-case alphabetic characters.

The available options correspond to the options available for the NuRegex class:

i case insensitive comparison
s dot metacharacter also matches newlines
x allow whitespaces and comments in pattern
l lazy quantifiers become greedy and vice versa
m caret and dollar anchors match at newlines

For example, /^f(o+)$/i matches strings "fo", "FOO", and "fooooOOOOO".

To include forward slashes in regular expressions, prefix each forward slash with a backslash.

Punctuation (Special Characters)

A small number of characters are reserved for punctuation.

character(s)usage
parenthesesdenote lists
single quotesquote objects, preventing evaluation
double quoteswrap strings
semicolons and
hash characters
begin comments

Comments

Comments begin with a semicolon or hash character and span a single line.

; This is a comment
# This is a comment

Expressions

Expressions are the syntactic building blocks of Nu. Expressions are written and represented internally as lists. Expressions are sequences of symbols, numbers, and strings enclosed in parentheses. Expressions frequently also contain other expressions.

(a first level expression may contain
   (a second level expression that contains
       (a third level expression
          (and this can continue arbitrarily))))

Operators

When an expression is evaluated, the first element of the expression is examined and evaluated. Usually that first element is a symbol, and often when that symbol is evaluated, it corresponds to an operator. When this occurs, the operator is evaluated with the rest of the expression as its arguments.

In general, an operator may or may not evaluate its arguments and sometimes may evaluate its arguments multiple times. This allows Nu to implement common control structures such as while and if as operators.

For a special class of operators, called functions, all of the arguments are evaluated before the function itself is evaluated. The function is then evaluated with the evaluated arguments. As a result, an expression like (+ 2 (- 4 2)) becomes (+ 2 2) and then 4.

Operators can be defined in Nu code using the function and do operators, which both create functions, and the macro operator, which creates more general operators.

Messages

Everything in Nu is an object, and every object in Nu responds to messages.
Nu's messaging system is built on Objective-C, and Nu code can send messages to objects whether those messages were written in Nu or Objective-C. Similarly, Objective-C code can send messages to objects with no regard for their implementation language. Frequently classes will include methods written in both languages.

The Nu message sending syntax is identical to its function call syntax. A message send is a list. The first element of the list is the target of the message and the rest of the list describes the message. Messages that have no arguments look like this:

(array count)

Messages that have a single argument look like this:

(array objectAtIndex: 1)

Here the second element of the list is a label that is also called the message selector. Immediately following the label is the message's argument.

Messages with multiple arguments look like this:

(array writeToFile:"myfile" atomically:NO)

Here the writeToFile: and atomically: labels together form the message selector writeToFile:atomically:. Each label is followed by an associated argument, in this case the string "myfile" and the symbol NO which is globally defined to zero.

In Nu, operator calls have a higher precedence than message sends. But it is still possible to send messages to operators using the send operator. Here is an example that uses the send operator to get the context of a block.

% (set y 32)
32
% (set block (do (x) (+ 1 y)))
(do (x) ((+ 1 y)))
% (send block context)

% ((send block context) description)
{
    y = 32; 
    ... implementation details...
}

Quoted Lists

Normally, Nu evaluates lists that are defined in Nu source text; these lists represent operator calls and message sends. But sometimes lists are used to represent data. In these cases, the quote operator can be used to prevent evaluation.

(quote (1 2 3))

As a convenience, the single quote character can be used to equivalently quote objects.

'(1 2 3)

quote can also be used on objects besides lists; often it is used to refer to a symbol without evaluating it.

Quasiquote

The quasiquote operator is similar to Nu's quote operator, except that quasiquote allows evaluation of selected subforms within the quasiquoted form by using quasiquote-eval or quasiquote-splice. Each of the quasiquote operators has a convenient abbreviation that is commonly used in place of the spelled-out operator name:

Operator Abbreviation
quasiquote`
quasiquote-eval,
quasiquote-splice,@

By itself, quasiquote works just like quote:

% `(a b c)
(a b c)

quasiquote-eval can be used to turn on evaluation for selected subforms:

% (set a 1)
1
% (set b 2)
2

% ; turn on evaluation for b
% `(a ,b c)
(a 2 c)

A more complex evaluation:

% `(x y z ,a ,b ,(+ a b))
(x y z 1 2 3)

quasiquote-splice also evaluates its form, but it differs from quasiquote-eval in how the result is returned. With quasiquote-splice, the evaluation must return a list. This list is then "spliced" in-line within the surrounding form of the caller by inserting the contents of the list (not the list itself) into the caller's list:

% ; Using quasiquote-eval:
% `(1 ,(list 2 3))
(1 (2 3))

% ; Using quasiquote-splice:
% `(1 ,@(list 2 3))
(1 2 3)

Neither quasiquote-eval nor quasiquote-splice can be used outside of a quasiquote form.

% (list 1 ,a)
NuQuasiquoteEvalOutsideQuasiquote: Comma must be inside a backquote

The quasiquote operators are particularly useful when writing macros, as the code in the macro body ends up looking much closer to the code that the macro-expansion phase generates.