Next: , Previous: , Up: iklib expander   [Index]


6.14.8 expand–time values

It is sometimes useful to precompute a value at expand–time and push it on the lexical environment to be later retrieved. Here is an example of simple expand–time value computation, retrieval and insertion in which the value is a self–evaluating fixnum:

(import (vicare))

(define-syntax obj1
  (make-expand-time-value (+ 1 2 3)))

(define-syntax get-obj1
  (lambda (stx)
    (retrieve-expand-time-value #'obj1)))

(get-obj1) → 6

here is an example of simple expand–time value computation, retrieval and insertion in which the value is a non–self–evaluating vector:

(import (vicare))

(define-syntax obj2
  (make-expand-time-value (vector 1 2 3)))

(define-syntax get-obj2
  (lambda (stx)
    #`(quote #,(retrieve-expand-time-value #'obj2))))

(get-obj2) → (quote #(1 2 3))

we see that to produce an expand–time value we define a syntax keyword bound to the result of make-expand-time-value.

Function: make-expand-time-value obj

Build and return a “special” object that is recognised by the expander as holding obj as a precomputed expand–time object.

Function: expand-time-value? obj

Return #t if obj is a “special” object that is recognised by the expander as holding a precomputed expand–time object.

Function: expand-time-value-object etv

Given a “special” object that is recognised by the expander as holding a precomputed expand–time object: return the actual value.

Function: retrieve-expand-time-value id

Given a syntactic identifier return its associated expand–time value; if id is not associated to a expand–time value: return #f.

What expand–time values are not for

We have to understand that the real use of expand–time values is not actually to precompute values and put them in compiled code; for this we can just use define-inline-constant, which in the end defines a “normal” syntax transformer as the following:

(import (vicare))

(define-syntax obj1
  (let ((const (vector 1 2 3)))
    (lambda (stx)
      (syntax-case stx ()
        (?id
         (identifier? #'?id)
         #`(quote #,const))))))

obj1    → (quote #(1 2 3))

What expand–time values are for

Let’s say we define a record type in a library (it must go in a library so that we can import it and use it at expand–time in the body of transformers):

(library (etv-demo)
  (export that make-that
          that-a that-b that-c)
  (import (vicare))
  (define-record-type that
    (fields a b c)))

now we can instantiate a struct that and push the instance on the lexical environment, bound to the identifier it:

(import (vicare)
  (for (etv-demo) expand))

(define-syntax it
  (make-expand-time-value
    (make-that 1 2 3)))

later we retrieve the struct instance, through the identifier it, and use its fields to produce the output of a syntax use:

(define-syntax get-it
  (lambda (stx)
    (let ((S (retrieve-expand-time-value #'it)))
      (with-syntax
          ((A (that-a S))
           (B (that-b S))
           (C (that-c S)))
        #'(quote #(A B C))))))

(get-it)        → (quote #(1 2 3))

Next: , Previous: , Up: iklib expander   [Index]