Is there a technical reason why code for phase 1 is in plain Racket, even when phase 0 can be in typed Racket?
Here is a Typed Racket snippet that is used in phase 1:
;; print-id.rkt
#lang typed/racket/optional
(provide print/id-proc)
(require (for-template racket/base))
(: print/id-proc (-> Syntax (Syntaxof Any)))
(define (print/id-proc stx)
(define d (syntax-e stx))
(cond
[(and (pair? d) (pair? (cdr d)) (identifier? (cadr d)))
(with-syntax ([id (cadr d)])
#'(printf '"print/id-proc: value of ~s is ~s\n" 'id id))]
[else #'(begin)]))
And its client:
#lang racket/base
(require (for-syntax racket/base "print-id.rkt"))
(define-syntax print/id print/id-proc)
(define x 123)
(print/id x)
The types of print/id-proc are indeed statically checked, although typing it isn't very convenient. Of course, its interaction with the untyped code is not guarded. Is this related to what you are asking?