Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [m2t-dev] [backend] bugs and thoughts

Laurent,

after looking at the Acceleo documentation, I would like to discuss a different approach to mapping ENode etc. to the backend with you.

It appears to me that ENode is not really a type but rather a set of infrastructure operations that can be applied to any object, i.e. a library. It looks like you could create an Acceleo specific library with functions operating on "Object".

What problems do you see with this approach?

- Arno

Laurent Goubet schrieb:
Arno,

Comments below.
I must admit I don't get your last suggestion quite well. As for the first, this seems promising, something like a "convert" method on the interface BackendType which would allow us to tell the backend how to effectively convert objects of a given type to (and from) ours would likely be enough for most conversion needs.

I get the idea. I spent some time thinking this through. Before I explain my thoughts, could you give me a practical example of what you would want to use the feature for? Is that something that could be done by subtyping one of the built-in types?

I see three potential ways to supplement BackendType:

* add "convert from" functionality, i.e. allow a type to provide implicit conversions *to* it.

* add "convert to" functionality, i.e. allow a type to provide implicit conversions *to* it.

* add both of the above.

Either of the first two is insufficient to implement full assignment compatibility of a newly created type with one of the built-in ones - the built-in type would not be modified, and one of the two directions of conversion would be barred.

The third alternative introduces redundancy and therefore potential for inconsistencies.

Which would you prefer? What are your thoughts?

And anyway, would you care to point me to some material about your type system etc.? That would be helpful reading to understand and anticipate your future needs.

There are strong consequences for implementation and performance, but I will elaborate on these when I have your response.

Among those three possibilities you give, the third is the one that suits my needs. The example I took when first submitting this request is really close to my actual need, I'll elaborate on this from the beginning ;).

The language I am testing the backend with is Acceleo (http://www.acceleo.org). This language appears to the user as weakly typed since everything is transparently converted to Acceleo-specific types : ENode for regular Objects (String, Integers, Long, ...) and ENodeList for Collections (ENodeList containing only ENodes). Let's take a look at a random Acceleo script :

<%script type="EClass" name="getName"%>
<%name%>

What does this script mean? It defines a "method" /getName/ that can be called on objects of type "EClass". This could be translated in Java as a method (this also demonstrate the need we have for an expression "InvokeOnWhatever" that could seek for a class member instead of a method) :

public String getName(EClass clazz) {
final EStructuralFeature feature = clazz.eClass().getEStructuralFeature("name");
   return clazz.eGet(feature);
}

Please note that this is a totally dummy translation, I simply put it that way so that you can see a little better without knowing Acceleo. Regardless of the script's signification, what Acceleo sees "behind the scene" is not an EClass, but an ENode wrapped around an EClass. This allows for interesting use cases, but this isn't the issue here. When using this with the backend, I must have it know that a function defined with a parameter of type "ENodeType" (a backend type I have defined for the ENodes) *can be called *with parameters of type "LongType", "StringType", "EObjectType", ...

For such use cases, both methods "convertTo(Object o)" and "convertFrom(Object o)" are mandatory for the backend (I have called my function, it returns an ENode, I need to convert it back to a primitive type).

I don't know if this little example is enough for you to see the need behind that suggestion of type converters, maybe you could take a look at Acceleo when you have some time.
I wound up defining an IntegerType, the syslib's functions for it as well as modifying the LongType to allow assignment-compatibility from Integer on it so that I could test the backend further... this will obviously be a blocking issue for us, is there any plans from your side to create the missing primitives (int, float, char, ...)? I think this would also maker the JavaBuiltinConverterFactory obsolete.

It was a conscious design decision to provide only Long and Double as numerical types. This was done in part to be compatible to OCL which (AFAIK ;-) ) has only these two types.

I see no real problem with adding support for all Java types. But I am curious - could you explain the context for which you need these things?

Well I need IntegerTypes in order not to have to explicitely convert every int or Integer I get as parameters or return types for my methods to long. For the example I took, let's say I have to convert "if (1 + 1 == 2) { ... }" to the backend. I need to call the syslib's "operatorPlus" and "operatorEqual" functions. If I do "as is", I will wind up with the temporary expression "if (11 == 2)" since String concatenation will be called instead of operatorPlus on longs (with something like /InvokeOnWhateverExpression("operatorPlus", [1, 1], sourcePos)/) and the subsequent "operatorEqual" will return false.

We then need to convert the parameters to long in order to have the expected result of "1 + 1". These syslib functions are not the only ones presenting the issue, I -let alone the users- use "int" parameters *way* more than I use long. I simply don't want to have these explicit conversions to handle each time I want to use primitive types (be it for a parameter or a return type). I explained in the previous mail that I ended up defining an IntegerType; I told it would be a blocking issue for us since this forces us to patch the backend in order to remove the JavaBuiltinConverter you use to convert int to long.

Another option would of course be for you to use these builtin converters every time you see an integer, but I think this would be an issue for performances as well (these conversions are currently not carried on when searching for a function which could be called with given parameters in the PolymorphicResolver).
Thanks for your efforts!

- Arno

Thanks for your reactivity

Laurent Goubet
Obeo


--
Arno Haase
Langemarckstr. 16
53227 Bonn

Mobil: +49 160 98525085
Tel:   +49 228 9654443
Fax:   +49 228 9654448

Attachment: signature.asc
Description: OpenPGP digital signature


Back to the top