I try to specify in Ocaml a model initially expressed in UML, with some classes and the associations between them.
Important:
I’m talking about the metamodel level (and meta meta model level, for which is the same mechanism). This means that these class and association constructs are used to define a model such as UML which acts as a metamodel, then allows to create a model.
I’m no more a totally beginner in OCaml programming, but I’m also far from being an OCaml expert. So pls. apologize my mistakes.
Well, I’m stuck in the middle with that.
I will start with a quite simple question: how to simply represent Uml classes and especially the Uml associations in OCaml?
First, let’s try to mimic in OCaml an UML class+association model.
Basically, we have the Module and the Object systems for that.
1/ Class
An Uml class has a name, some (0…n) attributes (which have a type) and some (0…n) operations (which have a signature). And also relations with other classes (moreover, a navigation can be defined between 2 classes : zero, one or two directions).
With the OCaml Object system I think I can directly represent a class (name, type, methods) and I’m done. I can then instantiate objects. But I’m stuck at a class/object level which is not what I look for.
class umlClass =
object
val mutable name = "Class"
val mutable att1 = "Attribute1"
method get_name = name
method set_name str= name <- str
method get_att1= att1
method set_att1 str = att1 <- str
(* etc. *)
end
With the module system, it seems easy. At first sight.
A record type seems to be a relevant construct for holding class name class attributes:
module FooClass =
struct
type t = {mutable classname : string ;
mutable att1 : string ;
mutable att2 : string;
}
let get_name c = c.classname
(* Uh-uh! It looks like this is a module that denotes an object but not a class *)
let ope1 c a1 a2 = a1 + a2 (* becoming weird... (thinking of a module as a class) *)
end
But in fact this module dos not represent a class: it represents a concrete object.
So the module system seems not adapted to that.
2/ Association between several "classes"
The general case in a n-ary association between some classes.
A binary association is a particular case. It can also be typed as an aggregation (a car has one engine and four wheels) or composition (a man has two hands).
Moreover, any association can be typed to describe its multiplicity (how many times an instance of a class is involved in this association, the role of a class in the association, and the navigability (“which class sees which classes”).
In the documentation of the Object system of OCaml, I see many interesting constructs for OOP: inheritance, multiple inheritance, polymorphic methods, etc. But I don’t see any construct for representing an association between some classes.
So I would naturally try to define tuples or record within the type of a class to create typed associations with other classes. It will certainly work but it looks a bit like reinventing the wheel.
In OCaml, what is the recommended way to represent (typed) associations between classes in OCaml? (that become links between instantiated objects)
Meta metamodel level
The meta metamodel is (mainly) based on a class and association. It can then be used to describe some UML-like models that will act as a metamodel (e.g. instead of simply having the classes Person and Car, and an association between Person and Car, we’ll have all classes stereotyped as “nice” or “bad” and associations stereotyped as “safe” or “unsafe”. Very simplified and inaccurate example).
Here is the problem I encounter when trying to manipulate classes and associations at the meta metamodel level in order to define a metamodel:
When specifying a model in OCaml, I can use concrete types:
...
type t = {mutable classname : string }
let get_name c param= "Bla " ^ c.classname ^ param
...
But when coming to write a metaclass, I see no solution in Ocaml with the module system (I don’t say there are no solutions). I just believe I’m reinventing metamodeling tooling.
If I use the Object system, maybe I can define a class at meta metamodel level) with meta description (ownedElement, ownedEnd, packagedElement, etc…) of all structural features of such a class: class name, attribute names and types, operation names and types.
Meta names for (metameta)Class, (metameta)Attribute and (metameta)Operation can all be defined so their instances (and their own instances) have name with string type.
But how can I define the type of (metameta)Attribute so that its instances can have a type so its own instances have any valid OCaml type?
And how can I define the type of a (metameta)Operation so its instances can have a type so its own instances have any valid OCaml function type?
I have an idea for expressing these abstract types with symbols then using pattern matching for instantiating a class from the metaClass.
But it looks like I would reinvent the wheel. And I feel that I’m doing the same job as the OCaml type system.
How can we handle that meta considerations when programming with OCaml?
Can the type system be used/hacked to do this meta modeling job?
(*
Some example stuff to come here.
*)