lucy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marvin Humphrey <>
Subject Re: [lucy-dev] Extensibility of Clownfish runtime core
Date Fri, 27 Dec 2013 03:28:57 GMT
Getting back to this issue...

On Wed, Oct 16, 2013 at 7:44 AM, Nick Wellnhofer <>
>On 10/10/2013 06:03, Marvin Humphrey wrote:
>> Something to consider is that there's little value in making the
>> core runtime classes extensible.  Lucy subclasses Hash, but it's a nasty
>> and we could have just written our own hash table implementation from
>> anyway.
>> What do you think of making all the core runtime classes final except
for Obj?
>> There are advantages to limiting ourselves to a single carefully designed
>> extension point.
> This should probably be decided on a case-by-case basis. In
> Clownfish::String I would make every method final but it might still be
> useful to inherit from String and add new methods.

Let's consider the costs and benefits of extendability for String.

Allowing the String class to be extended enables certain kinds of problem
solving approaches.  For example, the build tool Rake monkey patches the
String class to add the `ext` method, a feature which we use in our

    filepath_o = filepath_c.ext(".o")

What we're contemplating for Clownfish is actually less powerful than what
Ruby facilitates, because we'd only allow subclassed instances to run the
additional methods, while Ruby allows you to add methods to the original
class.  In any case, I don't think that use case is very compelling because
pefectly plausible alternative is available: instead of extending string
new instance methods, provide the same functionality via inert functions in
string manipulation libraries.

    filepath_o = MyPathTools.ext(filepath_c, ".o")

Another possible use case for extending String might be to allow a subclass
add a marker property, as contemplated in this blog post:

However, adding markers is made more difficult by a core feature of
automatic conversion of basic data types at the C/host border.  Since you
can't count on your subclass being preserved through that conversion
the marker is easily lost.

Consider the principle that Joshua Bloch articulates in his book, _Effective

    Item 17: Design and document for inheritance or else prohibit it

    Item 16 alerted you to the dangers of subclassing a “foreign” class that
    was not designed and documented for inheritance. So what does it mean
    a class to be designed and documented for inheritance?

    First, the class must document precisely the effects of overriding any
    method. In other words, the class must document its self-use of
    overridable methods. For each public or protected method or constructor,
    the documentation must indicate which overridable methods the method or
    constructor invokes, in what sequence, and how the results of each
    invocation affect subsequent processing. (By overridable, we mean
    and either public or protected.) More generally, a class must document
    circumstances under which it might invoke an overridable method. For
    example, invocations might come from background threads or static

The problem we're up against is that Clownfish does some inherently
things with object creation and destruction.  It has to be compatible with
memory management regimes of multiple host languages.  It has to provide
conversion routines to and from the host language data types which operate
the C/host boundary.  Round-tripping through the conversion routines is
already complicated enough, because the mapping from Clownfish data types to
host data types is always imperfect.  I don't see how you implement a sane
conversion routine which preserves subclassing for core data types.

It's hard to "design and document for inheritance" under the best of
circumstances.  Other object systems close off core data types, notably
so it's perfectly legitimate for Clownfish to do so as well.  While I can
why one might appreciate Ruby-style extensibility, I think prohibiting it
most core data types is a more appropriate choice for Clownfish.  Not only
we save ourselves the time and trouble it would take to implement
extensibility well in the first place, the simplification allows us to
Clownfish's distinguishing features more effectively.

So, if we're going case-by-case, I'd advocate that we work hard to design
following types for extensibility by users...


... and work to close everything else off.

Marvin Humphrey

  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message