Suggestion to replace use of generics with inheritence in future RM versions

Greetings,
Looking at the UML page Tom has posted a few minutes ago made me remember something I had in mind for some time.

With hope of avoiding any flame wars and attempts to discuss elegance of various approaches in OO approach, may I suggest that the specs use inheritence instead of generics in the future? This is purely based on the current state of some key technologies.

At the moment XSD has no generics support and Java’s generics (or parameterized types) support has a feature (read: problem) called type erasure.
XSD is the basis for both system to system and tool to tool communication, and that will not change for a significant time. So XSD based marshalling/unmarshalling to code will be reality for a while.

Java is.. well it is Java, and its handling of generics won’t change for at least a few more years. Most uses of the generics seem to use upper bounds for type parameters, so those cases should not be too hard to replace with inheritance with the upper bound as the type of fields that use generics at the moment. For unbounded type parameters (which are rare) we could define some assumed types in the implementing systems and either use an abstract class or find another workaround. That’d be a nice OO practice.

This is a note I wanted to write somewhere. It may cause issues in terms of existing code bases and data, it may not be worth the effort, but in a world where algorithmic stock trading can justify a $1.5 billion cable between London and Tokyo to improve latency by 60ms, I should have the luxury of leaving my mark about this design choice ( http://www.extremetech.com/extreme/122989-1-5-billion-the-cost-of-cutting-london-toyko-latency-by-60ms )

Kind regards
Seref

Hi Seref,

Ruby implementation might be one of the proof for replace of generics.
I had much struggled to implement generics and got the conclusion
that we do not need it. I felt low latency between UK and Japan!
However, inheritance could be harmful, because it has too tight restriction
for changes. Interface would be better.

Cheers,
Shinji(50msec latency)

Shinji KOBAYASHI wrote:

Ruby implementation might be one of the proof for replace of generics.
I had much struggled to implement generics and got the conclusion
that we do not need it.

Ruby doesn't have generics at all, right, Shinji?

There's a comparison of generics and inheritance in an appendix of Bertrand Meyer's "Object Oriented Software Construction", 2nd edition. (http://se.ethz.ch/~meyer/publications/acm/geninh.pdf seems to be the original paper that the appendix is based upon.)

Generics can be simulated in a language with inheritance, but there is a cost:
* Duplication of code.
* Extra verbosity.

I don't want to have either forced upon me. If I'm unfortunately forced to use a language that doesn't support generics, then I can always simulate it the generics with inheritance. But I certainly wouldn't want the specs to be obfuscated by hacks like that, thanks very much :wink:

Peter

Hi Peter,

Shinji KOBAYASHI wrote:

Ruby implementation might be one of the proof for replace of generics.
I had much struggled to implement generics and got the conclusion
that we do not need it.

Ruby doesn't have generics at all, right, Shinji?

It is right. I felt generics is very convenient, when I used Java, such as

Iterator<DvText> it = someRmArrayInstance.iterator()

But I found it must be cut off by 'Occam's razor' in Ruby.

it = some_rm_array.iterator

This code looks curious for Java/Eiffel/C# user who are similar to generics,
but it is enough for encapsulated object instance.
I think this depends on language environment, but nested generics seems
complicated codes for me.

List <Map <Integer, String>>

Generics is useful to declare what instance is, but it breaks encapsulation.
As regards to Bartrand Meyer's paper, 'a good balance' is a good design.

Cheers,
Shinji

Hi all,

Since this discussion is about how to implement things defined on the openEHR specs, I may suggest this is a topic of “implementation technology specification” instead of a “change request” to the specs. I mean, this is one of many things we need to consider when we implement openEHR in a certain technology, and if we can write down all those alternatives for each technology, we could have another layer of specifications, the “ITS for Java|Ruby|.Net”. E.g. HL7 has ITS specs.

Just my 2 cents.

Shinji KOBAYASHI wrote:

Iterator<DvText> it = someRmArrayInstance.iterator()

But I found it must be cut off by 'Occam's razor' in Ruby.

it = some_rm_array.iterator

This code looks curious for Java/Eiffel/C# user who are similar to generics,
but it is enough for encapsulated object instance.

Ruby is a dynamic language, so I guess it would have no need for generics. If you provide a wrongly typed object to a collection in Ruby, I imagine (never having programmed in Ruby myself) that you would find out about the error when you run the program.

Eiffel, C# and Java try to catch errors like that during compilation. Generics is useful for those languages: it tries to keep the extra safety of compile-type checking, while providing some of the flexibility that you get in dynamic languages like Ruby.

In the case of Java, generics don't work very well, as Seref pointed out. The JVM forced the Java designers to adopt a policy of "type erasure". And so, on the one hand, the compiler is less flexible than Eiffel and C#, rejecting a lot of uses of generics that would be permitted in those other languages; and on the other hand, the Java byte code that you finish up running in the JVM contains no info about the generic parameter type.

I'm not clear why the existence of generics in the spec would be a problem for a dynamic language like Ruby.

Peter

Hi Pablo,
I do not want to have a discussion about how to implement specs. That was not my point. Let me try to be more direct:

Generics causes problems during implementation of openEHR if Java or XML is involved. Java + XML has a huge user base. Even XML on its own has a huge user base.
By making a minor change in OO design options, openEHR can eliminate these problems for everyone using Java and especially XML.
This may help openEHR become a spec easier to implement.

This is the point I was trying to make.

I am not sure that this is an argument for removing generics though. Lots of people ‘use’ XML, but they don’t model in it - it is unusable for object-oriented modelling. I think most XML schemas are built as a particular data view of an object model, for a particular kind of communication channel. There are obviously going to be many non-XML communication channels in the future, as there already are inside major orgs like Google and Amazon, where binary messaging is being used. And it’s easy enough to create an XSD from an object model. It’s annoying that XML is too dumb to do things like generics natively, but not the end of the world.

As for Java, I don’t think we should remove the numerous uses of generics in the model due to Java’s poor implementation of them. For example, nearly every LOCATABLE descendant in openEHR (RECORD_COMPONENT descendants in 13606) have some generic declaration, e.g. Cluster.members: List etc. I don’t think creating hardwired classes like ListItem, ListSection, ListEntry, ListParticipation etc is a reasonable option for a clear model.

There are a few instances in openEHR of non-container generics, like DvInterval<T: DvOrdered> and so on. I don’t really think we should compromise the model here either - the specification says exactly the intended semantics, in a clear and comprehensible way.

Instead, I think we should re-invigorate the Java Implementation Technology Spec, that Rong wrote originally some years ago, to provide Java implementation guidance for issues like this. All target implementation technologies have their issues; if we keep hacking the primary specfication model to suit all of them, we will no longer have any clear statement at all of what we really wanted in the first place, and it would in any case probably be a very weak model, once you accommodate no generics, no multiple inheritance, no typing, …!

  • thomas

2012/3/22 Thomas Beale <thomas.beale@oceaninformatics.com>

Instead, I think we should re-invigorate the Java Implementation Technology Spec, that Rong wrote originally some years ago, to provide Java implementation guidance for issues like this. All target implementation technologies have their issues; if we keep hacking the primary specfication model to suit all of them, we will no longer have any clear statement at all of what we really wanted in the first place, and it would in any case probably be a very weak model, once you accommodate no generics, no multiple inheritance, no typing, …!

I was exaclty thinking about this while seeing this proposal for the ITEM_STRUCTURE change to a VALUE_CLUSTER:

http://www.openehr.org/wiki/display/spec/openEHR+2.x+RM+proposals±+lower+information+model#openEHR2.xRMproposals-lowerinformationmodel-CandidateA.1AddVALUECLUSTER%2CRemoveITEMSTRUCTUREtypes

It is an example of multiple inheritance not supported by Java and some other languages. I agree with you that a programming language limitation cannot be imposed to a good model design, but it is also true that for example Java is not a minor language to forget of. There should be a balance between what it is perfectly modelled and what can be implemented by most.

I have workarounds for the generics problems in Java, and I would be more than hapy to contribute them to any doc. I did not know about Rong’s document.

I think I have made my point, whether or not it is a good one is a different issue, but I don’t want it to be read as an open ended suggestion for throwing away good OO features.

Best regards
Seref

yes - I accept that in this case, and would not offer this MI structure as a final proposal - I just did it this way to record the initial idea. The final model should probably be one of:

  • a new sibling of ELEMENT and CLUSTER, called e.g. VALUE_CLUSTER

  • maybe replace ELEMENT and CLUSTER by a new merged class? Although clinical modellers have told me they want sometimes to force just an ELEMENT, no more children in some places.

  • therefore, maybe a modified CLUSTER (with added ‘value’ element), and the existing ELEMENT class. That would mean ITEM now has a ‘value’.

I quite like the last idea… it seems to me to reflect the reality that ‘any cluster could one day require a summarised value on itself’. Time to update the wiki page :wink:

Re multiple inheritance in general, although we have beautiful multiple inheritance in Eiffel (the language we did all the original modelling in, starting from GEHR, but a very minor language these days), we deliberately avoided using it in the openEHR reference model; instead, we limited ourselves to the kind of inheritance supported by Java and C#, i.e. only single inheritance for type substitution. I don’t think this compromise has hurt the models.

  • thomas

I have to say, software development would be absolutely dire from my point of view without one particular generic type: Hash<T, K>. That really would destroy nearly every class I have ever written!

  • thomas
(attachments)

OceanInformaticsl.JPG

it is actually on the normal spec page, see bottom of ‘stable’ specs group (direct link to PDF).

  • thomas

I should have been more specific. Generics in collections is a managable issue :slight_smile: and yes, I would not like to go back to non-generic collections either..

(attachments)

OceanInformaticsl.JPG

Hi Seref,

I understood your point. The fact is that this is a change request to the specs, and IMO things like these could be defined on annexes to the specs, in this case something like “if you are implementing things in Java you’ll have these problems with generics, so you can do things easier implementing the model this way…”.

The problem I see is the specs shouldn’t be changed for a technology issue, or maybe yes, if we consider the 4 or 5 big technologies out there, but not only one.

My point is: I agree with you no making something to simplify the implementation, I don’t agree to do it by changing the model.

David Moner wrote:

I was exaclty thinking about this while seeing this proposal for the ITEM_STRUCTURE change to a VALUE_CLUSTER:

http://www.openehr.org/wiki/display/spec/openEHR+2.x+RM+proposals+-+lower+information+model#openEHR2.xRMproposals-lowerinformationmodel-CandidateA.1AddVALUECLUSTER%2CRemoveITEMSTRUCTUREtypes

It is an example of multiple inheritance not supported by Java and some other languages.

Multiple inheritance is easily implemented in Java and C# ... via interfaces.

The problem is that you often need to duplicate code. For example, in that diagram, VALUE_CLUSTER inherits from both ELEMENT and CLUSTER. In C# you can't do that, so you would probably declare ValueCluster as implementing two interfaces, IElement and ICluster; then you would copy the implementations of Element and Cluster into ValueCluster. Java would do something similar, although the naming convention of the interfaces might be different. (In C#, you might even decide to avoid some of the code duplication by using extension methods. Or maybe not ... it might cause more trouble than it solves.)

Peter

Generally, you can do things in specifications that can't be
reproduced in actual implementations.
Since there is one specification, but many implementations, the list
of things that the specification
contains that aren't easy to implement varies widely between implementations.
The things that are hard to implement are sometimes also very useful
for expressing meaning
and purpose. So a good specification balances between using things
that are useful without
using things that are too hard to use.

With regard to generics, my normal implementation contexts do not
support generics (XML/XSD, old
versions of various languages), but I still find them useful in the
specifications and would prefer
the specification expressed itself cleanly

Grahame

+1 to Grahame comments.

  • Pablo.

I think the topic has drifted slight from Seref’s original issue, although Java nor c# can not implement generics as well as Eiffel or as intended by the spec author it is possible to get close enough to be usable. Similar implementation decisions were necessary when specifying the XML schema and again it is close enough to be usable.
My understanding of Seref’s original issue is the auto generation of Java classes from the XML schema using frameworks like jaxb and .Net. I personally think this is the wrong way around when it comes to the RM classes. I know every developer can do it better than the next but any developer can do it better than a tool. If you are going to invest in implementing openEHR you should take the time to get a good implentation of the building blocks by adopting and contributing to an existing implementation in your preferred language or do it yourself better than everyone else.
Cutting corners by using a tool will result in you throwing away the approach and doing it properly later anyway (been there done that).
The only tool that maybe plausible is an openEHR specific class generator for writing jaxb web services that are driven from AOM, not some generic XML tool that is not designed to handle the genericity and use of abstract types as used in openEHR and not able to be expressed in XML schema.
Ocean has been auto generating template data schema and template data classes for use in working systems for several years, they provide great benefit but need further work to make the generated artifacts simpler, flatter and more usable including with tools such as jaxb and mapforce. We need help to make this happen.
The problem is that everytime we remove complexity we come across a requirement for the complexity and end up with something closer to the RM again.
So yes we need to make the entry point to use openEHR lower, but we do this by comprising the capability of the resulting solution.

Anyway in conclusion I believe we need to keep the RM specs logical, have technical specs for serialisation such as XML and ADL, class implementations in strongly typed OO languages and dynamic languages. Persistence is another technical group of specs. But I think we should not mix serialization with class implematation or persistence, except for stating an anti pattern of using XML tools to generate a class implementation.

Heath

(attachments)

OceanInformaticsl.JPG

yep. Perfectly stated.

(attachments)

OceanInformaticsl.JPG