[racket-dev] Typed versions of untyped collections

From: Neil Toronto (neil.toronto at gmail.com)
Date: Mon Dec 17 18:10:49 EST 2012

On 12/17/2012 03:55 PM, Matthias Felleisen wrote:
>
> On Dec 17, 2012, at 5:43 PM, Neil Toronto wrote:
>
>> On 12/17/2012 02:44 PM, Matthias Felleisen wrote:
>>>
>>> My understanding is that
>>>
>>>   -- Neil created a single file P, I believe it is typed
>>>   -- he tells you to load plot/typed/ for the typed version
>>>   -- he tells you to load plot/ for the untyped version
>>>
>>> Somewhere in this arrangement a call in some untyped client to a
>>> function f from P will cross a line.
>>>
>>> If this is wrong, I'd like to know where it goes wrong.
>>
>> You're thinking of `math/array', which is written in Typed Racket. There *is* a big performance problem with arrays in untyped code, because arrays are basically higher-order functions. Getting elements from arrays that cross the contract barrier is expensive.
>
> Okay.
>
>
>> `plot' is written in untyped Racket. There's no performance problem with typed plots at all; in fact, using `plot/typed' from TR code ends up checking exactly the same contracts for the same plots. `plot/typed' is just another end-user that happens to re-export everything with types attached.
>
> I don't understand this last part at all. You have
>
> -- an untyped file M
> -- a typed file T that imports M and re-exports everything from there with types
>
> How can it possibly be the case that a client C imports T and does NOT pay for the contracts that T's types impose on the call chain?

That would only happen if client C is untyped. I wouldn't expect an 
untyped client to (require plot/typed), but I suppose it could happen.

So I suppose we have another, but rather unlikely, reason to have TR's 
`require' check for a `typed' submodule. Currently, if some macro wants 
to expand to (require plot) and a few plots, it actually should expand 
to (require plot/typed) and a few plots in case it's used in typed code. 
That results in a double layer of contract checks when used in untyped code.

If plots don't make much sense here, substitute your favorite untyped 
library that might end up with an additional typed interface.

Here's another reason: TR currently does magical things that user code 
can't do. I think one of the long-term goals of TR should be to turn 
such special cases into general cases. One of them is allowing TR 
programs to use (require racket/list) to import typed identifiers. We 
should be able to do that with anything that provides a typed interface.

Neil ⊥


Posted on the dev mailing list.