Previous: , Up: methods   [Contents][Index]


7.4 Calling object-type methods

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).

Syntax: method-call ?name ?subject-expr ?arg

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.

Function: method-call-late-binding name td subject arg

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.

Dot notation

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: , Up: methods   [Contents][Index]