lucy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marvin Humphrey <mar...@rectangular.com>
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 <wellnhofer@aevum.de>
wrote:
>On 10/10/2013 06:03, Marvin Humphrey wrote:
>> Something to consider is that there's little value in making the
Clownfish
>> core runtime classes extensible.  Lucy subclasses Hash, but it's a nasty
hack
>> and we could have just written our own hash table implementation from
scratch
>> 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
Ruby
String class to add the `ext` method, a feature which we use in our
Rakefiles:

    http://rake.rubyforge.org/classes/String.html

    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
a
pefectly plausible alternative is available: instead of extending string
with
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
to
add a marker property, as contemplated in this blog post:


http://www.nofluffjuststuff.com/blog/joe_walker/2007/04/java_7_idea_extensible_strings

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

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

    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
for
    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
nonfinal
    and either public or protected.) More generally, a class must document
any
    circumstances under which it might invoke an overridable method. For
    example, invocations might come from background threads or static
    initializers.

The problem we're up against is that Clownfish does some inherently
ambitious
things with object creation and destruction.  It has to be compatible with
the
memory management regimes of multiple host languages.  It has to provide
conversion routines to and from the host language data types which operate
at
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
Java,
so it's perfectly legitimate for Clownfish to do so as well.  While I can
see
why one might appreciate Ruby-style extensibility, I think prohibiting it
for
most core data types is a more appropriate choice for Clownfish.  Not only
do
we save ourselves the time and trouble it would take to implement
extensibility well in the first place, the simplification allows us to
pursue
Clownfish's distinguishing features more effectively.

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

    Obj
    Err

... and work to close everything else off.

Marvin Humphrey

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