[racket] making libraries work natively with both Racket & Typed Racket

From: Matthew Butterick (mb at mbtype.com)
Date: Sat Mar 21 14:09:04 EDT 2015

Is there an approved way of using #lang typed/racket/base/no-check (or maybe `with-type`) to create libraries that have both a typed and untyped interface? (The goal being to avoid use of `require/typed`)

For instance, the following works, but maybe it's a bad idea for other reasons:

;;;;;;;;;;;;;;;;;;;

;; adder.rkt = write typed code, but leave off #lang line & `provide`

(: fladd (Flonum Flonum . -> . Flonum))
(define (fladd f1 f2)
  (+ f1 f2))
;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;

;; typed.rkt = compile in typed context

#lang typed/racket/base
(require racket/include)
(provide fladd)
(include "adder.rkt")
;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;

;; untyped.rkt = compile in untyped context with contract

#lang typed/racket/base/no-check
(require racket/include racket/contract racket/math)
(provide (contract-out [fladd (flonum? flonum? . -> . flonum?)]))
(include "adder.rkt")
;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;

;; test.rkt

#lang racket/base

(module typed typed/racket/base
  (require "typed.rkt")
  (require typed/rackunit)
  (check-equal? (fladd 1.0 2.0) 3.0)) ; typechecks correctly

(module untyped racket/base
  (require "untyped.rkt")
  (require rackunit)
  (check-equal? (fladd 1.0 2.0) 3.0) ; meets `provide` contract
  (check-exn exn:fail:contract? (λ () (fladd 1 2)))) ; violates `provide` contract

(module violator racket/base
  (require "typed.rkt")
  (require rackunit)
  (check-exn exn:fail:contract? (λ () (fladd 1 2)))) ; violates typed/untyped contract barrier

(require 'typed)
(require 'untyped)
(require 'violator)
;;;;;;;;;;;;;;;;;;;



Posted on the users mailing list.