Previous: , Up: iklib syntaxes lambdas   [Index]


6.8.2.2 Validating lambda syntaxes

The syntaxes lambda* and case-lambda* are similar to lambda and case-lambda as defined by R6RS, but they allow the specification of logic predicates to validate the arguments and the return values; a logic predicate is a composition of predicate expressions. Examples:

#!vicare
(import (vicare)
  (vicare system $fx))

(define add
  ;;Fail if called with a non-fixnum argument.
  (lambda* ({a fixnum?} {b fixnum?})
    ($fx+ a b)))

(define vec
  ;;Fail if attempting to return a non-vector.
  (lambda* ({_ vector?} fun)
    (fun 1 2)))

(add 1 2)       ⇒ 3
(add 1 #\2)     error→ &procedure-argument-violation

(vec vector)    ⇒ #(1 2)
(vec list)      error→ &expression-return-value-violation

in the definition of the function bound to vec: notice that {_ vector?} is not a function argument, it is a special notation used to select a predicate to validate the return value.

In the extended lambda* and case-lambda* syntaxes the ?pred-formals can have any of the forms:

(?var ...)
(?var0 ?var ... . ?rest)
?args

Where in the standard lambda and case-lambda syntaxes an identifier is used to name a formal argument, in the extended lambda* and case-lambda* syntaxes each formal argument ?var can have any of the forms:

?id
(brace ?id ?logic-pred)

where: brace is the identifier exported by (vicare); ?id is an identifier naming the formal argument. ?logic-pred must have one of the following recursive formats:

?logic-pred = ?pred-id
            | (and ?logic-pred0 ?logic-pred ...)
            | (or  ?logic-pred0 ?logic-pred ...)
            | (xor ?logic-pred0 ?logic-pred ...)
            | (not ?logic-pred)

where: ?pred-id is an identifier expanding and evaluating to a predicate function accepting a single argument and returning true or #f; and, or, xor, not are the identifiers exported by (vicare).

The formal argument ?rest can have only one of the following forms:

?rest-id
(brace ?rest-id ?logic-pred)

and the formal argument ?args can have one of the following forms:

?args-id
(brace ?args-id ?logic-pred)

the ?logic-pred for ?rest and ?args is applied to each item in the proper list bound to ?rest-id and ?args-id.

The first item in the ?pred-formals can have the special syntax:

(brace _ ?logic-pred0 ?logic-pred ...)

where _ is the binding exported by (rnrs base (6)); in this case such item does not represent a formal argument, it just selects predicates to validate the values returned by the last ?body form.

Syntax: lambda* ?pred-formals ?body0 ?body …
Syntax: named-lambda* ?who ?pred-formals ?body0 ?body …

Like the standard lambda and additionally allow the specification of predicate functions to validate the arguments and the return value. The formal arguments are handled according to the following rules:

When using lambda*, in addition the behaviour of lambda, the fluid identifier syntax __who__ is bound to the quoted symbol _; the named-lambda* variant allows to specify an identifier ?who to be used as value for the __who__ fluid syntax.

Usage examples:

Syntax: case-lambda* ?pred-cl-clause …
Syntax: named-case-lambda* ?who ?pred-cl-clause …

Like the standard case-lambda and additionally allow the specification of logic predicates to validate the arguments and the return values. Clause by clause the formals are handled as explained for lambda*.

When using case-lambda*, in addition to the behaviour of lambda, the fluid identifier syntax __who__ is bound to the quoted symbol _; the named-case-lamba* variant allows to specify an identifier ?who to be used as value for the __who__ fluid syntax.

Usage examples:

#!vicare
(import (vicare))

(define f
  (case-lambda*
   (({a number?})
    (number->string a))))

(define g
  (case-lambda*
   ({args list?}
    (length args))))

(f 123)                 ⇒ "123"
(g 1 2 3)               ⇒ 3

Previous: , Up: iklib syntaxes lambdas   [Index]