Next: iklib expander parameters, Previous: iklib expander fluids, Up: iklib expander [Index]
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
.
Build and return a “special” object that is recognised by the expander as holding obj as a precomputed expand–time object.
Return #t
if obj is a “special” object that is recognised
by the expander as holding a precomputed expand–time object.
Given a “special” object that is recognised by the expander as holding a precomputed expand–time object: return the actual value.
Given a syntactic identifier return its associated expand–time value;
if id is not associated to a expand–time value: return #f
.
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))
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: iklib expander parameters, Previous: iklib expander fluids, Up: iklib expander [Index]