Chapter 1. Introduction to the language

This chapter aims to help you to have a quick overview of most of the features of Kermeta. Then, it gives the pointers to the detailed sections in the reference chapter. It also gives some small examples that should help you to understand the basis of the concepts without having to jump to the corresponding detailed section.

1.1. Presentation

Kermeta is a metamodeling language which allows describing both the structure and the behavior of models. It has been designed to be compliant with the OMG metamodeling language EMOF (part of the MOF 2.0 specification) and Ecore (from Eclipse). It provides an action language for specifying the behavior of models.

Kermeta is intended to be used as the core language of a model oriented platform. It has been designed to be a common basis to implement Metadata languages, action languages, constraint languages or transformation language.

Kermeta positioning

Figure 1.1. Kermeta positioning


In a nutshell, Kermeta is :

  • MOF compliant (EMOF compliant to be precise)

  • Model oriented

  • Imperative

  • Object-Oriented

  • Aspect-Oriented

  • Statically Typed (100% typesafe)

In addition to these characteristics, it includes some typically model-oriented concepts like associations, multiplicities or object containment management.

This chapter presents the main features of the Kermeta language. Section 2 presents the general syntax of the language, sections 3 & 4 give details about the object-oriented and model-oriented features of the language and finally section 4 provides information about some extra concepts in Kermeta (including aspect orientation).

With its workbench, it's goal is to provide a support for all Language Driven Engineering activities. It will be typically used to build tools useful to build software. This includes (but is not restricted to): model checkers, simulators, model transformations (any kind of transformations including model weavers or compilers).

1.2. An imperative syntax

Kermeta is an imperative language for modeling, with a basic syntax inspired from Eiffel. Code is statically type checked, and execution is made by an interpreter (a compiler is on the way, for exhausted performances).

1.2.1. First Program

Even if it is not very useful in our context, since it doesn't show the really interresting structures of the language, here is the traditional " Hello world " example you can find in every programming book.

@mainClass "helloworld::HelloworldExample"
@mainOperation "sayHello"
package helloworld;

require kermeta
using kermeta::standard

class HelloworldExample
{
    operation sayHello() is
    do
        stdio.writeln("Hello world, ...")
    end
}

1.2.2. Classic features

Kermeta language includes usual statements like blocks and loops, comments, etc

do
    // a loop for getting a text from an user
    var s : kermeta::standard::String
    from var found : kermeta::standard::Boolean init false
    until found
    loop
        s := stdio.read("Enter a text:\n --> ")
        if s.size > 0 then
            found := true
        else
            stdio.writeln("ERROR - Empty text!")
        end
    end
    stdio.writeln("\n You entered: " + s)
end

1.2.3. Corresponding sections in the Reference chapter

All these "classic" imperative features and their syntaxes are described in Chapter 2, Reference. More precisely in

1.3. An object-oriented language

Users of modern programming languages, like Java, would feel easy with object-oriented features in Kermeta: classes, inheritance, exceptions, and even genericity.

require "truc"
// persons who write documents
class Writer {
    attribute name : kermeta::standard::String
}

// generic concept for every document
abstract class Document {
    reference author : Writer
    attribute text : kermeta::standard::String
}

// a "Document" from the real world
class Book inherits Document {}

// a specialized "Book"
class ChildBook inherits Book {
    attribute minimalAge : kermeta::standard::Integer
}

Such classes can be used for verifications:

// a specialized Exception
class AgeException inherits kermeta::exceptions::Exception {}

abstract class Reader {
    operation read(book : ChildBook) : Void is abstract
}

class Child inherits Reader {
    attribute age :  kermeta::standard::Integer
    operation initialize(age :  kermeta::standard::Integer) : Child is
    do
        self.age := age
        result := self // return self so we can chain this call directly after a new
    end
    // an action which triggers an Exception
    operation read(book : ChildBook) : Void is
    do
        if age < book.minimalAge then
            raise AgeException.new
        end
    end
}

1.4. A model-oriented language

As explained in the Preface and in Architecture, Kermeta extends the MOF. It provides useful means to manipulate models. The support of model introduces the main difference with "more" traditional programming languages.

1.4.1. Associations : toward a first concrete example of a Kermeta model

Association is one of the key concepts when using and defining models. It is obviously part of Kermeta.

MOF defines the concept of "Property" which generalizes the notions of attributes, and associations (composite or not) that you can find in UML. Kermeta syntax also distinguishes these two notions as introduced in Section 2.15, “Class properties”.

As a reminder, the attribute keyword defines a link with containment (a composite association) whereas the reference keyword just defines an association. As you can see, property declarations are very close to variable declarations introduced in Section 2.6, “Using Variables”). Each reference may be explicitly linked to another reference (it is the opposite concept in MOF terminology – see also section Section 2.15.1, “Attributes (attribute), references (reference) ”).

class Library
{
    attribute books : set Book[0..*]
}

class Book
{
    attribute title : String
    attribute subtitle : String

    reference authors : oset Author[1..*]#works
}


class Author
{
    attribute name : String
    attribute lastName : String
    
    reference works : set Book[0..*]#authors
}

If we represent our Kermeta model in a graphical syntax we obtain the following class diagram (Figure 1.2, “A concrete example : a library”).

A concrete example : a library

Figure 1.2. A concrete example : a library


1.4.2. Loading an existing model

Using Eclipse Modeling Framework (EMF), Kermeta can load and save models done with other EMF tools.

/* Initialize the EMF repository */
var repository : EMFRepository init EMFRepository.new

/* Create an EMF Resource, given model and metamodel URIs as String */
var resource : Resource init repository.createResource(myModelURI, itsMetamodelURI)

/* Load the resource */
resource.load

// get elements from the resource
// in this sample, you know that your root element is always a Library, 
// so you can directly get the first one
var aLibrary : Libray
aLibrary ?= resource.one // note the conditional assignment using the ?=, if not a Library you'll get Void

In the same way, you can serialize a model, or load, change and save an existing model.

[Caution]Caution

Your model URI MUST be of the form "platform:/resource/myProject/myModel" or "platform:/plugin/myProject/myModel".

Your metamodel URI MUST be of the form "platform:/resource/myProject/myModel" or "platform:/plugin/myProject/myModel" or an URI registered in the EMF registry.

[Caution]Caution

Be aware that you CANNOT load kermeta text files (*.kmt). Only xmi files are allowed to be loaded. Parsing and obtaining a model from a textual syntax is not part of Kermeta. This is the role of other tools (like sintaks). Technically, it is possible to create some Kermeta operation that will hide this step, however, this is not the goal of this manual to explain this procedure.

1.4.3. Navigation in a model

Actually, navigating in a model is as simple as using objects in an object-oriented program. However, several features have been added in order to ease this activity.

For example, thanks to the lambda expressions, the collections of the language are easily manipulated using lexical closure (select, collect, each, etc). This applies to all the collections of the language, the one you may define directly but also the one which are used when an Attribute or Reference has a multiplicity greater than 1.

Example (based on the library sample of Section 1.4.1, “Associations : toward a first concrete example of a Kermeta model”):

var smithBooks : Set<Book> init Set<Book>.new
smithBooks.addAll(
	lib.books.select{aLibraryBook | 
		aLibraryBook.authors.exists{aBookAuthor | aBookAuthor.lastName == "Smith"}})
		

In the example above, lib is an instance of Library. It searchs in the books, select the books where the author last name is "Smith".

1.4.4. Model type

In order to improve reuse of existing code between metamodel variants, the language introduces the notion of ModelType. It is based on the notion of conformance between two metamodels. This allows to write behavior that is valid for a given metamodel and that will also work for any conformant metamodel.

TODO write a small illustrative example of a simple printer based on a ModelType : a subset of class diagram of UML

1.4.5. Kermeta model reflexively available

Kermeta has been developed, using MDE principles so it also provides its own metamodel (reflectiveley available). Details of Kermeta metamodel is available in Chapter 3, Kermeta Metamodel

1.4.6. Corresponding sections in the Reference chapter

You can get more informations about all Kermeta model-oriented features in the Chapter 2, Reference. More precisely in

1.5. Aspect-oriented language

Since Kermeta is an extension of MOF, a MOF meta-model can conversely be seen as a valid Kermeta program that just declares packages, classes and so on but does nothing. Kermeta can then be used to breath life into this meta-model by incrementally introducing aspects for handling concerns of static semantics, dynamic semantics, or model transformations.

One of the key features of Kermeta is the static composition operator require allows extending an existing meta-model with new elements such as properties, operations, constraints or classes. This operator allows defining these various aspects in separate units and integrating them automatically into the meta-model. The composition is done statically and the composed model is typed-checked to ensure the safe integration of all units. This mechanism makes it easy to reuse existing meta-models or to split meta-models into reusable pieces. It can be compared to the open class paradigm. Consequently a meta-class that identifies a domain concept can be extended without editing the meta-model directly. Open classes in Kermeta are used to organize cross-cutting concerns separately from the meta-model to which they belong, a key feature of aspect-oriented programming. With this mechanism, Kermeta can support the addition of new meta-class, new subclasses, new methods, new properties, new contracts to existing meta-model. The require mechanism also provides flexibility. For example, several operational semantics could be defined in separate units for a single meta-model and then alternatively composed depending on particular needs. This is the case for instance in the UML meta-model when several semantics variation points are defined.

Thank to this composition operator, Kermeta can remain a kernel platform to safely integrate all the concerns around a meta-model. This feature has proved to be extreemly useful in the context of metamodel engineering.

1.5.1. Corresponding section in the Reference chapter

You'll find more details in the Reference chapter, more precisely in: Section 2.20, “Weaving Kermeta code”

1.6. Some "advanced" features

Kermeta implements several "less common" or advanced features that helps in many situations.

Typically, lambda expressions/functions is a well known concept, very useful in almost all kermeta code. Even, if you will probably not write your own function, you'll certainly use the existing one defined on collections.

1.6.1. Functions in Kermeta

In order to implement and statically type check OCL-like iterators, Kermeta includes some limited functional features by implementing lambda expressions.

This is typically used on Collection which provides functions like : each, select, forAll, detect, ...

Example 1: the following code will build a collection of names of the operations that start with "test".

var names : Collection<String>
names := self.getMetaClass.classDefinition.ownedOperation
            .select{ op | op.name.indexOf("test") == 0}
            .collect{ op | op.name }
	    

Example 2: Providing a time function on Integer

operation times(body : <Integer->Object>) : Void is do
    from var i : Integer init 0
    until i == self
    loop
        body(i)
        i := i + 1
    end
end

this allows to write code like :

var res : Integer
10.times { i | stdio.writeln(i.toString + ": Hello") } // Say 10 times Hello

See sections "Lambda Expressions and functions" and Lambda Expression for detailed informations.

1.6.2. Other advanced features

1.6.2.1. High level modeling

Kermeta most recent versions embed advanced concepts like Lambda Expressions and functions, Dynamic evaluation of Kermeta expressions, Design by contract (pre, post, inv contraints) or Weaving Kermeta code.

1.6.2.2. Other technical features

As Kermeta language is implemented upon Eclipse and Java, you can call Java code inside Kermeta code.(see Section 2.22, “Using existing java code in Kermeta”)

There is some special behavior regarding object comparison or cloning.