[racket] Defining a typed language

From: Konrad Hinsen (konrad.hinsen at fastmail.net)
Date: Fri Oct 17 06:38:10 EDT 2014

Sam Tobin-Hochstadt writes:

 > My suggestion is to have your `test-lang` language use
 > `#%module-begin` to expand into `(tr:module-begin (require
 > test-lang/more) user-program-here ...)`, which should fix the problem.

Thanks, that sounds like a good idea... but it doesn't work either. Here's
my new test-lang/main.rkt:

-- test-lang/main.rkt ----------------------------
#lang typed-racket/minimal

(require typed/racket
         (only-in typed/racket
                  [#%module-begin tr:module-begin]
                  [require tr:require]))

(provide (except-out (all-from-out typed/racket) #%module-begin)
         (rename-out [module-begin #%module-begin]))

(define-syntax module-begin
  (syntax-rules ()
    [(_ decl ...)
      (tr:require test-lang/more)
      decl ...)]))

When I run my test program again:

-- test.rkt --------------------------------------
#lang test-lang

(: x Integer)
(define x 42)
(print x)

(print (bar x))

I get the error message

  ; /Users/hinsen/projects/racket/test.rkt:9:8: bar: unbound identifier in module
  ;   in: bar

When I remove the require from begin-module and put it right into test.rkt,
it works just fine.

I ran both versions through the macro stepper to see where the
difference comes from. There is a difference right from the start,
before any macro expansion is done: In the working version (with the
require in test.rkt), the binding for 'bar' is shown as

   Apparent identifier binding
   in phase 0:
     defined in: test-lang/more
       as: bar.4
     imported from: test-lang/more

where as in the buggy version (with the require in test-lang/main.rkt) it is

   Apparent identifier binding

This looks like some magic happens even before the first macro
expansion - I need a magician to figure that out!  ;-)


Posted on the users mailing list.