Previous: Memoization, Up: Higher Ordered Fun


23.9.2 Conventional Calling

To make use of idiomatic calling-convention macros, evaluate the form:

     (use-modules (ice-9 calling))
— Scheme Macro: save-bindings-excursion vars [body...]

Expand to a form that saves the values for each binding named in vars, a list of unevaluated symbols naming bindings in the save-bindings-excursion caller, evaluates the body forms, then restores the values. These operations form the three branches of a dynamic-wind. Here is an example:

          (define a 42)
          (define c 99)
          (define (chk!) (write-line (list #:a a #:c c)))
          
          (save-bindings-excursion (a c)
            (chk!)
            (set! a 0)
            (set! c -1)
            (chk!))
— Scheme Macro: with-excursion-function vars collect

Expand to an application of collect to an excursion proc ex. ex takes one argument, a thunk, which forms the middle branch of a dynamic-wind. In the first branch, ex saves the values of vars, a list of unevaluated symbols naming bindings in the with-excursion-function caller. In the third branch, ex restores these values. Here is an example that shows how to use this macro:

          (with-excursion-function
            (a c) (lambda (ex)
                    (ex (lambda ()
                          (chk!)
                          (set! a 0)
                          (set! c -1)
                          (chk!)))))

In this example, collect is an anonymous procedure, and the excursion proc is named ex. Note that this is functionally equivalent to the one for save-bindings-excursion (with setup definitions elided).

— Scheme Macro: with-getter-and-setter vars collect

Expand to an application of collect to getter and setter procs for vars, an unevaluated list of symbols naming bindings in the caller of with-getter-and-setter. The call looks like:

          (collect getter setter)

getter and setter are procedures used to access or modify vars. setter, called with keywords arguments, modifies the named values. For example, if foo and bar are among vars, then:

          (setter #:foo 1 #:bar 2)
          ===
          (begin (set! foo 1) (set! bar 2))

getter, called with just keywords, returns a list of the corresponding values. To continue the above example:

          (getter #:foo #:bar)
          ⇒ (1 2)

getter, called with no arguments, returns a list of all accepted keywords and the corresponding values. To continue the above example, with the additional stipulation that foo and bar are the only names in vars:

          (getter)
          ⇒ (#:foo 1 #:bar 2)

These calling sequences supports two handy idioms:

          (apply setter (getter))              ;; save and restore
          
          (apply-to-args (getter #:foo #:bar)  ;; fetch and bind
            (lambda (foo bar) ....))
— Scheme Macro: with-getter vars collect

Like with-getter-and-setter but collect only getter.

— Scheme Macro: with-delegating-getter-and-setter vars sub-g sub-s collect

Expand to an application of collect to getter and setter procs for vars, an unevaluated list of symbols naming bindings in the caller of with-delegating-getter-and-setter. The call looks like:

          (collect getter setter)

If given a name not in vars, getter and setter call sub-g and sub-s, respectively.

— Scheme Macro: with-excursion-getter-and-setter vars collect

Expand to an application of collect to excursion proc ex, getter and setter procs for vars, an unevaluated list of symbols naming bindings in the caller of with-excursion-getter-and-setter. The call looks like:

          (collect excursion getter setter)

See with-excursion-function and with-getter-and-setter.

— Scheme Macro: with-configuration-getter-and-setter vars-etc collect

Expand to an application of collect to getter and setter procs for vars-etc, a list of binding specifiers for bindings visible in the caller of with-configuration-getter-and-setter. The call looks like:

          (collect getter setter)

getter and setter can trigger arbitrary computation, according to the binding specifier, which has the form:

          (name [getter-hook [setter-hook]])

Both hook elements are evaluated; name is not. Either hook may be #f or a procedure.

getter-hook is a thunk that returns a value for the corresponding name. If omitted (or #f is passed), use the normal value of name.

setter-hook is a procedure of one argument that accepts a new value for name. If omitted, name is simply updated with set!.

— Scheme Macro: with-delegating-configuration-getter-and-setter vars-etc sub-g sub-s collect

Like with-delegating-getter-and-setter but using vars-etc as with with-configuration-getter-and-setter.

— Scheme Macro: let-with-configuration-getter-and-setter vars-etc collect

Like with-configuration-getter-and-setter except that each element of vars-etc is:

          (name initial-value getter-hook setter-hook)

Also, this macro introduces an additional lexical binding for each of the names in vars-etc. It is short-hand for:

          (let ((<var1> initial-value-1)
                (<var2> initial-value-2)
                 ...)
           (with-configuration-getter-and-setter
              ((<var1> v1-get v1-set)
               (<var2> v2-get v2-set)
               ...)
             collect))