[racket-dev] Typed Racket and importing polymorphic code

From: Shriram Krishnamurthi (sk at cs.brown.edu)
Date: Mon Aug 2 11:14:24 EDT 2010

This is related to the other thread, on eq?.  I'll follow-up here.

>> That's beside the point.  map has just as much a polymorphic type as
>> insert.  You said earlier, "it shouldn't work to use `insert' in an
>> untyped context, since there's no way to generate a contract for its
>> type".  Why does this statement not apply to map?
>
> No contract is needed for `map' at all - it (like all Racket
> primitives) is known to protect itself.

I think this is a bad explanation.  What you said in your other thread
makes more sense -- TR passes through things and assumes that they
protect themselves:

  Other modules protect their own code.

The fact that map is a primitive does not strike me as relevant here.

Okay, so here's another scenario.  This time, TR will NOT just pass
the value through, as it did map.

---------------------------------------------------------------- a.rkt
#lang racket

(define foo 4)
(provide foo)
;; NOTE: a has not done a good job of "protecting" foo,
;; whatever the heck that means
---------------------------------------------------------------- b.rkt
#lang typed/racket

(require/typed "a.rkt" [foo Number])
(provide foo)
;; Now I'm going to put an explicit TYPE on foo
---------------------------------------------------------------- c.rkt
#lang racket

(require "b.rkt")
(string-length foo)
----------------------------------------------------------------------

The error message is

  string-length: expects argument of type <string>; given 4

Nothing that looks like a contract violation.

I was willing to live with your previous explanation re. map (whether
or not it was primitive, the idea that something just passed through).
But the idea that the typed intermediation above seems to do nothing
is much harder to defend on similar grounds.

In fact, let's go a step farther, since apparently what matters is
whether something is defined in the module.  Here is an alternate
version of b.rkt:

---------------------------------------------------------------- b.rkt
#lang typed/racket

#lang typed/racket

(require/typed "a.rkt" [foo Number])
(: my-foo Number)
(define my-foo foo)
(provide my-foo)
---------------------------------------------------------------- c.rkt
#lang racket

(require "b.rkt")
(string-length my-foo)
----------------------------------------------------------------------

and I get the same run-time error.

Shriram


Posted on the dev mailing list.