apply proc [arg1 ...] args | Function |
Args must be a sequence (list, vector, or string) or a primitive Java array. (This is an extension over standard Scheme, which requires that args be a list.) Calls the proc (which must be a procedure), using as arguments the arg1... values plus all the elements of args. |
constant-fold proc arg1 ... | Syntax |
Same as ( proc arg1 ...) , unless proc and
all the following arguments are compile-time constants.
(That is: They are either constant, or symbols that have a global
binding and no lexical binding.) In that case, proc
is applied to the arguments at compile-time, and the result replaces
the constant-fold form. If the application raises an exception,
a compile-time error is reported.
For example:
(constant-fold vector 'a 'b 'c)is equivalent to (quote #(a b c)) , assuming vector
has not been re-bound.
|
You can associate arbitrary properties with any procedure. Each property is a (key, value)-pair. Usually the key is a symbol, but it can be any object.
The system uses certain internal properties:
'name
refers to the name used when a procedure is printed;
'emacs-interactive
is used to implement Emacs interactive
specification;
'setter
is used to associate a setter
prcedure.
procedure-property proc key [default] | Function |
Get the property value corresponding to the given key.
If proc has no property with the given key,
return default (which defaults to #f ) instead.
|
set-procedure-property! proc key value | Function |
Associate the given value with the key property of proc. |
To change the print name of the standard +
procedure (probably
not a good idea!), you could do:
(set-procedure-property! + 'name 'PLUS)Note this only changes the name property used for printing:
+ => #<procedure PLUS> (+ 2 3) => 5 (PLUS 3 4) => ERROR
As a matter of style, it is cleaner to use the define-procedure
form, as it is a more declarative interface.
define-procedure name [propname: propvalue] ... method ... | Syntax |
Defines name as a compound procedure consisting of the
specified methods, with the associated properties.
Applying name select the "best" method, and applies that.
(However, the current implementation of selecting the "best" method
is not reliable if there is more than one method )
For example, the standard (define-procedure vector-ref setter: vector-set! (lambda ((vector :: <vector>) (k :: <int>)) (invoke vector 'get k))) |
A generic procedure is a collection of method procedures. (A "method procedure" is not the same as a Java method, but the terms are related.) You can call a generic procedure, which selects the "closest match" among the component method procedures: I.e. the most specific method procedure that is applicable give the actual arguments.
make-procedure [keyword: value]... method... | Function |
Create a generic procedure given the specific methods.
You can also specify property values for the result.
The keywords specify how the arguments are used.
A (define plus10 (make-procedure foo: 33 name: 'Plus10 method: (lambda (x y) (+ x y 10)) method: (lambda () 10))) |
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 [rtype] body)where
formals ::= (formal-arguments) | rest-argYou 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:
#f
. The initializer is evaluated in an
environment in which all the previous formal parameters have been bound.
#!key
was specified, then there shall be an even number of
remaining actual arguments. These are interpreted as a series of pairs,
where the first member of each pair is a keyword specifying the argument name,
and the second is the corresponding value. It shall be an error if the first
member of a pair is not a keyword. It shall be an error if the argument name
is not the same as a variable in a key-args, unless there
is a rest-arg. If the same argument name occurs more than once
in the list of actual arguments, then the first value is used.
If there is no actual argument for a particular key-arg,
then the variable is bound
to the corresponding initializer, if one was specified, and
otherwise to #f
. The initializer is evaluated in an
environment in which all the previous formal parameters have been bound.
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 tha specifies the
functions return type. It is syntactic sugar for
(as <TYPE> (begin BODY))
.
cut slot-or-expr slot-or-expr* [<...> ]
|
Syntax |
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 A Here are some examples: The first argument can also be a slot, as one should expect in Scheme: |
cute slot-or-expr slot-or-expr* [<...> ]
|
Syntax |
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: As you see from comparing this example with the first example above, the
|