On Feb 7, 2008, at 3:50 PM, P T Withington wrote:
Since a mixin is an "interface with implementation", it makes sense
to me that the implementation part of the mixin should obey the same
rules that a subclass would have to obey. So, if the mixin is
overriding, it should declare override. If the mixin has a public
method, it should declare it public.
agreed.
When your compiler splits the mixin into an interface and an
implementation (interstitial class), the only signatures that should
appear in the interface are the public parts of the mixin, right?
It would not make sense to have an interface declare a method that
is not public. At least that's the way I interpret your results.
An interface is a contract about an API, to have part of the API be
inaccessible just wouldn't be useful.
That makes good sense to me. Yes, of course a mixin might want to
have some private functions.
Similarly, I expect that you probably _can_ define an interface to
be in a namespace, but then all the methods that it specifies would
have to be in the same namespace too, so that if you have access to
the namespace you have access to the API, but you either get the
whole API or nothing.
haven't tried this yet...
To answer your specific question:
Should we require 'public' on the mixin? or is it optional?
In a mixin, 'public' means that it is part of the mixin interface
(part of the API contract defined by the mixin), whereas non-public
(default) means that it is only part of the mixin implementation.
It may support the implementation of the API, but it is not part of
the API.
Sounds good.
_Probably_ we should also allow a mixin to declare just an API
signature also, which would be a way of indicating a "required
method" of any subclass that mixes it in.
Like an abstract method in java (AS3 also has abstract methods BTW -
though we don't yet support them).
Unfortunately, from your experiments, it appears that such a
required method would have to be public, which is often not what you
want (since a required method is meant to be a constraint on the sub
or concrete class implementation, not on its API).
Yes, true. Perhaps the best we can do is:
- if the API signature is declared public, then it's part of the
interface.
- if the API signature is not public, it's not part of the
interface, it becomes an abstract method in the interstitial,
and must be declared (public) in the class. I think we could
mitigate the effects by declaring it
using some $lzprivate$ prefix and marking the javadoc private.
Can I defer the issue of 'required methods' for the moment? We might
want to think about
making this more general (i.e. supporting the abstract function
concept in any class as well as mixin).
- Don
On 2008-02-07, at 15:20 EST, Donald Anderson wrote:
In the classic 'Sundae extends Vanilla with Banana' example,
all of the classes define function 'test'. Just focusing on this
part,
I was a little confounded by the need for override and public
keywords.
What follows is a recipe that works, and it does make sense.
'public' and 'override' must appear exactly as indicated:
class Vanilla {
public function test () { return "vanilla"; }
}
interface Banana {
function test () ;
}
class Banana$Vanilla extends Vanilla implements Banana {
public override function test () { return "banana"; }
}
class Sundae extends Banana$Vanilla {
public override function test () { return "sundae"); }
}
In Banana$Vanilla:test, the 'public' is needed satisfy
the 'implements Banana'. The 'override' is needed since
test is also defined in Vanilla.
In Sundae:test, 'override' is needed because test is defined in
superclasses. 'public' is needed to match Banana$Vanilla.
In Vanilla:test, the 'public' is needed to match what is being
overridden in Banana$Vanilla.
So back up to what the original source must look like:
class Vanilla {
public function test () { return "vanilla"; }
}
mixin Banana {
/*public?*/ override function test () { return "banana"; }
}
class Sundae with Banana {
public override function test () { return "sundae"); }
}
Should we require 'public' on the mixin? or is it optional?
(It actually doesn't matter much to me -- I think I always emit
public in the class, and no public in the interface).
Obviously if you know that the ultimate superclass has test(),
then the mixin should declare it override. Is this something
we'll know in practice? In theory this could be detected
for the classes we see in the parse, but it's a bigger deal
if the method being overridden is in a library (eventually).
Also, I was wondering how namespaces work in this.
From some quick experiments, it looks like namespaces
are not allowed on interface methods,
interface Banana {
// ns1 function another(); // XXX compiler error
function another();
}
nor by using a namespace name can you fulfill your implementation:
class Banana$Vanilla extends Vanilla implements Banana {
ns1 function another(); // XXX error - Banana not
implemented.
}
- Don
--
Don Anderson
Java/C/C++, Berkeley DB, systems consultant
voice: 617-547-7881
email: [EMAIL PROTECTED]
www: http://www.ddanderson.com
--
Don Anderson
Java/C/C++, Berkeley DB, systems consultant
voice: 617-547-7881
email: [EMAIL PROTECTED]
www: http://www.ddanderson.com