I imagine a type-definition construct that allows programmers to specify how 
the type is translated into a contract. Think (define-trusted-type Finalizer C) 
and then the C specifies how little and how much of the type you wish to check. 

And yes, this is potentially a soundness hole but I am thinking that the 
primary uses could be connected to things in the core or the FFI. And 
programmers who wish to reduce the soundness of TR could use it to speed up 
boundary crossings at the cost of getting things wrong. In a sense, it's an FFI 
for types. 

-- Matthias







On Aug 17, 2014, at 3:47 PM, Sam Tobin-Hochstadt wrote:

> Can you say more about what the API for what you're imagining is?
> 
> Sam
> 
> On Sun, Aug 17, 2014 at 3:41 PM, Matthias Felleisen
> <matth...@ccs.neu.edu> wrote:
>> 
>> I am imagining that the type compilation of type Finalizer and such things 
>> would be parameterized over programmer code which would yield a 'trusted' 
>> 'thing' in this case except that this would open the door for other such 
>> things.
>> 
>> 
>> 
>> 
>> On Aug 17, 2014, at 3:39 PM, Sam Tobin-Hochstadt wrote:
>> 
>>> How would that change things here? The issue is about
>>> finalizer-for-what, and that chaperones/impersonators affect object
>>> identity.
>>> 
>>> Sam
>>> 
>>> On Sun, Aug 17, 2014 at 3:37 PM, Matthias Felleisen
>>> <matth...@ccs.neu.edu> wrote:
>>>> 
>>>> Could we benefit from an abstract/opaque Finalizer type here? I know we 
>>>> don't have those yet but it may address the general problem. -- Matthias
>>>> 
>>>> 
>>>> 
>>>> 
>>>> On Aug 16, 2014, at 8:55 AM, Neil Toronto wrote:
>>>> 
>>>>> Short version: the contract system doesn't allow `register-finalizer` to 
>>>>> be used in Typed Racket.
>>>>> 
>>>>> Long version: consider the following Typed Racket program, in which 
>>>>> instances of `os-resource-wrapper` represent an operating system resource 
>>>>> `os-resource`, which itself is just a counter. It attempts to register a 
>>>>> finalizer for allocated wrappers, which decrements the counter.
>>>>> 
>>>>> 
>>>>> #lang typed/racket
>>>>> 
>>>>> (require/typed
>>>>> ffi/unsafe
>>>>> [register-finalizer  (All (A) (-> A (-> A Any) Void))])
>>>>> 
>>>>> (: os-resource Integer)
>>>>> (define os-resource 0)
>>>>> 
>>>>> (struct os-resource-wrapper ())
>>>>> 
>>>>> (: alloc-os-resource (-> os-resource-wrapper))
>>>>> (define (alloc-os-resource)
>>>>> (set! os-resource (add1 os-resource))
>>>>> (define w (os-resource-wrapper))
>>>>> (register-finalizer w (λ (w) (set! os-resource (sub1 os-resource))))
>>>>> w)
>>>>> 
>>>>> (define w (alloc-os-resource))
>>>>> (printf "os-resource = ~v~n" os-resource)
>>>>> (collect-garbage)
>>>>> (sleep 1)  ; give finalizers a chance to run
>>>>> (printf "os-resource = ~v~n" os-resource)
>>>>> 
>>>>> 
>>>>> I get this output:
>>>>> 
>>>>> os-resource = 1
>>>>> os-resource = 0
>>>>> 
>>>>> The finalizer is being run while the program still has a pointer to the 
>>>>> wrapper object. I think it's because the wrapper object is being 
>>>>> impersonated when it's sent across the contract barrier, and the 
>>>>> *impersonator* is getting the finalizer. (Or it's a chaperone, or an 
>>>>> impostor, or a charlatan, or whatever. Let's go with impersonator.)
>>>>> 
>>>>> In my specific case, the OS resources are OpenGL objects; e.g. vertex 
>>>>> object arrays. The call to `register-finalizer` *must* be in Typed Racket 
>>>>> code because the wrapper contains an (Instance GL-Context<%>), which 
>>>>> can't have a contract put on it, so it can't pass from untyped to typed 
>>>>> code.
>>>>> 
>>>>> Is there any reason for `register-finalizer` to behave this way? Does it 
>>>>> ever make sense to register a finalizer on an impersonator?
>>>>> 
>>>>> Neil ⊥
>>>>> _________________________
>>>>> Racket Developers list:
>>>>> http://lists.racket-lang.org/dev
>>>> 
>>>> 
>>>> _________________________
>>>> Racket Developers list:
>>>> http://lists.racket-lang.org/dev
>> 


_________________________
  Racket Developers list:
  http://lists.racket-lang.org/dev

Reply via email to