Previous: methods sealing, Up: methods [Contents][Index]
The following keyword syntactic bindings are involved in the definition
and use of methods: method
, virtual-method
,
seal-method
, method-call
. In addition the function
method-call-late-binding
performs a method call with “late
binding” (run–time dispatching).
The keyword method
is used in define-record-type
to
define methods for a record–type (see (vicare-scheme)Record–type methods). For example:
(define-record-type duo (fields one two) (method (sum-them) (+ (duo-one this) (duo-two this))) (method (mul-them) (* (duo-one this) (duo-two this))))
the syntax method-call
is then used to call a record’s methods:
(define {O duo} (new duo 3 5)) (method-call sum-them O) ⇒ 8 (method-call mul-them O) ⇒ 15
When defining a record or struct: Vicare automatically adds a method to the methods table, for each field, with the same name of the field. When the field is mutable: if the method is called with one argument, it behaves as a field accessor; if the method is called with two arguments, it behaves as a field mutator. When the field is immutable: the method can be called with one argument only. Example:
(define-record-type duo (fields (immutable one) (mutable two))) (define {O duo} (new duo 1 2)) (method-call one O) ⇒ 1 (method-call one O 123) error→ &syntax (method-call two O) ⇒ 2 (method-call two O 9) (method-call two O) ⇒ 9
The following syntactic bindings are exported by the library
(vicare)
.
Apply an object–type’s method to the return value of ?subject-expr and the optional arguments ?arg.
?name must be a symbol representing a method or field name. ?subject-expr must be a Scheme expression which, expanded and evaluated at run–time, returns a single value. Each ?arg must be a Scheme expression which, expanded and evaluated at run–time, returns a single value.
When possible, method-call
determines at expand–time the type
of the expression ?subject-expr and searches for a method with
equal name, according to eq?
. If the method is found, the
syntactic identifier to which the implementation procedure is bound is
inserted in the macro expansion:
(?procedure ?subject-expr ?arg ...)
If the object–type of ?subject-expr has no matching method: its super–type is inspected, then the super–type of the super–type and so on. If no method is found in the types hierarchy: an exception is raised.
method-call
is able to retrieve the type of its second argument
at expand–time only when the typed language is enabled. If
method-call
cannot determine the type of ?subject-expr at
expand–time, the macro use is expanded to:
(method-call-late-binding (quote ?name) #f ?subject-expr ?arg ...)
and the function method-call-late-binding
attempts to determine a
suitable method at run–time.
Apply an object–type’s method to subject and the optional arguments ?arg. Return the application results.
The argument name must be a symbol representing a method or field name. The argument subject must be a Scheme object implementing a set of methods. The optional ?arg arguments can be any value.
The argument td must be #f
or a predetermined type
descriptor for subject; this argument is usually #f
.
This function attempts to determine the type of subject at
run–time and searches the object–type’s table of methods, if any, for
a method whose name equals name according to eq?
. If a
method is found, its implementation procedure is retrieved and applied
to subject and the arg values.
If the object–type of subject has no matching method: its super–type is inspected, then the super–type of the super–type and so on. If no method is found in the type’s hierarchy: an exception is raised.
Usually we do not need to call this function explicitly; however, it is useful for debugging purposes.
When the Scheme reader’s textual input port is configured in
‘#!vicare’ mode: if a list starts with a symbol; the name of the
symbol is a string of length at least 2; the first character of
the string is a dot; the second character of the string is not
a dot, then a method-call
symbol is inserted and the symbol
stripped of the dot.
We can try it at the REPL:
vicare> '(.ciao) $1 = (method-call ciao)
Notice that R6RS forbids symbols starting with a dot, with the exception of the ellipsis; so this transformation does not influence the other reader operations.
We can use this notation to call an object–type’s methods as in the following program:
#!vicare (program (demo) (options typed-language) (import (vicare)) (define-record-type duo (fields one two) (method (sum-them) (+ (.one this) (.two this))) (method (mul-them) (* (.one this) (.two this))) (method (display port) (display this port))) (define {O duo} (new duo 3 4)) (pretty-print (.sum-them O) (current-error-port)) (pretty-print (.mul-them O) (current-error-port)) (.display O (current-error-port)) (newline (current-error-port)) #| end of program |# )
Previous: methods sealing, Up: methods [Contents][Index]