Skip to content

Details ~ Transformation Description

Vlad Ureche edited this page Jun 11, 2015 · 10 revisions

If you haven't read the [[introduction|Tutorial--Introduction]] and [[first example|Tutorial--Example-(Part-1)]] already, it's a good time to do so, as this advanced discussion assumes familiarity with the ildl-plugin.

In this section we will show some tricks for creating transformation objects. There are five sections:

  • Transformation Objects
  • Writing Coercions
  • Handling Generics
  • Intercepting Methods
  • Annotations

All of the API mentioned in this part lives in the ildl-plugin repository, in the components/runtime/src directory. If you have imported the ildl-* projects in the Scala IDE, you can find the classes under the ildl-runtime project, in the src directory.

Transformation Objects

Transformation descriptions have to be objects and need to extend one of the two marker traits:

It is recommended that description objects do not inherit from anything whose members contain either @high or @repr annotations. Currently this is not enforced in the plugin but seeing its dangers, we will soon add checks against it.

Going back to the marker traits, the difference between the two comes from the ability to target generic data types: flexible transformations can target any generic type while rigid transformations can only target monomorphic types.

A note about generics: It is important to distinguish between targeting generics and targeting inside generics. Current ildl transformations can target generic types such as List[T] and use the type parameters in the transformation (e.g. to LazyList[T]) but, under the current generics compilation scheme, they cannot target inside generics, for example targeting BigInt inside List[BigInt]. This is why, in the [[efficient collections|Sample--Efficient-Collections]] benchmark, we had to create two objects: BigIntToLong and QueueOfBigIntToFunnyQueue. This will be discussed [[later|Details--Object-Model]] in detail.

Writing Coercions

Both the TransformationDescription and the RigidTransformationDescription objects have the two toRepr and toHigh coercions:

  • in flexible transformations these can be fully generic, taking as many type parameters as necessary:
object MyFlexibleTransformation extends TransformationDescription {
  def toRepr[T](high: List[T]): Vector[T] @high = high.toVector
  def toHigh[T](repr: Vector[T] @high): List[T] = repr.toList
}
  • in rigid transformations these must not have type parameters and must only convert between the High and Repr types defined in the RigidTransformationDescription:
object MyRigidTransformation extends RigidTransformationDescription {
  type High = List[Int]
  type Repr = Vector[Int]
  def toRepr(high: List[Int]): Vector[Int] @high = high.toVector
  def toHigh(repr: Vector[Int] @high): List[Int] = repr.toList
}

A word of warning in writing coercions: Coercions are automatically considered to be transparent:

  X.toHigh(X.toRepr(obj)) == obj

Not respecting this restriction can lead to incorrect behaviour and loss of data. Furthermore, for mutable collections, where aliasing can occur, or for objects that can be used for synchronization, the following (much stronger) restriction applies:

  X.toHigh(X.toRepr(obj)) eq obj

This ...

From here:

Frog Work Ahead: Some of the pages of this wiki are in flux. If you can't find what you are looking for, please [file a bug](https://github.com/miniboxing/ildl-plugin/issues).
Clone this wiki locally