WhizzML Reference Manual

3.2 Definitions

3.2.1 Variable assignments

A global variable is associated with a (possibly newly created) location and value by means of the define keyword:

(define <id> <expression>)

E.g.:

(define age 46)
(define name "Biel")
(define same-name name)

3.2.2 Parallel variable assignments

It is possible to define in parallel more than one variable with a singl define form by using an explicit list of identifiers instead of a single one:

(define [<id0> ... <idn>] <expression>)

The above expression will be translated to the semantic equivalent of:

(define tmp-var <expression>)
(define <id0> (nth tmp-var 0))
...
(define <idn> (nth tmp-var n)

where tmp-var is a fresh, private name. From this equivalence it follows that <expression> can evaluate to a list of more than n elements: the trailing ones will simply be ignored.

For instance:

(define [a b] [1 2])
a ;; => 1
b ;; => 2
(define (alist h) (list h true false "extra"))
(define [c d e] (alist "a"))
c ;; => "a"
d ;; => true
e ;; => false

As in the case of destructuringlet bindings, dot notation is also available (cf. subsection 2.7.1 ):

(define [<id0> ... <idn> . <y>] <expression>)

translates to:

(define tmp-var <expression>)
(define <id0> (nth tmp-var 0))
...
(define <idn> (nth tmp-var n)
(define <y> (drop n tmp-var))

For instance:

(define [a b . c] (range 10))
a ;; => 0
b ;; => 1
c ;; => [2 3 4 5 6 7 8 9]

3.2.3 Procedure definitions

Since naming procedure values by assigning them to a variable via define is a very common need, WhizzML provides special syntax for doing it in a shorter form. Formally, the two following definitions are equivalent:

(define <p-id> (lambda (<id1> ... <idn>) <body>))
(define (<p-id> <id1> ... <idn>) <body>)

as are the two following ones for variadic procedures:

(define <p-id> (lambda (<id1> ... <idn> . <idn+1>) <body>))
(define (<p-id> <id1> ... <idn> . <idn+1>) <body>)

Thus, instead of defining the inc procedure as

(define inc (lambda (x) (+ x 1)))

one can write, equivalently and more idiomatically,

(define (inc x) (+ x 1))

The same pattern applies for any number of arguments:

(define rand-less-than-42 (lambda () (rand-int 42)))
(define (rand-less-than42) (rand-int 42))

(define safe-div (lambda (x y) (if (= y 0) 0 (/ x y))))
(define (safe-div x y) (if (= y 0) 0 (/ x y)))

and, in the same way, to functions that take a variable number of arguments. Instead of

(define add (lambda (x . xs) (apply + x xs)))
(define to-list (. xs) xs)

one can define add and to-list more directly with:

(define (add x . xs) (apply + x xs))
(define (to-list . xs) xs)