Part of the problem here is determining the reason for extending the
base class:
a) the base class was cleverly designed so that certain objects were
intended to be extended/replaced
b) the base class doesn't fit my needs and I need to tweak it a
little to make it useful for me
Making *everything* open is useful for option (b) and perhaps
necessary with swiss-army-knife objects like the view class, but
scary for option (a) because the stuff that's "public" is
indistinguishable from the stuff that's "private". OTOH, requiring
explicitly defined access points means that your base class
implementer needs to be clever enough to know what to open up.
It's a classic chicken and egg with no perfect solution. Personally,
I like open access (solving problem b), but it's always useful if
there's some way for the clever base class implementers out there to
provide hints regarding the objects s/he *wants* you to extend/
replace. That is perhaps some reason for designing a form of
"typing" where the base class can declare what type of object may
replace specified children.
Or maybe the question answers itself: replacement is useful for (a),
while extension is useful for (b). And thus one would be allowed to
extend any child elements, but would only be allowed to replace those
that were declared as replaceable by the class implementer.
On Dec 14, 2005, at 2:37 PM, P T Withington wrote:
On 14 Dec 2005, at 13:11, Oliver Steele wrote:
On Dec 13, 2005, at 6:09 PM, Antun Karlovac wrote:
Should you be able to reach inside of a class and add attributes
to a class'es children? Is that good OO practice? Doesn't that
require that you have an intimate knowledge of its workings when
you make an instance?
It's terrible practice unless --- wait --- it's AOP for
declarative programming, in which case it must be best-of-best
practice!
But, I thought AOP was simply a way to retrofit dynamicity into a
language that is too static to do what you really want? Oh, and
the tag part of LZX is too static!
Seriously (well, I can't actually find a flaw in the AOP analogy,
so maybe it's serious too...) One reason not to use attributes
and constraints is performance. Another is YAGNI. An organically
grown class is unlikely to have the extra indirection, but you
often need to modify those classes in unforeseen ways too.
You could argue that you shouldn't be extending a class in ways
that its author didn't foresee, and should fork and refactor them
instead. C++ and Java support this methodology by providing
visibility modifiers that prevent a subclass from calling or
overriding superclass methods that are marked 'private'. The
scripting languages get along without it. Right now, LZX is more
like the scripting languages, with respect to methods. This
proposal would extend that laissez-faire attitude to structure as
well.
I really like the granularity Dylan introduce with the open/sealed
adjective. I like the designer being able to say: "these are the
bits of my class that I expect to be extended". I like that AS3
has adopted this, and I would like to see it adopted in
Javascript. It has the benefit of making the language a little
less sloppy, and the bonus of making it easier to compile. (I
_don't_ like the super-fine-grained access that C++ introduced. It
is too complex and restrictive for a scripting language.)
I would vote for the class library designer having to at least say:
<class name="baseclass" extensibility="open">
<view name="top" extensibility="open" ... />
(or something like that) to declare that the class permits
extensibility in the sense of your proposal. And I would propose
that we think about making classes in a library not extensible
outside the library by default (as in Dylan).
I also like that you should have to declare your intension to
extend, to allow the compiler to tell you when you made a type-oh.
[...]
In my classes I teach developers to specify attributes at the
root of the class that the children constrain themselves too, e.g.
<class name="myclass">
<attribute name="contentswidth" />
<view name="contentsview" width="${parent.contentswidth}" />
</class>
Being able to paramaterize the name of classes that a class uses
inside itself (in a declarative manner) would be a great feature
for components in general.
Yeah, and yesterday's proposal doesn't really cover this. That's
a third use case, where you want to use the class name from the
override but the inherit class attributes and children from the
class definition. The proposal could be extended to define this
as valid:
<class name="baseclass">
<view name="top" height="20" width="100%" bgcolor="red"/>
<class name="myclass" extends="baseclass">
<mytop replace="top">
and having the effect of:
<class name="myclass">
<mytop name="top" height="20" width="100%" bgcolor="red"/>
Surely mytop must subclass top's class in this case (covariance)
and the default must be for the 'default init-args' to be passed to
it? So you would just say:
<class name="myclass" extends="baseclass">
<mytop name="top" extends="view" />
?
_______________________________________________
Laszlo-dev mailing list
[email protected]
http://www.openlaszlo.org/mailman/listinfo/laszlo-dev
_______________________________________________
Laszlo-dev mailing list
[email protected]
http://www.openlaszlo.org/mailman/listinfo/laszlo-dev