Home » Modeling » EMF » [emf] question about ComposedSwitch
| | |
Re: [emf] question about ComposedSwitch [message #719531 is a reply to message #719437] |
Sat, 27 August 2011 16:26 |
Ed Merks Messages: 33141 Registered: July 2009 |
Senior Member |
|
|
Knut,
Comments below.
On 26/08/2011 11:19 PM, Knut Wannheden wrote:
> Hi Ed,
>
> On 8/26/11 5:49 PM, Ed Merks wrote:
>> Knut,
>>
>> Would making private things protected help significantly? Perhaps if
>> your
>> strategy is suitably general we could incorporate it in the core...
>>
>
> No, unfortunately making the private method
> ComposedSwitch#findDelegate(EPackage) protected isn't enough. In
> ComposedSwitch#doSwitch(EClass, EObject) the protected method
> Switch#doSwitch(EClass, EObject) is also being called on the
> delegates. This of course only works because ComposedSwitch is in the
> same Java package as Switch. In my own subclass I would not be able to
> do this.
We could add a protected delegatedDoSwitch method to do the work of
delegate.doSwitch(theEClass, theEObject) and then you'd be able to call
that...
>
> So unless that method also becomes public (which doesn't seem quite
> right) the strategy would have to be implemented in the core.
I'd like to understand the exact details of the strategy.
>
> Now that you've made yourself familiar with Xtext you may have come
> across its PolymorphicDispatcher class. This is essentially what I'm
> trying to replace with a ComposedSwitch.
Could you illustrate what you have in mind?
>
> Regards,
>
> --knut
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
| |
Re: [emf] question about ComposedSwitch [message #719727 is a reply to message #719702] |
Sun, 28 August 2011 16:17 |
Ed Merks Messages: 33141 Registered: July 2009 |
Senior Member |
|
|
Knut,
Comments below.
On 28/08/2011 6:39 AM, Knut Wannheden wrote:
> Ed,
>
> On 8/27/11 18:26, Ed Merks wrote:
>>
>> We could add a protected delegatedDoSwitch method to do the work of
>> delegate.doSwitch(theEClass, theEObject) and then you'd be able to call
>> that...
>
> That would of course also be a nifty solution.
>
>>> So unless that method also becomes public (which doesn't seem quite
>>> right) the strategy would have to be implemented in the core.
>> I'd like to understand the exact details of the strategy.
>
> There are a few setups I'd like to support with this alternative
> strategy:
>
> 1. Let's say I have a ComposedSwitch which has a registered delegate
> for package 'a'. Now I switch on an instance 'b:BB' with super types
> 'b:B' and 'a:A' (in that order). I would now like the ComposedSwitch
> to delegate this to the switch for 'a:A' instead of returning "null".
So switch to the super type for which there is a registered and hence
specialized delegate.
>
> 2. Again I have a ComposedSwitch for package 'a' with types 'a:A' and
> 'a:AA', where 'a:A' is the super type of 'a:AA'. Now I switch on an
> instance of 'b:BB' which has the super types 'a:A' and 'b:B', where
> 'b:B' in turn has super type 'a:AA'. The ComposedSwitch should now
> delegate to the switch for 'a:AA' rather than 'a:A', since 'a:AA' is a
> "more concrete" super type of 'b:BB'.
So switch to the super type which has the most eAllSuperTypes for which
there are registered and hence specialized delegates.
>
> 3. Similar setup with types 'a:A' and 'a:A2' (no super type
> relationship between these) and a type 'b:B' which inherits from both
> 'a:A' and 'a:A2'. I would now like the ComposedSwitch to raise an
> exception because it can't decide which type to switch on instead of
> switching on 'a:A'.
When the alternatives are equally good, that's not good...
>
> I think these examples illustrate the difference to the current
> ComposedSwitch algorithm.
So what's the algorithm? For each Y among X's eSuperTypes, compute the
number of delegates that are available for Y's package, and for the
package of each Z among Y's eAllSuperTypes. Choose the Z with the most
delegates but throw an exception if two have the same number of
delegates. Is that the idea? I'm not sure if the default case ever
kicks in?
>
> --knut
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Re: [emf] question about ComposedSwitch [message #719805 is a reply to message #719727] |
Mon, 29 August 2011 05:28 |
Knut Wannheden Messages: 298 Registered: July 2009 |
Senior Member |
|
|
Ed,
On 8/28/11 18:17, Ed Merks wrote:
> Knut,
>
> Comments below.
>
> On 28/08/2011 6:39 AM, Knut Wannheden wrote:
>> Ed,
>>
>> On 8/27/11 18:26, Ed Merks wrote:
>>>
>>> We could add a protected delegatedDoSwitch method to do the work of
>>> delegate.doSwitch(theEClass, theEObject) and then you'd be able to call
>>> that...
>>
>> That would of course also be a nifty solution.
>>
>>>> So unless that method also becomes public (which doesn't seem quite
>>>> right) the strategy would have to be implemented in the core.
>>> I'd like to understand the exact details of the strategy.
>>
>> There are a few setups I'd like to support with this alternative
>> strategy:
>>
>> 1. Let's say I have a ComposedSwitch which has a registered delegate
>> for package 'a'. Now I switch on an instance 'b:BB' with super types
>> 'b:B' and 'a:A' (in that order). I would now like the ComposedSwitch
>> to delegate this to the switch for 'a:A' instead of returning "null".
> So switch to the super type for which there is a registered and hence
> specialized delegate.
>>
>> 2. Again I have a ComposedSwitch for package 'a' with types 'a:A' and
>> 'a:AA', where 'a:A' is the super type of 'a:AA'. Now I switch on an
>> instance of 'b:BB' which has the super types 'a:A' and 'b:B', where
>> 'b:B' in turn has super type 'a:AA'. The ComposedSwitch should now
>> delegate to the switch for 'a:AA' rather than 'a:A', since 'a:AA' is a
>> "more concrete" super type of 'b:BB'.
> So switch to the super type which has the most eAllSuperTypes for which
> there are registered and hence specialized delegates.
>>
>> 3. Similar setup with types 'a:A' and 'a:A2' (no super type
>> relationship between these) and a type 'b:B' which inherits from both
>> 'a:A' and 'a:A2'. I would now like the ComposedSwitch to raise an
>> exception because it can't decide which type to switch on instead of
>> switching on 'a:A'.
> When the alternatives are equally good, that's not good...
>>
>> I think these examples illustrate the difference to the current
>> ComposedSwitch algorithm.
> So what's the algorithm? For each Y among X's eSuperTypes, compute the
> number of delegates that are available for Y's package, and for the
> package of each Z among Y's eAllSuperTypes. Choose the Z with the most
> delegates but throw an exception if two have the same number of
> delegates. Is that the idea? I'm not sure if the default case ever kicks
> in?
The discussed algorithm of course only concerns the "else" part of
ComposedSwitch#doSwitch(EObject, EClass), where we deal with an
"unknown" type. I would summarize the algorithm as follows. For an
instance of the unknown type X get eAllSuperTypes and filter out any
unknown types. If we end up with an empty set or a single type we're
done. If we end up with multiple types then we continue to eliminate any
types which are direct or indirect super types of another type in this
set. If we still have more than one type left, we would have to
arbitrate somehow (e.g. call a protected method which by default throws
an exception).
So the default case would still kick in if we don't find any known super
type or if the delegate of the found super type didn't return anything.
--knut
|
|
|
Re: [emf] question about ComposedSwitch [message #720014 is a reply to message #719805] |
Mon, 29 August 2011 16:51 |
Ed Merks Messages: 33141 Registered: July 2009 |
Senior Member |
|
|
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
Knut,<br>
<br>
Comments below.<br>
<br>
On 28/08/2011 10:28 PM, Knut Wannheden wrote:
<blockquote cite="mid:j3f7cn$tn4$1@news.eclipse.org" type="cite">Ed,
<br>
<br>
On 8/28/11 18:17, Ed Merks wrote:
<br>
<blockquote type="cite">Knut,
<br>
<br>
Comments below.
<br>
<br>
On 28/08/2011 6:39 AM, Knut Wannheden wrote:
<br>
<blockquote type="cite">Ed,
<br>
<br>
On 8/27/11 18:26, Ed Merks wrote:
<br>
<blockquote type="cite">
<br>
We could add a protected delegatedDoSwitch method to do the
work of
<br>
delegate.doSwitch(theEClass, theEObject) and then you'd be
able to call
<br>
that...
<br>
</blockquote>
<br>
That would of course also be a nifty solution.
<br>
<br>
<blockquote type="cite">
<blockquote type="cite">So unless that method also becomes
public (which doesn't seem quite
<br>
right) the strategy would have to be implemented in the
core.
<br>
</blockquote>
I'd like to understand the exact details of the strategy.
<br>
</blockquote>
<br>
There are a few setups I'd like to support with this
alternative
<br>
strategy:
<br>
<br>
1. Let's say I have a ComposedSwitch which has a registered
delegate
<br>
for package 'a'. Now I switch on an instance 'b:BB' with super
types
<br>
'b:B' and 'a:A' (in that order). I would now like the
ComposedSwitch
<br>
to delegate this to the switch for 'a:A' instead of returning
"null".
<br>
</blockquote>
So switch to the super type for which there is a registered and
hence
<br>
specialized delegate.
<br>
<blockquote type="cite">
<br>
2. Again I have a ComposedSwitch for package 'a' with types
'a:A' and
<br>
'a:AA', where 'a:A' is the super type of 'a:AA'. Now I switch
on an
<br>
instance of 'b:BB' which has the super types 'a:A' and 'b:B',
where
<br>
'b:B' in turn has super type 'a:AA'. The ComposedSwitch should
now
<br>
delegate to the switch for 'a:AA' rather than 'a:A', since
'a:AA' is a
<br>
"more concrete" super type of 'b:BB'.
<br>
</blockquote>
So switch to the super type which has the most eAllSuperTypes
for which
<br>
there are registered and hence specialized delegates.
<br>
<blockquote type="cite">
<br>
3. Similar setup with types 'a:A' and 'a:A2' (no super type
<br>
relationship between these) and a type 'b:B' which inherits
from both
<br>
'a:A' and 'a:A2'. I would now like the ComposedSwitch to raise
an
<br>
exception because it can't decide which type to switch on
instead of
<br>
switching on 'a:A'.
<br>
</blockquote>
When the alternatives are equally good, that's not good...
<br>
<blockquote type="cite">
<br>
I think these examples illustrate the difference to the
current
<br>
ComposedSwitch algorithm.
<br>
</blockquote>
So what's the algorithm? For each Y among X's eSuperTypes,
compute the
<br>
number of delegates that are available for Y's package, and for
the
<br>
package of each Z among Y's eAllSuperTypes. Choose the Z with
the most
<br>
delegates but throw an exception if two have the same number of
<br>
delegates. Is that the idea? I'm not sure if the default case
ever kicks
<br>
in?
<br>
</blockquote>
<br>
The discussed algorithm of course only concerns the "else" part of
ComposedSwitch#doSwitch(EObject, EClass), where we deal with an
"unknown" type. </blockquote>
<br>
You mean the if-part, right? (Where it arbitrarily picks the first
super type.)<br>
<blockquote><small> @Override</small><br>
<small> protected T doSwitch(EClass theEClass, EObject
theEObject)</small><br>
<small> {</small><br>
<small> Switch<T> delegate =
findDelegate(theEClass.getEPackage());</small><br>
<small> if (delegate == null)</small><br>
<small> {</small><br>
<small> List<EClass> eSuperTypes =
theEClass.getESuperTypes();</small><br>
<small> return eSuperTypes.isEmpty() ?
defaultCase(theEObject) : doSwitch(eSuperTypes.get(0),
theEObject);</small><br>
<small> }</small><br>
<small> else</small><br>
<small> {</small><br>
<small> T result = delegate.doSwitch(theEClass, theEObject);</small><br>
<small> return result == null ? defaultCase(theEObject) :
result;</small><br>
<small> }</small><br>
<small> }</small><br>
</blockquote>
<blockquote cite="mid:j3f7cn$tn4$1@news.eclipse.org" type="cite">I
would summarize the algorithm as follows. For an instance of the
unknown type X get eAllSuperTypes and filter out any unknown
types. If we end up with an empty set or a single type we're done.
If we end up with multiple types then we continue to eliminate any
types which are direct or indirect super types of another type in
this set. If we still have more than one type left, we would have
to arbitrate somehow (e.g. call a protected method which by
default throws an exception).
<br>
</blockquote>
If we had two left, but the first had 10 eAllSuperTypes and the
other had none, would we pick the first? Or is a problem whenever
there is super type with a delegate that isn't considered? Of
course we could delegate to more than one, but then we have to deal
with whether it's a problem if we visit the same type more than
once...<br>
<blockquote cite="mid:j3f7cn$tn4$1@news.eclipse.org" type="cite">
<br>
So the default case would still kick in if we don't find any known
super type or if the delegate of the found super type didn't
return anything.
<br>
<br>
--knut
<br>
</blockquote>
</body>
</html>
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Re: [emf] question about ComposedSwitch [message #720043 is a reply to message #720014] |
Mon, 29 August 2011 18:11 |
Knut Wannheden Messages: 298 Registered: July 2009 |
Senior Member |
|
|
Ed,
Comments below.
On 8/29/11 18:51, Ed Merks wrote:
>>> So what's the algorithm? For each Y among X's eSuperTypes, compute the
>>> number of delegates that are available for Y's package, and for the
>>> package of each Z among Y's eAllSuperTypes. Choose the Z with the most
>>> delegates but throw an exception if two have the same number of
>>> delegates. Is that the idea? I'm not sure if the default case ever kicks
>>> in?
>>
>> The discussed algorithm of course only concerns the "else" part of
>> ComposedSwitch#doSwitch(EObject, EClass), where we deal with an
>> "unknown" type.
>
> You mean the if-part, right? (Where it arbitrarily picks the first super
> type.)
>
> @Override
> protected T doSwitch(EClass theEClass, EObject theEObject)
> {
> Switch<T> delegate = findDelegate(theEClass.getEPackage());
> if (delegate == null)
> {
> List<EClass> eSuperTypes = theEClass.getESuperTypes();
> return eSuperTypes.isEmpty() ? defaultCase(theEObject) :
> doSwitch(eSuperTypes.get(0), theEObject);
> }
> else
> {
> T result = delegate.doSwitch(theEClass, theEObject);
> return result == null ? defaultCase(theEObject) : result;
> }
> }
>
Yes, I mean the if-part. I didn't have the code in front of me at the
time of writing. Sorry about the confusion.
>> I would summarize the algorithm as follows. For an instance of the
>> unknown type X get eAllSuperTypes and filter out any unknown types. If
>> we end up with an empty set or a single type we're done. If we end up
>> with multiple types then we continue to eliminate any types which are
>> direct or indirect super types of another type in this set. If we
>> still have more than one type left, we would have to arbitrate somehow
>> (e.g. call a protected method which by default throws an exception).
> If we had two left, but the first had 10 eAllSuperTypes and the other
> had none, would we pick the first? Or is a problem whenever there is
> super type with a delegate that isn't considered? Of course we could
> delegate to more than one, but then we have to deal with whether it's a
> problem if we visit the same type more than once...
I suppose we would have to implement a sensible default for this corner
case. I don't think that delegating more than once is a good idea, as
the return value "null" may be what should be returned. I think it would
be better to either (a) always pick the first type or (b) thrown an
exception indicating the ambiguity. I lean towards (a) but I think this
decision should also be encapsulated in a protected method to give the
developer the chance to override it. This would then also require the
delegatedDoSwitch() method you proposed.
This discussion advanced much further into implementation details than I
thought it would. I take it that means you don't think the idea is
completely bonkers. Should I report an enhancement request for this?
--knut
|
|
|
Goto Forum:
Current Time: Thu Apr 25 22:24:43 GMT 2024
Powered by FUDForum. Page generated in 0.04326 seconds
|