[racket] Creation of lambda version with syntaxes.

From: Danny Yoo (dyoo at cs.wpi.edu)
Date: Sun Apr 8 14:59:29 EDT 2012

> I am currently working on creating my own language in racket. Therefore I would like to change the standard lambda implementation to a version in which a certain method call is interleaved between every 2 execution lines of the body.


The macro system in Racket allows us to express a compile-time
computation.  In particular, during compilation, Racket walks through
our programs and applies "macro expansion" to transform our programs
down to simple core forms.

To interleave a particular statement between pairs of body elements,
we might imagine that the macro takes the body of a function:

       b_1 b_2 ... b_n

and does some funny injection between each b_i.  Here's what this
might look like:
       b_1 (printf "hi\n") b_2 (printf "hi\n") ... b_n)


;; interleaving.rkt ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket

(require (for-syntax racket/list))

(define-syntax (define/interleaved stx)
  (syntax-case stx ()
    [(_ (fun-name ids ...) body ...)
     (begin
       (define body-element-syntaxes (syntax->list #'(body ...)))
       (define interleaved-body-element-syntaxes
         (add-between body-element-syntaxes #'(printf "hi\n")))

       #`(define (fun-name ids ...)
           #, at interleaved-body-element-syntaxes))]))

;; Example:
(define/interleaved (f x)
    (printf "this is a test\n")
    (* x x))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

When we compile this program, Racket sees the use of
"(define/interleaved ...)".  It then uses the macro associated to that
name to transform the source program, at compile-time.

define/interleaved is a function that takes the literal text of the
program and destructures it and restructures it to a new, simpler
program.  In the example above, the new program is in the form of a
syntax object:

     #`(define (fun-name ids ...)
           #, at interleaved-body-element-syntaxes))

It uses portions of the old syntax tree, like the original function's
name and argument list.  But it also carries along an amended list of
body elements that we computed at compile-time.


Posted on the users mailing list.