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)