generate Haskell code from model

Hello everybody, I would like to start a discussion on how to generate best-practice Haskell code from a model, e.g. from EMF. It seems to be very difficult and unconvenient to simulate OOP with Haskell (as described in the paper "Object-oriented style overloading for Haskell"). However, I think it might be possible to generate "something useful" out of a model to not start from scratch an implementation. For example, I could imagine to generate for every class a module, import and export lists and a type class (with some restrictions) at the very least. In the EMF book there is an example, PurchaseOrder, look at http://www.awprofessional.com/content/images/0131425420/samplechapter/budins... at page 11. How would you like generated code from this model to look like? The most obvious way would be something like this: data PurchaseOrder = PurchaseOrder {shipTo::String, billTo:: String, items::[Item]} data Item = Item {productName::String, quantity::Int, price::Float} This does not work well if function names are reused or inheritance comes into play, however, even this might be a useful starting point (better than nothing). The benefits of the model+generate approach are well known. Best practices in programming are propagated, for Haskell e.g. use different modules for different things, use the tedious import/export lists, Haddock your code... What are your ideas? Best regards, Steffen -- Dipl.-Inform. Steffen Mazanek Institut für Softwaretechnologie Fakultät Informatik Universität der Bundeswehr München 85577 Neubiberg Tel: +49 (0)89 6004-2505 Fax: +49 (0)89 6004-4447 E-Mail: steffen.mazanek@unibw.de

On 4/13/07, Steffen Mazanek
Hello everybody,
I would like to start a discussion on how to generate best-practice Haskell code from a model, e.g. from EMF.
I started learning Haskell precisely to solve problems like this. But, once I got into it, I realized that Haskell is a much better modeling language than the modeling language I was using (MOF/UML, the predecessors to EMF). Furthermore, all the infrastructure built on top of that modeling language was very easy to replace with Haskell code. As a result, I gave up that effort. You said "The benefits of the model+generate approach are well known," however I disagree. W3C DOM, MOF, UML, CORBA, and NetBeans 3.x-4.x are all obvious examples of the failure of the model+generate approach. If the modeling language is sufficiently powerful, then it should be feasible to execute the models directly using a (custom-built) interpreter. If the modeling language is weak then it is better to just do the modeling in Haskell or another more powerful language. The MDA idea was that you would have one model and then be able to use that model in a variety of different programming languages, without having to rewrite code in each target language. Now, people are getting this benefit via a "code, then translate" approach. For example, GWT allows the developer to write Java code, then generate the equivalent Javascript, without any hand-wavy models in between. JRuby lets one write code in Ruby to be used by code in Java; IronPython does the same for other .NET languages. In fact, C# is basically the .NET counterpart to EMF. FWIW, I also think that data based languages like ERD, Relax NG, and XQuery/XPath/XML Schema are a much closer fit to Haskell than EMF. EMF is designed to be translated any object-oriented, class-based, (soley) subtype-polymorphic, single-dispatched, single-inheritance language; i.e. Java. In fact, EMF is really a Java-optimized subset of what was supposed to become part of MOF 2.0. - Brian

Brian, but don't you think that you have to write a lot
of boilerplate code in Haskell?
Second, if Haskell should be more successful in the
real world there has to be a way of demonstrating
basic ideas of a big program to "customers". How
would you do this? Everybody knows UML class
diagrams, for example. In contrast, nobody knows
about termgraphs or lambda *g*.
Third, assume you already have a model, want to
write the corresponding code yourself?
Thank you very much for contributing to the discussion.
Please assume, that you have to generate the code from
a model. Further assume, that you have no choice and
are not allowed to discuss the sense of this approach :-)
How should the code look like?
Best regards,
Steffen
2007/4/13, Brian Smith
On 4/13/07, Steffen Mazanek
wrote: Hello everybody,
I would like to start a discussion on how to generate best-practice Haskell code from a model, e.g. from EMF.
I started learning Haskell precisely to solve problems like this. But, once I got into it, I realized that Haskell is a much better modeling language than the modeling language I was using (MOF/UML, the predecessors to EMF). Furthermore, all the infrastructure built on top of that modeling language was very easy to replace with Haskell code. As a result, I gave up that effort.
You said "The benefits of the model+generate approach are well known," however I disagree. W3C DOM, MOF, UML, CORBA, and NetBeans 3.x-4.x are all obvious examples of the failure of the model+generate approach. If the modeling language is sufficiently powerful, then it should be feasible to execute the models directly using a (custom-built) interpreter. If the modeling language is weak then it is better to just do the modeling in Haskell or another more powerful language.
The MDA idea was that you would have one model and then be able to use that model in a variety of different programming languages, without having to rewrite code in each target language. Now, people are getting this benefit via a "code, then translate" approach. For example, GWT allows the developer to write Java code, then generate the equivalent Javascript, without any hand-wavy models in between. JRuby lets one write code in Ruby to be used by code in Java; IronPython does the same for other .NET languages. In fact, C# is basically the .NET counterpart to EMF.
FWIW, I also think that data based languages like ERD, Relax NG, and XQuery/XPath/XML Schema are a much closer fit to Haskell than EMF. EMF is designed to be translated any object-oriented, class-based, (soley) subtype-polymorphic, single-dispatched, single-inheritance language; i.e. Java. In fact, EMF is really a Java-optimized subset of what was supposed to become part of MOF 2.0.
- Brian
-- Dipl.-Inform. Steffen Mazanek Institut für Softwaretechnologie Fakultät Informatik Universität der Bundeswehr München 85577 Neubiberg Tel: +49 (0)89 6004-2505 Fax: +49 (0)89 6004-4447 E-Mail: steffen.mazanek@unibw.de

Hi Just to say, I agree with Brian totally! I've been (violently and forcefully) exposed to MOF tools in the past, and at every turn my thought was "the Haskell would be clearer, shorter and executable!"
Brian, but don't you think that you have to write a lot of boilerplate code in Haskell?
Can you give an example? Usually higher order functions, monads, laziness etc can combine to make the boilerplate minimal, if not invisible. This is exactly the kind of problem haskell-cafe will excel at.
Second, if Haskell should be more successful in the real world there has to be a way of demonstrating basic ideas of a big program to "customers". How would you do this? Everybody knows UML class diagrams, for example. In contrast, nobody knows about termgraphs or lambda *g*.
The UML is not executable, draw a pretty picture. No one knows UML, everyone knows pretty pictures - most people can guess at the meaning of UML because they know the meaning of pictures. As to reverse engineering a diagram from code, that always leads to ugly (and pointless) diagrams.
Third, assume you already have a model, want to write the corresponding code yourself?
If the model is executable, why do you want to write the code?
Thank you very much for contributing to the discussion. Please assume, that you have to generate the code from a model.
If the model is the code, then the tool "cat" can be used to generate the code from the model :-)
Further assume, that you have no choice and are not allowed to discuss the sense of this approach :-)
Ah, artificial technical limitations are unlikely to be something that people adhere too :) If you can generate Java code from a model, why on earth would you then want to generate Haskell code from it? I see know reason to use the assembly language called Haskell vs the assembly language called Java - since if you are compiling a model to anything, it is just serving as an assembly language. Thanks Neil PS. Apologies - I got a 3rd in my degree module in meta-modelling - apparently giving alternative (better) solutions in Haskell does _not_ get bonus marks. This makes me not like meta-modelling very much.

Hi Neil, Just to say, I agree with Brian totally! I've been (violently and
forcefully) exposed to MOF tools in the past, and at every turn my thought was "the Haskell would be clearer, shorter and executable!"
This is true only for programming in the small, isn't it? Furthermore, from my point of view Haskell code is very clear if we talk about computations, in contrast the dependencies of data modelling are harder to overview. Humans just like pictures :) Not everybody is a hardcore Haskell hacker.
Brian, but don't you think that you have to write a lot
of boilerplate code in Haskell?
Can you give an example? Usually higher order functions, monads, laziness etc can combine to make the boilerplate minimal, if not invisible. This is exactly the kind of problem haskell-cafe will excel at.
I do not mean the code per se. I was talking more about structure, modules, comments, ... Haskell hackers have invented a lot of cool stuff to make their life easier, however this stuff often is complicated to understand :-) or not standard compliant. If you can generate Java code from a model, why on earth would you
then want to generate Haskell code from it? I see know reason to use the assembly language called Haskell vs the assembly language called Java - since if you are compiling a model to anything, it is just serving as an assembly language.
Hmph, how to disprove this argument? Say, you have generated ddl-code from an ER-model and now want to generate Haskell data structures that operate on this data. How would you procede? This is similar to HaXML that helped you to generate Haskell types for an xml schema. Best regards, Steffen -- Dipl.-Inform. Steffen Mazanek Institut für Softwaretechnologie Fakultät Informatik Universität der Bundeswehr München 85577 Neubiberg Tel: +49 (0)89 6004-2505 Fax: +49 (0)89 6004-4447 E-Mail: steffen.mazanek@unibw.de

This is true only for programming in the small, isn't it?
my favourite opinion on that subject was expressed, back in 1984, in Burstall, Lampson A kernel language for modules and abstract data types http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-1.html paraphrasing: programming-in-the-large should look pretty much like programming-in-the-small. what you need is a simple notation 'for dealing with big objects (pieces of a program) as if they were small ones (numbers); this is the basic good trick in matrix algebra'. meta-mudelling is a popular subject (and my tendency towards puns is not to be construed as a criticism - i like going meta if i can do so without going crazy;-), but the pragmatic focus is on the models, isn't it? try not to think of a modeling language for Haskell code. instead, think of Haskell itself as a meta-modelling language: first, you design a modelling language suitable for the problem at hand, then you make that modelling language precise and executable by prototyping it as an embedded domain-specific language in Haskell, then you model your problem in that modelling language. finally, you run your model. sometimes, you are done at this point. sometimes, you will need many more models, more efficiently implemented, so it makes sense to move from the prototypical implementation of your modelling language to an efficiency-oriented one (perhaps by turning an embedded interpreter into an embedded compiler and runtime system). sometimes, you only needed that one model, but you need it faster, and in a different language, to fit into some external constraints, so you either make your embedded compiler generate code in that language, or you re-implement by hand once you know that your model does what you want. of these, only the last alternative is not in line with model-driven development, in its code-and-model-are-linked-by-tools incarnation. if you need to model parsers, you start with a parser language, if you need to model other grammar-based problems, such as type systems or operational semantics, you generalise to monadic combinators, if you need to model financial contracts, you start with a contract language, if you need to model animation, you start with an animation language, if you need to model graphical representations of data-flow, you start by embedding Petri nets, and so on.. it is up to you to find and define the right modelling language for your problem/ domain/audience/customers/bosses/.., but Haskell provides good abstractions to build on, and -not to be underestimated- a common framework (or meta language) in which several such modelling languages can be combined. the latter not only means that abstractions common to different modelling languages can be extracted into libraries, and studied in general (such as monads and monad transformers), it also means that your model of a grammar can be integrated with your model of an execution mechanism, which in turn can be linked with your visual model of static and dynamic properties of your systems. in other words, you can model complex systems in a single framework, while still getting to choose the most appropriate language for modelling each part of your system.
Hmph, how to disprove this argument? Say, you have generated ddl-code from an ER-model and now want to generate Haskell data structures that operate on this data. How would you procede? This is similar to HaXML that helped you to generate Haskell types for an xml schema.
provided that the modelling language is defined precisely, you can write a compiler for it in Haskell (Haskell is good for writing compilers, remember?-). such a compiler could generate Haskell code, or tools, or data types, or.., or even Java code. rumour has it that it could even be used to reverse engineer and process Cobold, if necessary;-) (the xml example -is that xml schemata or dtds, btw?- demonstrates that precise definitions don't necessarily make for concise code, but thats what you get with standards..) claus which reminds me that so far there have been only two times i found myself agreeing with anything umlish: a paper by Harel explaining his ideas about statecharts, and a workshop of umlers i stumbled into, where it became clear to me that those pragmatic users of uml mainly use the graphics to depict their type hierarchies, while tending to ignore the advanced, complicated, and not necessarily well-defined aspects of uml.

On 4/13/07, Neil Mitchell
Second, if Haskell should be more successful in the real world there has to be a way of demonstrating basic ideas of a big program to "customers". How would you do this? Everybody knows UML class diagrams, for example. In contrast, nobody knows about termgraphs or lambda *g*.
The UML is not executable, draw a pretty picture. No one knows UML, everyone knows pretty pictures - most people can guess at the meaning of UML because they know the meaning of pictures. As to reverse engineering a diagram from code, that always leads to ugly (and pointless) diagrams.
Speaking of pretty pictures, there's a tool from Business Objects called Gems, which is based on a "lazily evaluated, strictly-typed language called CAL, with many similarities to Haskell"
From http://labs.businessobjects.com/cal/default.asp "These pieces of business logic, which we called "Gems" to give them a nice friendly face, are declarative 'functional' objects."
Although unrelated to UML, it provides a nice way of graphically representing functions, check it out: http://resources.businessobjects.com/labs/cal/gem_cutter_manual.pdf Or, if you prefer a (boring) video: http://resources.businessobjects.com/labs/cal/gem_part_1_mov.zip I haven't put much thought on that, but I think it's possible representing (de-sugared) Haskell functions using GraphML and relying on existing renderers for simplicity ... anyone tried that already ? -- Ricardo Guimarães Herrmann "You never change things by fighting the existing reality. To change something, build a new model that makes the existing model obsolete" - R. Buckminster Fuller
participants (5)
-
Brian Smith
-
Claus Reinke
-
Neil Mitchell
-
Ricardo Herrmann
-
Steffen Mazanek