[racket-dev] Math library initial commit almost ready; comments on issues welcome

From: Neil Toronto (neil.toronto at gmail.com)
Date: Mon Oct 1 21:44:26 EDT 2012

On 10/01/2012 06:29 PM, Sam Tobin-Hochstadt wrote:
> On Mon, Oct 1, 2012 at 6:49 PM, Neil Toronto <neil.toronto at gmail.com> wrote:
>> #lang typed/racket
>> (: plus (Flonum Flonum -> Flonum))
>> (define (plus a b)
>>    (+ a b))
>> (module provider racket
>>    (require (submod ".."))
>>    (provide inline-plus)
>>    (define-syntax-rule (inline-plus a b) (plus a b)))
>> (require 'provider)
>> (inline-plus 1.2 2.3)
> This program doesn't make sense -- the outer module depends on
> 'provider (see the `(require 'provider)`) but 'provider depends on the
> outer module (that's what the inner `require` is doing).  That's a
> cycle, and not allowed, typed or untyped.

You're right, that's wrong. Well, wrong-ish. Modules try to give the 
illusion of being evaluated top-to-bottom, but that apparently can't 
hold here.

FWIW, here's something that does work, and does what I want:

#lang racket/base

;; Struct definition
(module typed-struct typed/racket/base
   (struct: flonum-wrapper ([value : Flonum]) #:transparent)
   (provide (struct-out flonum-wrapper)))

;; Macros
(module untyped-syntax racket/base
   (require racket/flonum
            (submod ".." typed-struct))

   (provide fw+)

   (define-syntax-rule (fw+ x-expr y-expr)
     (let ([x x-expr] [y y-expr])
       (cond [(not (flonum-wrapper? x))
              (raise-argument-error 'fw+ "flonum-wrapper" 0 x y)]
             [(not (flonum-wrapper? y))
              (raise-argument-error 'fw+ "flonum-wrapper" 1 x y)]
              (flonum-wrapper (fl+ (flonum-wrapper-value x)
                                   (flonum-wrapper-value y)))])))

;; Definitions that depend on macros
(module more-typed-struct typed/racket/base
   (require (submod ".." typed-struct)
            (submod ".." untyped-syntax))

   (provide fwdbl)

   (: fwdbl (flonum-wrapper -> flonum-wrapper))
   (define (fwdbl x)
     (fw+ x x)))

(require 'typed-struct

(provide (all-from-out
           (submod "." typed-struct)  ; `submod' is necessary?
           (submod "." untyped-syntax)
           (submod "." more-typed-struct)))

The only bit that bothers me is the (begin (not (flonum-wrapper? x)) 
...) stuff left lying around after TR's optimizer eliminates the 
branches in the expansions of `fw+'. IIRC, they cause futures to sync, 
but I'm going to believe that they won't always - or will be optimized 
away - just so I can have a decent solution to the typed macro problem.

Neil ⊥

Posted on the dev mailing list.