Semantic typing in domain-specific languages

In domain-specific languages (DSL) concepts of the targeted problem-domain are introduced as language constructs. This is done in order to model using these concepts and abstract from specific technical solutions. However, a static typing of the DSL is useful, especially when it is used to calculate values. In DSLs the typesystem can be designed individually just as all the provided language constructs. For this reason, the data types shouldn’t be introduced because of technical differences but because of their semantics in the problem domain. Such semantic type systems and a static typing of a DSLs can prevent semantic errors during modeling by checking for type incompatibilities. This article discusses the idea of semantic typing and shows a concrete implementation in a DSL for creating user interfaces.



Background

In programming languages the data type defines the value range and the operations available on a data value. Typing assures that no semantic or syntactically errorneous operations are performed.

Most programming languages come with a set of predefined data types, that are either elementary or composite data types. The latter are compositions of elementary data types. Usually the users of the language can create their own composite data types. In some programming languages they can also overload or assign alternative names for existing data types. However, the basic set of elementary data types is fixed.



Static and dynamic typing

Depending on the point in time a data type is known and the type checks are performed one can distinguish between static and dynamic typing:


  • In dynamically typed programming languages the data types are unknwon before runtime which allows for very compact code. However, using incompatible datatypes lead to runtime errors. Dynamic typing is used in the programming languages such as Python, LUA and PHP.

  • In programming languages that apply static typing the datatype is known during compilation. This enables the compiler to check for type incompatibilities. The information about the data types is also used to create optimized object-code that allows for more efficient operations and calls at runtime. Because no type information is required any longer after the compilation it can be dropped to prevent runtime overhead. Popular examples for statically typed languages are C and Java.



Typing in internal and external DSLs

According to Stahl [5] DSL can be subdivided into internal and external DSLs. The latter are developed from scratch. Internal DSL, on the other hand, are embedded into an existing programming languages such as Ruby and LISP that provide suitable mechanism for adaptations. They are described using means of this host language and use their lexer and parsers. Thus, they are a subset of the host language are therefore restricted in their expressiveness. Internal DSLs also use the type system of the host language and its capabilities. In external DSLs the type system has to be explicitely designed.

The typesystem of such an external DSL can be designed according to individual requirements. In this process the available data types as well as the style of typing has to be defined. In DSLs the same advantages and disadvantages of static and dynamic typing apply just as in regular programming languages. In statically typed DSLs type incompatibilities can be checked during editing. This allows to detect errorneous models in a very early stage which can improve productivity.



Semantic type systems

In DSL design language constructs aren’t introduced because of technical differences in the solution domain but because of their domain specific semantics. This approach can also be applied when designing the type systems of a DSL: data types should be distinguishable because of their domain specific meaning in the problem domain. The data type can be used to define properties of data such as the owner or the validity date. The data type can also define the physical unit of a value. A angular value can be of a different data type depending on whether the value is in degree or radian, a temperature value can be one of the data types degree celsius, degree kelvin or degree fahrenheit.

In such a case the domain specific meaning of a value is expressed in its data type. In this article we call this semantic data type.



Using the type information

In programming languages with expressive type systems this can be used to specify properties of the programm and verigy them automatically [3]. In object oriented programming objects and classes are introduced as representatives of real-world elements. Whether an operation is suitable on such an element can be explicitely defined by the selected data types and can be checked by type compatibility.

However, object oriented programming concepts are not used in DSLs because of their complexity. Nevertheless, simple semantic type systems can be used to assure correctness in target domain by type compatibility. Hördegen shows this approach in an internal DSL based Haskell, a statically typed functional language. His example uses type checking and type inference for checking of semantical correctness [3].

This article extends Hördegens approach and applies it to an external DSL. It is also shown how a type system of such a DSL can be designed by an example. This type system allows the users of the DSL to introduce data types for domain concepts. Using the type information errors can be detected during modeling by type incompatibilities. This, for instance, enables to prohibit expressions that mix up different units like add a temperature value in degree fahrenheit with another value in degree kelvin. Furthermore, the knowledge about the different types can also be used to call a suitable unit conversion operation in the generated code before performing the addition.



Example of a semantically typed external DSL

HMISL is a Xtext-based textual DSL for modeling the bahaviour logik of user interfaces for in-car infotainment systems [1]. The DSL is statically typed and its type system was implemented using Völter’s Xtext-typesystem [6].

In the HMISL the bahaviour logik is modelled as state dependent reaction to asynchronous events such as user interactions or value changes. In earlier versions of the HMISL the reaction to the events was expressed in the embedded programming language LUA, which is dynamically typed [4]. From the HMISL models code for a Java-framework was generated that runs the LUA fragments using a JVM-based LUA interpreter. However, using LUA in the context of the statically typed HMISL repetitively gave rise to errors due to usage of wrong types. Such errors were found hard to detect before they lead to acutal runtime errors in the LUA interpreter. Because two different languages were used error were hard to find in the generated code.

The recent version of the HMISL [2] don’t uses LUA as embedded programming language any longer. Instead of that, it now uses a proprietary micro language, which posses a C-like syntax. This allowed a consistent strong static typing.

In order to achieve a broad applicability of HMISL the typesystem is not fixed but can be adapted by the users. They are able to introduce their own semantic type system without changing the DSL definition. All available semantic types are defined in a preamble. For each type one has to define which technical data type it is based on. Those technical data types are statically predefined in the DSL (fixed point value, floating point value, boolean value, text). For each semantic data type the value range of the technical data type can be further restricted. This is done by defining an expression in the micro language that evaluates to true for each valid value (constraint). The HMISL code generator can be configured to include a call to an evaluation function in the generated code for each assignment to a value of the semantic type. In order to check whether the value that is about to be assigned is valid in terms of the semantic data type the evaluation function applies the constraint.

Furthermore users can provide data type conversion functions between different semantic data types. Such data type conversions can be accessed in the HMISL’s micro language by using the “as”-operator. In the generated code the corresponding conversion function from the source data type to the target data type is called. After that the evaluation function is called to check whether the converted value is valid in terms of the target data type. The user is displayed an error when the “as”-operator is used but no corresponding conversion function is defined.

Again, the statically typed micro language is used to express the data type conversion function. In order not to run into typing errors all the mathematical operators in the micro language are defined on the technical data types. Furthermore, each semantic data type can be converted into its technical data type even without having to define an respective conversion function.

The code snippet in Listing 1 shows an example of a semantic type system declaration in the HMISL. This type system includes three different semantic types for temperature in degree Fahrenheit, Celsius and Kelvin whereas each of these is based on the technical data type floating point number. Conversion functions between each of these types are also defined.

configuration TemperatureTypes {...
	type DegreeFahrenheit is real {
		valid {return value >= −459.67;}
		to DegreeKelvin {return (value+459.67)*5⁄9;}
		to DegreeCelsius {return (value-32)*5⁄9;}
	}
	type DegreeCelsius is real {
		valid {return value >= -273.15;}
		to DegreeFahrenheit {return value*9/5+32;}
		to DegreeKelvin {return value+273.15;}
	}
	type DegreeKelvin is real {
		valid {return value >= 0;}
		to DegreeCelsius {return value-273.15;}
		to DegreeFahrenheit{return value*9/5−459.67;}
	}
}
Listing 1 – Type declaration in the HMISL preamble



The code example in Listing 2 shows value calculation and data type conversion in the HMISL’s micro language using these semantic types. The checks for type compatibility is performed at modeling time and lead to the shown results.

hmisl TemperatureTypes; // Include typesystem
...
DegreeCelsius meltingPointC;
DegreeFahrenheit meltingPointF;
DegreeKelvin meltingPointK;

meltingPointC = 0.0 as DegreeCelsius; // OK
meltingPointF = meltingPointCelsius; // Error – incompatible types
meltingPointF = meltingPointCelsius as DegreeFahrenheit; // OK, will call automatic conversion 
meltingPointK = -1.0 as DegreeKelvin; // Error – incompatible value
meltingPointK = (0.0 as DegreeCelsius) as DegreeKelvin; // OK

// Ausgabe: Ice melts at 0°C = 273.15°K = 32°F
log "Ice melts at "..meltingPointC.."°C = "..meltingPointK.."°K = "..meltingPointF.."°F";

// Operation on technical data type that will lead subsequently to a call of the evaluation function
DegreeCelsius boilingPointC = (meltingPointC as real + 100) as DegreeCelsius;

// Output: Water boils at 100°C
log "Water boils at ".. boilingPointC.."°C";
Listing 2 – Data type checks in the HMISL



Conclusion

When using semantic data types in statically typed DSLs changes to the meaning of a value need to be expressed explicitely by type conversions. Missing type conversions indicate semantic errors which can be detected during modeling by type incompatibilities. Knowing the data type of a value also enables to autoamtically add calls to suitable conversion operations and checks for exceedance of the valid data range in the generated code.

In model-driven development of user interface the concept of semantic typing proved to be beneficial to operate on values that can be expressed in different unit.



Literature

  1. Gerlach, Simon (2011): Ergänzung vorhandener GUI-Modellierungswerkzeuge zur vollständig modellbasierten Entwicklung von Automotive-HMIs. In: Hans-Ulrich Heiß, Peter Pepper, Holger Schlingloff und Jörg Schneider (Hg.): INFORMATIK 2011. Proceedings of 41th annual conference of the Gesellschaft für Informatik e.V. (GI). INFORMATIK. Berlin, 10/4-10/7/2011. Gesellschaft für Informatik. Bonn: Gesellschaft für Informatik (Lecture Notes in Informatics (LNI), P-192), P. 293.
  2. Gerlach, Simon (2011): The HMISL language for modeling HMI product lines. In: Andreas Riener (Hg.): Third International Conference on Automotive User Interfaces and Interactive Vehicular Applications. Adjunct Proceedings. AutomotiveUI. Salzburg, 11/29-12/02/2011. ICT&S Center, University of Salzburg, P. 15–16.

  3. Hördegen, Heinrich: Eine Embedded-DSL in Haskell. Starke Typen. In: iX (7), 2011, S. 110–114.
  4. Ierusalimschy, R.: Programming in Lua (second edition). Lua.org, 2006.

  5. Stahl, Thomas; Bettin, Jorn: Modellgetriebene Softwareentwicklung. Techniken, Engineering, Management. 2. Auflage. Heidelberg: dpunkt.verlag, 2007.

  6. Völter, Markus: Xtext-Typesystem Framework. voelterblog. 24. August 2010, 2010.

  7. Völter, Markus: MD*/DSL Best Practices. März 2011, 2011.

Advertisements
  1. You may want to try this as well http://xsemantics.sourceforge.net/ for implementing type systems (both static and dynamic) for Xtext languages

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: