[plt-scheme] inheritance of private fields?

From: tom sgouros (tomfool at as220.org)
Date: Fri Feb 29 17:31:58 EST 2008

Matthias Felleisen <matthias at ccs.neu.edu> wrote:

> 
> define's introduce invisible local definitions.
> 
> field introduces fields that can be visible from subclasses:
> 
>    (define pond%
>       (class object%
>         (super-new)
>         (field [current-depth 200])
>         (define/public (get-depth) current-depth)))
> 
>     (define small-pond%
>       (class pond%
>         (inherit-field current-depth)
>         (super-new)
>         (define/override (get-depth) (min 100 current-depth))))

This makes sense, and I maybe see what you're driving at with it.  Is it
correct to say that I should forget about what I was trying to do
(inherit the name and change the value) and just hide the data value I
have behind some accessor function and inherit that, as you do here?

> The proposal below was about protecting methods wrt scope.
> 
> ;; ---
> 
> Your message drops the important example:
> 
> (with-handlers ((exn:fail:object? (lambda (x) (printf "method get- 
> depth not found, as expected: ~e" x))))
>   (send fish get-depth))
> 
> If I haven't sent it before. sorry -- Matthias

No, you sent it before.  I just didn't (don't) understand why it's
interesting, especially given that it all worked the same after I
removed the member-key business.  I didn't see anything in the
definition of fish% that would have led me to believe that (send fish
get-depth) would be anything but an error.  This is probably because of
my rudimentary understanding of scoping rules.  When I look at the
definition of fish%, the only reference to get-depth seems to be the
unproblematic one where it's called as a method of pond%.

Thank you,

 -tom

> 
> 
> 
> On Feb 29, 2008, at 3:24 PM, tom sgouros wrote:
> 
> >
> > Matthias Felleisen <matthias at ccs.neu.edu> wrote:
> >
> >>
> >>
> >> Yes, that's what I meant. Does the below working example help? (v
> >> 4.0) -- Matthias
> >>
> >
> > Not really.  I mean this (same thing as your example, but without the
> > member-key incantation) works, so far as I can see:
> >
> >     (define fish%
> >       (class object%
> >         (super-new)
> >         (define my-depth 10)
> >         (define my-pond (new pond%))
> >         (define/public (dive amt)
> >           (set! my-depth
> >                 (min (+ my-depth amt )
> >                      (send my-pond get-depth)))
> >           my-depth)))
> >
> >     (define pond%
> >       (class object%
> >         (super-new)
> >         (define current-depth 200)
> >         (define/public (get-depth) current-depth)))
> >
> > (define fish (new fish%))
> >
> > What does the generate-member-key do for me?
> >
> > But more to the point, my question is, I think, much simpler than
> > this.
> > It's about one class inheriting non-method data fields from its parent
> > and overriding their values, which I haven't figured out how to do,
> > despite parsing the documentation as closely as I know how to do, and
> > which seems like it ought to be trivial.  Maybe it's not?
> >
> > I am way too dense about the abstractions here to understand how to
> > make
> > the connection between my problem and your example, which is about
> > sharing symbols between two non-related classes, one of which uses
> > another.  (The fact that they seem to me to be shared already just
> > makes
> > your answer seem a bit more mysterious.)  The problems seem vaguely
> > related, but too vague for me too make sense of.
> >
> > I would also be interested to know whether I can treat inherit-field
> > like a let*, or whether the order of initializations is not
> > guaranteed.
> >
> > Many thanks,
> >
> >  -tom
> >
> >
> >>
> >> #lang scheme
> >>
> >> (require scheme/class)
> >>
> >> (define-values (fish% pond% ) ;; two mutually recursive classes
> >>   (let () ; create a local definition scope
> >>     (define-member-name get-depth (generate-member-key))
> >>     (define fish%
> >>       (class object%
> >>         (super-new)
> >>         (define my-depth 10)
> >>         (define my-pond (new pond%))
> >>         (define/public (dive amt)
> >>           (set! my-depth
> >>                 (min (+ my-depth amt )
> >>                      (send my-pond get-depth)))
> >>           my-depth)))
> >>     (define pond%
> >>       (class object%
> >>         (super-new)
> >>         (define current-depth 200)
> >>         (define/public (get-depth) current-depth)))
> >>     (values fish% pond%)))
> >>
> >> (define fish (new fish%))
> >>
> >> (send fish dive 300)
> >>
> >> (with-handlers ((exn:fail:object? (lambda (x) (printf "method get-
> >> depth not found, as expected: ~e" x))))
> >>   (send fish get-depth))
> >>
> >>
> >>
> >>
> >> On Feb 29, 2008, at 9:47 AM, tom sgouros wrote:
> >>
> >>>
> >>> Matthias Felleisen <matthias at ccs.neu.edu> wrote:
> >>>
> >>>>
> >>>> Take a look at the paper at
> >>>>
> >>>>  http://www.ccs.neu.edu/scheme/pubs/#aplas06-fff
> >>>>
> >>>> It shows how to generate "private" names that you can share in a
> >>>> way
> >>>> that's analogous to protected in Java but you can choose the
> >>>> restriction policy via lexical scope.
> >>>
> >>> Thank you for the help, and I'm sorry to be so dense, but I've been
> >>> looking at that paper for about half an hour, and I don't see which
> >>> part
> >>> is applicable.  You're not talking about the generate-member-key
> >>> business are you?  Can you be more specific, please?
> >>>
> >>> My apologies,
> >>>
> >>>  -tom
> >>>
> >>>>
> >>>>
> >>>> On Feb 29, 2008, at 7:45 AM, Tom Sgouros wrote:
> >>>>
> >>>>>
> >>>>> Hello all:
> >>>>>
> >>>>> I want to define a general class with some private fields that
> >>>>> can be
> >>>>> used by subclass.  Here's a dumb example of what I thought
> >>>>> would be
> >>>>> the
> >>>>> right way to do this, but apparently isn't:
> >>>>>
> >>>>> (define size%
> >>>>>   (class* object% ()
> >>>>>     (public print-name print-age print-weight)
> >>>>>
> >>>>>     (init-field (name 'Fred) (bday 070661)))
> >>>>>
> >>>>>     (define age (calculate-age bday))
> >>>>>     (define weight 0)
> >>>>>
> >>>>>     (define print-name (display name))
> >>>>>     (define print-age (display age))
> >>>>>     (define print-weight (display weight))
> >>>>>
> >>>>>     (super-new)))
> >>>>>
> >>>>> Now I want to be able to define a sub-class of this, so that
> >>>>> age and
> >>>>> weight are available to definitions in that sub-class.  I haven't
> >>>>> been
> >>>>> able to do that, so feel I must be missing something.
> >>>>>
> >>>>> In the example age is a calculated value that depends on other
> >>>>> init-field values.  I'd make it public by putting it into the
> >>>>> init-
> >>>>> field
> >>>>> sequence, if there's a guarantee that the init-field entries are
> >>>>> processed in order (that it's a let* and not a let).  I can't
> >>>>> find any
> >>>>> such guarantee in the documentation.  Failing that, what should I
> >>>>> do to
> >>>>> make it available?
> >>>>>
> >>>>> The weight private field should have no default value, but is
> >>>>> intended
> >>>>> to be given one by the sub-class.  In my class-naif view of these
> >>>>> things, I should really make size% an interface and force the sub-
> >>>>> class
> >>>>> to fill in the weight.  But I can't seem to figure out how to do
> >>>>> that,
> >>>>> either.
> >>>>>
> >>>>> Can someone explain to me the proper way to deal with these
> >>>>> issues?
> >>>>> Any
> >>>>> advice welcome.
> >>>>>
> >>>>> Many thanks,
> >>>>>
> >>>>>  -tom
> >>>>>
> >>>>> -- 
> >>>>>  ------------------------
> >>>>>  tomfool at as220 dot org
> >>>>>  http://sgouros.com
> >>>>>  http://whatcheer.net
> >>>>> _________________________________________________
> >>>>>   For list-related administrative tasks:
> >>>>>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
> >>>>
> >>>
> >>>
> >>> -- 
> >>>  ------------------------
> >>>  tomfool at as220 dot org
> >>>  http://sgouros.com
> >>>  http://whatcheer.net
> >>
> >
> >
> > -- 
> >  ------------------------
> >  tomfool at as220 dot org
> >  http://sgouros.com
> >  http://whatcheer.net
> 


-- 
 ------------------------
 tomfool at as220 dot org
 http://sgouros.com  
 http://whatcheer.net


Posted on the users mailing list.