[racket] typed racket and interfaces

From: Alexander D. Knauth (alexander at knauth.org)
Date: Sun May 4 14:47:06 EDT 2014

>  * If we have users write types in interfaces, what happens when
>    untyped classes try to implement those interfaces?
Untyped interfaces can specify contracts for their methods, so could it use that?

>  * What do interface types look like? Do they list the types of methods
>    that should be in them?
Based on the interface form and the Class type constructor (in v6.0.1.6), I think that they should look something like this:
 (Interface interface-type-clause ...)
   interface-type-clause = [method-id method-type]
                         | #:implements interface-type
This is basically a simplification of the grammar for the Class type constructor, and it matches the grammar of the interface form even better than the new Class type constructor matches the grammar for the class form.  

And it would mean that a class that uses the interface would implement the methods given, with the types given, and would also implement the interfaces given by #:implements.  
So the type of this:
(require/typed “untyped.rkt” [foo<%> Foo<%>]
(class* object% (foo<%>)
  ...
  )
would have a type that includes #:implements Foo<%>, and if Foo<%> is (Interface #:implements Super-Interface<%> [m t]), then that would mean that it would include #:implements Super-Interface<%> and [m t].  The things in the Interface type could go right into the Class type.  
So this:
(Class stuff ... [m1 t1] ... #:implements (Interface [m2 t2] ... #:implements (Interface [m3 t3] ...)))
Would mean the same as this:
(Class stuff ... [m1 t1] ... #:implements (Interface [m2 t2] ... [m3 t3] ...))
Which would mean the same as this:
(Class stuff ... [m1 t1] ... [m2 t2] ... [m3 t3] ...)

By the way I also noticed that class* doesn’t seem to work in typed racket either.  

> Do you have a use case in mind for interface types?

Not really anymore.  
I was trying to make my own types for some of the things in racket/gui, but the new version has that already (in typed/racket/gui).  
By the way it seems like typed/racket/gui is treating interface types like class types anyway, and since #:implements can be used more than once, it seems like it’s expecting that interface types should be represented with class types.  

But still, what if I wanted to do something like this:
(class* object% (printable<%>)
    (super-new) (inspect #f)
    (: custom-print (Output-Port (U 0 1) -> Void))
    (define/public (custom-print out d)
      ...)
    (: custom-write (Output-Port -> Void))
    (define/public (custom-write out)
      ...)
    (: custom-display (Output-Port -> Void))
    (define/public (custom-display out)
      ...))

But that’s still a what if case.  

> We've thought about adding something like #:implements/inits or
> something like that for this use-case, but we haven't implemented
> anything yet. Does that sound like it would be useful to you?

Yes, it does sound useful.  

I made a class called frame-with-callback% that inherits everything from frame% but adds callback init arguments and overrides the on-subwindow-char and on-subwindow-event methods.  I can just rewrite all of the init arguments from frame%, but it would be nice to have something like #:implements/inits.  

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20140504/abc9521c/attachment.html>

Posted on the users mailing list.