Extended Formal Arguments List

The formal arguments list of a lambda expression has two extendsions over standard Scheme: Kawa borrows the extended formal argument list of DSSSL, and Kawa allows you to declare the type of the parameter.

lambda-expression ::= (lambda formals opt-return-type body)
return-type ::= type
opt-return-type ::= [[::type]


formals ::= (formal-arguments) | rest-arg

You can of course also use the extended format in a define:

(define (name formal-arguments) [rtype] body)

formal-arguments ::=
    req-opt-args (rest-key-args | . rest-arg)

req-opt-args ::= req-arg ... [#!optional opt-arg ...]
rest-key-args ::= [#!rest rest-arg] [#!key key-arg ...]
req-arg ::=  variable [:: type] | (variable [[::type)
opt-arg ::= arg-with-default
key-arg ::= arg-with-default
arg-with-default ::= variable [:: type]
    | ( variable [:: type [initializer] | initializer [[::type]] )
rest-arg ::= variable

When the procedure is applied to a list of actual arguments, the formal and actual arguments are processed from left to right as follows:

If a type is specified, the corresponding actual argument (or the initializer default value) is coerced to the specified type. In the function body, the parameter has the specified type.

If rtype (the first form of the function body) is an unbound identifier of the form <TYPE> (that is the first character is ‘<’ and the last is ‘>’), then that specifies the function’s return type. It is syntactic sugar for (as <TYPE> (begin BODY)).

Syntax: cut slot-or-expr slot-or-expr* [<...>]

where each slot-or-expr is either an expression or the literal symbol <>.

It is frequently necessary to specialize some of the parameters of a multi-parameter procedure. For example, from the binary operation cons one might want to obtain the unary operation (lambda (x) (cons 1 x)). This specialization of parameters is also known as partial application, operator section, or projection. The macro cut specializes some of the parameters of its first argument. The parameters that are to show up as formal variables of the result are indicated by the symbol <>, pronouced as "slot". In addition, the symbol <...>, pronounced as "rest-slot", matches all residual arguments of a variable argument procedure.

A cut-expression is transformed into a lambda expression with as many formal variables as there are slots in the list slot-or-expr*. The body of the resulting lambda expression calls the first slot-or-expr with arguments from the slot-or-expr* list in the order they appear. In case there is a rest-slot symbol, the resulting procedure is also of variable arity, and the body calls the first slot-or-expr with remaining arguments provided to the actual call of the specialized procedure.

Here are some examples:

(cut cons (+ a 1) <>) is the same as (lambda (x2) (cons (+ a 1) x2))

(cut list 1 <> 3 <> 5) is the same as (lambda (x2 x4) (list 1 x2 3 x4 5))

(cut list) is the same as (lambda () (list))

(cut list 1 <> 3 <...>) is the same as (lambda (x2 . xs) (apply list 1 x2 3 xs))

The first argument can also be a slot, as one should expect in Scheme: (cut <> a b) is the same as (lambda (f) (f a b))

Syntax: cute slot-or-expr slot-or-expr* [<...>]

The macro cute (a mnemonic for "cut with evaluated non-slots") is similar to cut, but it evaluates the non-slot expressions at the time the procedure is specialized, not at the time the specialized procedure is called.

For example (cute cons (+ a 1) <>) is the same as (let ((a1 (+ a 1))) (lambda (x2) (cons a1 x2)))

As you see from comparing this example with the first example above, the cute-variant will evaluate (+ a 1) once, while the cut-variant will evaluate it during every invocation of the resulting procedure.