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]