compile/define
Symbol: compile/define
define is the Scheme-layer spelling. Koskari code binds a value with
var and a function with
def; see
Bindings and refs.
Syntax:
Function:
(define [NAME FORMALS ...] BODY ...)or(define (NAME FORMALS ...) BODY ...)Typed function:
(define [(NAME :: TYPE) FORMALS ...] BODY ...)or(define [(NAME type: TYPE) FORMALS ...] BODY ...), the return type bundled with the name as a typed formal bundles,(n :: int)Declaration only:
(define NAME),(define NAME :: TYPE), or(define NAME type: TYPE)Declare and store:
(define NAME VALUE),(define NAME :: TYPE VALUE), or(define NAME type: TYPE VALUE)
The form of the first operand selects the arm. A pair, [ ] or ( ),
is a function head: its first element is the name and the rest are the
formals, in every shape lambda accepts. A symbol
is a value binding.
The name takes the first slot of the head, so its return type bundles
with it as a typed formal does, [(f :: int) x], never inline. An
inline [f :: int x] is rejected as a bare :: in the formals, and
[f type: 1 x] is a keyword formal named type defaulting to 1.
In block form the function head is followed by a colon and an indented body:
define [NAME FORMALS ...]:
BODY ...
Use-case: Scheme-style definitions. (define [f x] body) reads as
Scheme’s (define (f x) body); (define x v) is
(var x v).
Behaviour: A function head declares NAME in the current scope
and stores (function NAME FORMALS ... BODY ...) into it, as
(def NAME [FORMALS ...] BODY ...) does. The function needs at least
one body form. A recursive call to NAME inside the body reads the
binding in the enclosing scope.
A symbol in the name position behaves as var:
NAME is declared in the current scope, VALUE, when present, is
evaluated and stored, and without a value the slot is left empty, so
reading it before a store raises. The form’s value is None.
A pair in the name position whose first element is not a symbol, and
the pre-Scheme shorthand (define NAME [FORMALS ...] BODY ...), match
no rule and raise SyntaxMatchError; move the name inside the pair.
Pitfall: (define [a b] x) is not an unpacking. It defines a
function named a with one formal b whose body is x, and binds
nothing named b:
(define [a b] #(1 2))
(a "ignored") ;; (1, 2)
Unpack with var over a pattern, or with
define-values:
(var [a b] #(1 2))
(define-values [a b] #(1 2))
A decorator line above a function define decorates the function and
binds the result; see decorate.
Examples:
;; Declaration only; assign later with set!
(define x)
(set! x 42)
;; Typed declaration and value
(define port :: int)
(define host type: str "localhost")
;; Declare and store
(define y 99)
;; Function, with ( ) or [ ] around the head
(define (square x) (* x x))
(define [double x] (* x 2))
(define [fact n]
(cond [(== n 0) 1]
[else: (* n (fact (- n 1)))]))
;; Typed function
(define [(half :: float) x] (/ x 2))
In block form, with a decorator:
define [twice f]:
(lambda [x] (* 2 (f x)))
@twice
define [inc x]:
(+ x 1)
(inc 4) ;; 10
See also: compile/define-global, compile/var, def, compile/function, compile/define-values.