Posted by & filed under Uncategorized.

Let’s take a look at the following Play! Scala artifacts…

Routes (note the option ‘?’ in the regex)

GET  /contacts/$filter<[a..z]?>  controllers.Contacts.list(filter: Option[String])

Contacts controller

def list(filter: Option[String]) = Action {
  // ...

View template

<a href="@routes.Contacts.list(None)">All</a>
<a href="@routes.Contacts.list(Some("a"))">A</a>


…the reverse routes of the view template are expanded to /contacts/ and /contacts/a.

To get rid…

…of the trailing slash ‘/’ in /contacts/ I chose the following config:

Routes (note the missing option ‘?’ in the regex)

GET  /contacts                  controllers.Contacts.list
GET  /contacts/$filter<[a..z]>  controllers.Contacts.listBy(filter: Option[String])

Contacts controller

def list = listBy(None)

def listBy(filter: Option[String]) = Action {
  // ...

View template

<a href="@routes.Contacts.list">All</a>
<a href="@routes.Contacts.listBy(Some("a"))">A</a>


… results in /contacts and /contacts/a as desired.

Are there better / simpler ways to achieve the same result?

Posted by & filed under Coding.

Extending the functionality of classes is trivial: simply use inheritance and add new methods.

There are cases where extending classes by inheritance is not practicable, e.g. given final classes like java.lang.String.

Another simple way of extending the functionality of classes is applying methods defined somewhere else. Modern languages like Xtend and Scala provide convenient syntax for this:

Posted by & filed under Coding.

A few months ago I saw an impressive presentation of treehugger.js – a handy JavaScript library for representing, analyzing and transforming tree data structures, performing program processing. As a little finger exercise I started to write a similar library for Scala. Here is the first shot:

Posted by & filed under Coding.


A few days ago my companion Hendy Irawan shared with me his thoughts about accelerating the creation of code generators.

The common way of writing a code generator (e.g. based on Xtext) is

  1. Writing a prototype of (parts of) your program.
  2. Identifying the parts of your code to be generated. This leads to the domain, the input for which the generator (function) is defined. Gathering the domain demands some abstraction in most cases.
  3. Creating your domain specific language (dsl), a formal (= computer readable) language which semantically contains the essence of the code to be generated.
  4. Creating generator templates (based on your prototype), which are (more or less) strings with variable parts. The generator interprets an input (= model) which is formulated with the dsl (= meta model) in the way, that variable template parts are substituted with properties of the input.
  5. Writing code (models) based on the dsl and feed your generator with it. The result should look like your prototype.

Refining a code generator means repeating the steps above and typically includes

  • Enhancing the meta model / dsl.
  • Adjusting the models and the generator templates.

The generator has to be run to verify the result.


Initial Situation

There is one special case regarding the refinement of a generator: not touching the dsl and the models. The generated code is only as good as the prototype used to derive the generator templates. Therefor one common use case is refining the prototype and stay with the dsl and models. But stepping through the round-trip mentioned above is kind of cumbersome because it takes a significant amount of time compared to just modify the generated code.



Our question is if it is possible to write a ‘reverse generator’ which merges modified generated code back into existing generator templates. The benefit would be a fast round-trip between generator and generated code.



We can think of (default) generators as projections in a geometric sense. As a (stupid but simple) example, code generation is like a linear transformation of a 2D object (model + templates) to a 1D object (generated code), leaving off one dimension (the knowledge about the model). In other words: the code generator has more detailed knowledge (= greater dimension) about the domain (in a meta sense) than the generated code.

A reverse generator must have the ability to merge generated code back into the templates. Theoretically, the simplest way to achieve this is by augmenting the generated code with extra information about its origin (within a generator template). Then the following conditions have to be satisfied:

  • Informations derived from the model are fixed and should not be touched.
  • Protected regions should not be touched.
  • The remaining generated code has to be sliced and merged back into the template methods where it belongs to.

The first two points are trivial. The last point is the interesting case because one template method is potentially called n times. Having n occurrences of similar code makes it hard to unambiguously map it back to its origin when one or more of the occurrences are modified. This case has to be further investigated…

Posted by & filed under Coding.

Update: Just noticed that I forgot to mention, that the following line has to be added to the main method of project/Build.scala: routesImport += "binders._"

Regarding the previous post, it makes sense to provide a special Enumeration type which is bindable by the Play framework:

Posted by & filed under Coding.

With Play and Scala, type-safe web development is a breeze.

The following example shows how Play parses url paths and derives values of an Scala enumeration. There are two valid url paths: /signup/company and /signup/sales. Other url paths, such as /signup/unknown are properly handled as invalid.

Play handles routes with variable parts like /signup/:account. In our case, it tries to parse the variable part :account to an enumerated type Account.Value, using the function bindableAccount.

The value is passed to the Controller, which passes it directly to the View in this example.

Oh, btw – links to these urls are type-safe, too: href="@routes.SignUp.form(Account.Company)"