[racket] typed racket: inconsistent interaction between typed and untyped code?

From: Carl Eastlund (cce at ccs.neu.edu)
Date: Fri Mar 4 18:14:50 EST 2011

Ah.  This looks like the bug I've seen reported elsewhere that causes
blame to be associated with the wrong module.  The actual problem
going on here appears to be that test-sim passes an "Any" to
toplevel-vals, but sim-structs expects toplevel-vals to receive a
toplevel.  The blamed module, sim, isn't involved at all.

Carl Eastlund

On Fri, Mar 4, 2011 at 6:06 PM, Matthias Felleisen <matthias at ccs.neu.edu> wrote:
> The interesting thing is that the contract blames the TYPED module,
> contrary to all the blame theorems. Time to fix them. Anyone?
> On Mar 4, 2011, at 5:22 PM, Carl Eastlund wrote:
>> Danny,
>> This is an issue with the type Any.  Typed Racket has to protect all
>> values passed from typed code to untyped code from all possible
>> type-unsound uses.  For many kinds of values, this means Typed Racket
>> has to close off pretty much all kinds of uses.  In your case, you
>> have a transparent struct.  If it were unwrapped, untyped code could
>> inspect it, extract a constructor for its struct type, create an
>> instance with field contents that violate your define-struct:
>> declaration, and pass it back into typed code.  You have to be very
>> careful with Any on boundaries, because it has to make a lot of things
>> completely opaque.
>> Sadly, off the top of my head, I don't have a quick workaround for
>> you.  Maybe Sam will have a better suggestion.
>> Carl Eastlund
>> On Fri, Mar 4, 2011 at 4:20 PM, Danny Yoo <dyoo at cs.wpi.edu> wrote:
>>> I'm hitting an error when trying to pass values between typed and
>>> untyped code.  I've shrunk the error to the following test code.
>>> Consider three files 'sim-structs', 'sim.rkt', and 'test-sim.rkt'.
>>> sim-structs and sim are written in Typed Racket, and test-sim is
>>> written in regular racket.
>>> ;; sim-structs.rkt
>>> #lang typed/racket/base
>>> (provide (all-defined-out))
>>> (define-struct: machine ([env : (Listof Any)]))  #:transparent)
>>> (define-struct: toplevel ([vals : (Vectorof Any)])  #:transparent)
>>> ;; sim.rkt
>>> #lang typed/racket/base
>>> (require "sim-structs.rkt")
>>> (provide new-machine)
>>> (: new-machine ( -> machine))
>>> (define (new-machine)
>>>  (make-machine (list (make-toplevel (vector 'foobar)))))
>>> ;; test-sim.rkt
>>> #lang racket
>>> (require "sim.rkt" "sim-structs.rkt")
>>> (toplevel-vals (first (machine-env (new-machine))))
>>> When I try to execute test-sim, it fails with the following error:
>>> tesla ~/work/js-sicp-5-5 $ /pro/plt/software/racket/5.1/std/bin/racket
>>> test-sim.rkt
>>> contract violation: expected <toplevel?>, given: #<Typed Value:
>>> #(struct:toplevel #(foobar))>
>>>  contract on toplevel-vals24 from
>>>    (file
>>>     /home/dyoo/work/js-sicp-5-5/sim-structs.rkt)
>>>  via
>>>    (file
>>>     /home/dyoo/work/js-sicp-5-5/test-sim.rkt)
>>>  blaming
>>>    (file /home/dyoo/work/js-sicp-5-5/sim.rkt)
>>>  contract: (-> toplevel? (vectorof Any))
>>>        at: /home/dyoo/work/js-sicp-5-5/sim-structs.rkt:11.16
>>>  === context ===
>>> /pro/plt/software/racket/5.1/std/collects/racket/contract/private/blame.rkt:58:0:
>>> raise-blame-error
>>> /home/dyoo/work/js-sicp-5-5/test-sim.rkt: [running body]
>>> It looks as though there's some special "Typed Value" wrapper there
>>> that shouldn't be visible from the untyped test-sim code.  Is there a
>>> workaround?

Posted on the users mailing list.