In Racket's class system, what do augment, overment, augride, etc. do?
Asked Answered
S

1

8

Racket's documentation only partially describe what augment and pubment do: augment makes a method that executes after the superclass's version of that method, while pubment makes a method that will implicitly have the augment property if it is defined in a child class.

The docs say absolutely nothing about overment and augride, and I can't guess what they would do based on their names. What are they, and what is the difference between them?

Severe answered 31/3, 2015 at 22:34 Comment(0)
A
13

The relatively large family of inheritance functions for Racket's class system is, as you describe, a little confusing, and their somewhat cutesy names don't always help.

In order to understand this, Racket provides two separate mechanisms for method inheritance.

  • public methods correspond to the classical idea of public methods in other OO models. Methods declared with public may be overridden in subclasses, unless they're declared final, in which case they cannot.
  • pubment methods are similar, but they cannot be overridden, only augmented. Augmenting a method is similar to overriding it, but the dispatch calls the superclass's implementation instead of the subclass's.

To clarify the difference between overriding and augmentation, when an overridden method is called, the overriding implementation is executed, which may optionally call the superclass's implementation via inherit/super. In contrast, in an augmented method, the superclass's implementation receives control, and it may optionally call the subclass's implementation via inner.

Now, we're also provided public-final, override-final, and augment-final. These are pretty simple. Declaring a method with public-final means it can neither be augmented nor overridden. Using override-final overrides a superclass's public method, but it doesn't allow any further overriding. Finally, augment-final is similar, but for methods declared with pubment, not public.

So then, what about the two weird hybrids, overment and augride?

  • overment can be used to implement methods initially defined with public. This "converts" them to augmentable methods instead of overridable methods for all the class's subclasses.
  • augride goes in the opposite direction. It converts an augmentable method to one that is overridable, but the overriding implementations only replace the augmentation, not the original implementation.

To summarize:

  • public, pubment, and public-final all declare methods that do not exist in a superclass.
  • Then we have a family of forms for extending superclass methods:
    • override and augment extend methods declared with public and pubment, respectively, using the relevant behaviors.
    • override-final and augment-final do the same as their non-final counterparts, but prevent further overriding or augmentation.
    • overment and augride convert overridable methods to augmentable ones and vice-versa.

For another, fuller explanation, you might be interested in taking a look at the paper from which Racket's model was derived, which is quite readable and includes some helpful diagrams.

Ayurveda answered 31/3, 2015 at 23:2 Comment(3)
It's a shame that Racket's default class system supports final methods, though. I'm sure I'll end up having to write some nasty workaround for some final method at some point in the future.Severe
@ThrowawayAccount3Million Having final methods is an important tool to enforce encapsulation. It shouldn't be abused, and I don't think the Racket libraries ever use it lightly.Ayurveda
Thanks—this is important stuff! Is it explained in the official documentation anywhere? In particular, do you know the meaning of the arguments to augment, or know where they're documented? (So far, I haven't been able to understand the meaning of the example here.)Dewitt

© 2022 - 2024 — McMap. All rights reserved.