Home » Language IDEs » Objectteams » An idea on value bound classes
An idea on value bound classes [message #506933] |
Mon, 11 January 2010 12:04 |
Eugene Hutorny Messages: 110 Registered: January 2010 |
Senior Member |
|
|
Value bound types opens possibility on optional features that are available for some values only.
This may be useful for modeling "parallel" hierarchies. For example all mammal females has feature "breed". But if it is declared on the Mammal class, male instances will also get this feature. I do not see a good solution for this issue with existing OO languages. With value bound types it may look as the following:
enum Gender { Male, Female }
public class Human<Gender gender> extends Primates<gender> {
@Override
Human<?> breed() { ... } when( gender == Gender.Female )
}
Primates<?> individual = new Human<@Gender.Female>();
Primates<@Gender.Male> male = new Human<@Gender.Male>();
Primates<@Gender.Female> female = new Human<@Gender.Female>();
individual.breed(); // compiler error
male.breed(); // compiler error
female.breed(); // OK
[Updated on: Mon, 11 January 2010 12:11] Report message to a moderator
|
|
|
Re: An idea on value bound classes [message #506965 is a reply to message #506933] |
Mon, 11 January 2010 14:54 |
Stephan Herrmann Messages: 1853 Registered: July 2009 |
Senior Member |
|
|
Wow, that's indeed an interesting idea.
It's certainly not a small change so please don't expect a solution
in one of the next milestones, but let's see where this would take us:
You propose methods that are available depending on a condition.
The most fundamental solution would be to support arbitrary
conditions, but that wouldn't be checkable by the compiler.
So you propose conditions based on the actual value of a
value parameter of the enclosing class. Furthermore, your
example suggests to think only of those values that are typed
to a enum. Enums have the advantage that the possible values
are indeed known to the compiler.
The proposal could be seen as a lightweight kind of mixins or
traits in the way that you can compose types from smaller
building blocks, here the fundamental class hierarchy plus
add-ins depending on the value parameter.
One note on syntax: I don't think the "when" syntax is
appropriate here, because in OT/J "when" denotes a filter
on a callin trigger. I.e., "when" encodes a runtime condition.
By contrast your proposal is not a control flow construct,
but defines rules on applicability of certain methods,
that are checked by the compiler.
Here is an alternative syntax:
public class Mammal<Gender gender> {
// conditional methods:
switch (gender) {
case Female:
Mammal<?> breed() { ... }
}
// follows: unconditional methods
// ...
}
this sure looks ... unusual at first, but might serve as a
basis for further discussion. The above syntax makes
explicit that we are actually discussion a form of variant
types ("unions"). The power is indeed that these variants
are orthogonal to the regular class hierarchy.
For comparison, here is another OT/J based solution:
public team class Mammals {
public abstract class Mammal { /* common methods */ }
public class Male extends Mammal { }
public class Female extends Mammal {
public Mammal breed() { .... }
}
}
public team class Humans extends Mammals {
}
void test(final Mammals theSpecies) { // can be subtype of Mammals
Mammal<@species> individual = new Female<@species>();
Male<@species> male = new Male<@species>();
Female<@species> female = new Female<@species>();
individual.breed(); // compiler error
male.breed(); // compiler error
female.breed(); // OK
}
final Mammals theMammals = new Mammals();
final Humans theHumans = new Humans();
test(theMammals);
test(theHumans);
Here, too, we have two dimensions of specialization:
- Mammals -> Humans
- Mammal -> Female
The alternative solution sure looks different, but I'd claim it has
roughly the same capabilities as the feature you propose.
Additionally, my solution gives a more precise return type
for breed: mammals breed Mammals.Mammal, humans yield
Humans.Mammal, without the need for explicit covariant
redefinition.
What do you think?
Stephan
|
|
|
Re: An idea on value bound classes [message #506999 is a reply to message #506965] |
Mon, 11 January 2010 16:26 |
Eugene Hutorny Messages: 110 Registered: January 2010 |
Senior Member |
|
|
Stephan Herrmann wrote on Mon, 11 January 2010 09:54 | Wow, that's indeed an interesting idea.
It's certainly not a small change so please don't expect a solution
in one of the next milestones, but let's see where this would take us:
|
Please take it as just an idea to discuss, not a feature request
Stephan Herrmann wrote on Mon, 11 January 2010 09:54 |
You propose methods that are available depending on a condition.
The most fundamental solution would be to support arbitrary
conditions, but that wouldn't be checkable by the compiler.
So you propose conditions based on the actual value of a
value parameter of the enclosing class. Furthermore, your
example suggests to think only of those values that are typed
to a enum. Enums have the advantage that the possible values
are indeed known to the compiler.
|
I think that there is a class of conditions that can be checked by the compiler and it is not limited to enums only.
Stephan Herrmann wrote on Mon, 11 January 2010 09:54 |
The proposal could be seen as a lightweight kind of mixins or
traits in the way that you can compose types from smaller
building blocks, here the fundamental class hierarchy plus
add-ins depending on the value parameter.
|
Yes, that describes my proposal well.
Stephan Herrmann wrote on Mon, 11 January 2010 09:54 |
One note on syntax: I don't think the "when" syntax is
appropriate here, because in OT/J "when" denotes a filter
on a callin trigger. I.e., "when" encodes a runtime condition.
By contrast your proposal is not a control flow construct,
but defines rules on applicability of certain methods,
that are checked by the compiler.
|
I used "when" just to express the idea in a simple way.
Stephan Herrmann wrote on Mon, 11 January 2010 09:54 |
Here is an alternative syntax:
public class Mammal<Gender gender> {
// conditional methods:
switch (gender) {
case Female:
Mammal<?> breed() { ... }
}
// follows: unconditional methods
// ...
}
this sure looks ... unusual at first, but might serve as a
basis for further discussion. The above syntax makes
explicit that we are actually discussion a form of variant
types ("unions"). The power is indeed that these variants
are orthogonal to the regular class hierarchy.
|
Well, "switch" is also a control flow construct, isn't it?
Stephan Herrmann wrote on Mon, 11 January 2010 09:54 |
For comparison, here is another OT/J based solution:
public team class Mammals {
public abstract class Mammal { /* common methods */ }
public class Male extends Mammal { }
public class Female extends Mammal {
public Mammal breed() { .... }
}
}
public team class Humans extends Mammals {
}
void test(final Mammals theSpecies) { // can be subtype of Mammals
Mammal<@species> individual = new Female<@species>();
Male<@species> male = new Male<@species>();
Female<@species> female = new Female<@species>();
individual.breed(); // compiler error
male.breed(); // compiler error
female.breed(); // OK
}
final Mammals theMammals = new Mammals();
final Humans theHumans = new Humans();
test(theMammals);
test(theHumans);
Here, too, we have two dimensions of specialization:
- Mammals -> Humans
- Mammal -> Female
The alternative solution sure looks different, but I'd claim it has
roughly the same capabilities as the feature you propose.
Additionally, my solution gives a more precise return type
for breed: mammals breed Mammals.Mammal, humans yield
Humans.Mammal, without the need for explicit covariant
redefinition.
What do you think?
Stephan
|
When class Human adds new features, they will not be available in Male, or Female classes:
public team class Humans extends Mammals {
public class Human extends Mammal {
public void think() {}
}
}
...
male.think(); // compiler error
|
|
|
Re: An idea on value bound classes [message #507012 is a reply to message #506999] |
Mon, 11 January 2010 16:52 |
Eugene Hutorny Messages: 110 Registered: January 2010 |
Senior Member |
|
|
Eugene Hutorny wrote on Mon, 11 January 2010 11:26 |
When class Human adds new features, they will not be available in Male, or Female classes:
|
I've figured out how to solve this with teams:
public team class Mammals {
public abstract class Mammal { /* common methods */ }
public class Male extends Mammal { }
public class Female extends Mammal {
public void feed(Mammal mammal) {}
public Mammal breed() { return new Female(); }
}
}
public team class Humans extends Mammals {
public class Human extends Mammal {
public void think() {}
}
public class Male extends Human { }
public class Female extends Human {
public Human breed() { return new Female(); }
}
}
void test(final Humans species) {
Human<@species> individual = new Female<@species>();
Male<@species> male = new Male<@species>();
Female<@species> female = new Female<@species>();
individual.think();
male.think();
female.think();
//individual.breed(); // compiler error
//male.breed(); // compiler error
Human<@species> child = female.breed(); // OK
female.feed(child); // OK
child.think();
}
[Updated on: Mon, 11 January 2010 16:54] Report message to a moderator
|
|
|
Re: An idea on value bound classes [message #507199 is a reply to message #507012] |
Tue, 12 January 2010 13:26 |
Stephan Herrmann Messages: 1853 Registered: July 2009 |
Senior Member |
|
|
Quote: |
Quote: |
When class Human adds new features, they will not be available in Male, or Female classes:
|
I've figured out how to solve this with teams:
|
Yep, your solution works, but it can be done even simpler:
public team class Mammals { /* as before /* }
public team class Humans extends Mammals {
public class Mammal {
public void think() {}
}
// within this team Male and Female will automatically extend the augmented version of Mammal
}
void test(final Humans species) { // no longer supports general Mammals
Human<@species> individual = new Female<@species>();
Male<@species> male = new Male<@species>();
Female<@species> female = new Female<@species>();
individual.think();
male.think();
female.think();
//individual.breed(); // compiler error
//male.breed(); // compiler error
Mammal<@species> child = female.breed(); // OK <- changed
female.feed(child); // OK
child.think();
}
You needn't introduce a new type Humans.Human.
Simply adding methods to Humans.Mammal suffices.
As long as the team instance is known to be of type Humans,
all roles (Mammals, Male and Female) will provide the think() method.
Maybe all types XYZ.Mammal should now be renamed to
XYZ.Individual, so we speak of Humans.Individual rather
than Humans.Mammal.
So now, that you seen an alternative soluation that works
with current OT/J, do you still see significant advantage in
associating methods with value parameters?
best,
Stephan
|
|
| |
Goto Forum:
Current Time: Thu Sep 26 10:13:05 GMT 2024
Powered by FUDForum. Page generated in 0.05310 seconds
|