[racket] How to use abstract classes?

From: Alexander Kasiukov (kasiuka at sunysuffolk.edu)
Date: Wed Aug 24 18:44:06 EDT 2011

Awesome! Thank you very much! It does look more elegant than using 
method overrides.

On 8/24/2011 4:20 PM, Jon Rafkind wrote:
> Here is the code. I had to split the abstract methods from the 
> concrete methods in the interface. The trick with mixins is that they 
> can't be instantiated themselves, you have to apply them to some class 
> and then instantiate that class.
>
> #lang racket
>
> (provide
>   first-child-class%
>   second-child-class%)
>
> (define child-interface-partial
>   (interface ()
>              child-method
>              ))
>
> (define child-interface
>   (interface (child-interface-partial)
>              child-implementation-dependent-method))
>
> #;
> (define generic-parent-class%
>   (class* object% ()
>           (super-new)
>           (define/public (child-method this-time) (error 'child-method 
> "abstract method"))
>           (define/public (child-implementation-dependent-method 
> given-inputs-list)
>             (map
>               (lambda(this-item)
>                 (eprintf "Next list item is ~v" (child-method this-item)))
>               given-inputs-list))))
>
> (define generic-parent-class-mixin
>   (mixin (child-interface-partial)
>          (child-interface)
>
>          (define/public (child-implementation-dependent-method 
> given-inputs-list)
>             (map
>               (lambda(this-item)
>                 (eprintf "Next list item is ~v\n" (send this 
> child-method this-item)))
>               given-inputs-list))
>
>          (super-new)))
>
> (define first-child-class%
>   (generic-parent-class-mixin
>       (class* object% (child-interface-partial)
>               (super-new)
>               (define/public (child-method given-input)
>                 (string-append "First got  " given-input)))))
>
> (define second-child-class%
>   (generic-parent-class-mixin
>     (class* object% (child-interface-partial)
>             (super-new)
>             (define/public (child-method given-input)
>               (string-append "Second got  " given-input)))))
>
> (define x1 (new first-child-class%))
> (define x2 (new second-child-class%))
>
> (send x1 child-implementation-dependent-method '("a" "b" "c"))
> (send x2 child-implementation-dependent-method '("a" "b" "c"))
>
> Output:
> Next list item is "First got  a"
> Next list item is "First got  b"
> Next list item is "First got  c"
> '(#<void> #<void> #<void>)
> Next list item is "Second got  a"
> Next list item is "Second got  b"
> Next list item is "Second got  c"
> '(#<void> #<void> #<void>)
>
>
> On 08/24/2011 11:18 AM, Alexander Kasiukov wrote:
>> Dear Jon,
>>
>> Thank you very much for your help! I got what I needed to work with 
>> method overrides (following a suggestion of Robby Findler), but it 
>> does look like mixins may give a less redundant way to accomplish the 
>> same functionality. I am at a loss trying to understand how to make 
>> them work based on the Bakus-Naur description. (I am just starting to 
>> learn Racket and Lisp in general.) Could you show an example or 
>> suggest a place where I can look up one? I am trying to do something 
>> along the lines of
>>
>> #lang racket
>>
>> (provide
>>     first-child-class%
>>     second-child-class%)
>>
>> (define child-interface
>>     (interface ()
>>         child-implementation-dependent-method
>>         child-method))
>>
>> (define generic-parent-class%
>>     (class* object% ()
>>         (super-new)
>>         (define/public (child-method this-time) (error 'child-method 
>> "abstract method"))
>>         (define/public (child-implementation-dependent-method 
>> given-inputs-list)
>>             (map
>>                 (lambda(this-item)
>>                     (eprintf "Next list item is ~v" (child-method 
>> this-item)))
>>                 given-inputs-list))))
>>
>> (define first-child-class%
>>     (class* generic-parent-class% (child-interface)
>>         (super-new)
>>         (define/override (child-method given-input)
>>             (string-append "First got  " given-input))))
>>
>> (define second-child-class%
>>     (class* generic-parent-class% (child-interface)
>>         (super-new)
>>     (define/override (child-method given-input)
>>         (string-append "Second got  " given-input))))
>>
>> Sincerely yours,
>> Alex
>>> Date: Wed, 24 Aug 2011 09:04:40 -0600
>>> From: Jon Rafkind<rafkind at cs.utah.edu>
>>> To:users at racket-lang.org
>>> Subject: Re: [racket] How to use abstract classes?
>>> Message-ID:<4E551308.5020503 at cs.utah.edu>
>>> Content-Type: text/plain; charset=ISO-8859-1
>>>
>>> You could use a mixin.http://docs.racket-lang.org/reference/mixins.html?q=mixin&q=class#(form._((lib._racket/private/class-internal..rkt)._mixin))
>>>
>>> On 08/24/2011 08:31 AM, Alexander Kasiukov wrote:
>>>> Dear Racket users,
>>>>
>>>> What is the best way to make a class in Racket abstract? I would like to have a class which
>>>>
>>>>      never gets instantiated
>>>>      implements certain methods common to all of its children
>>>>      needs to call some of the methods implemented in the children.
>>>>
>>>> Sincerely yours,
>>>> Alex
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20110824/393c55c0/attachment.html>

Posted on the users mailing list.