[Haskell-cafe] Code that writes code

Jesse Schalken jesseschalken at gmail.com
Sun Aug 22 03:34:37 EDT 2010


 I would also like to strongly discourage code generators.

Any code that has to be "generated" can and should have its common
characteristics separated out with only unique characterstic remaining
typically with an interface (i.e. type class) or polymorphic type
dividing the two, creating a separation of concerns (this is really just
abstraction).

Every software project which I've worked on that used a code generator
turned into a nightmare, because when we find we need to change
something about the generator's output, all the already generated code
has to be updated manually while at the same time maintaining all of the
unique modifications that have been since the code was first generated.
It's a horrible duplication of program logic and maintenance work.

Of course code generation is perfectly fine when the output is not
intended to be read and maintained by a human. For example, a compiler
is technically a code generator, but it is purely for optimization
purposes and the output is not intended to then be maintained by a human
manually. A compiler might unroll a loop repeating the loop body a
hundred times causing obvious duplication of logic, but it's fine
because the assembler output is not intended to be maintained by a
human, only the source input is. Efficiency and maintainability cannot
be satisfied at the same time, which is why assembly sucks (not
maintainable) and so do dynamic/scripting languages (not efficient), and
compiled languages like Haskell are awesome (source code is highly
maintainable, compiler output is highly efficient).

Anyway, from my experience if you're generating code intended to be
maintained by a human, you're doing it wrong. Though I am very
interested to hear counter examples.

Jesse

On 20/08/2010 6:17 PM, Graham Klyne wrote:
> Maybe not helpful to you at this stage, but...
>
> An alternative to generating source code is to factor out the common
> "boilerplate" elements into separate functions, suitably
> parameterized, and to
> use higher order functions to stitch these together.
>
> An example of this kind of approach, which is handled by code
> generation in some
> other languages (e.g. lex, yacc, etc), is the Parsec combinator-based
> parsing
> library (http://www.haskell.org/haskellwiki/Parsec) - instead of
> generating
> code, the syntax "rules" are written directly using Haskell functions and
> assemble the common underlying repeated logic dynamically, behind the
> scenes.
>
> I adopted a development of this approach for a programme with a built-in
> scripting language that I implemented some time ago:  the scripting
> language was
> parsed using Parsec, not into a syntax tree, but directly into a
> dynamically
> assembled function that could be applied to some data to perform the
> scripted
> function (http://www.ninebynine.org/RDFNotes/Swish/Intro.html).
>
> What I'm trying to point out here that, rather than go through the
> step of
> generating source code and feeding it back into a Haskell compiler, it
> may be
> possible to use higher order functions to directly assemble the
> required logic
> within a single program.  For me, this is one of the great
> power-features of
> functional programming, which I now tend to use where possible in other
> languages that support functions as first class values.
>
> #g
> -- 
>
> Andrew Coppin wrote:
>> I'm working on a small Haskell package. One module in particular
>> contains so much boilerplate that rather than write the code myself,
>> I wrote a small Haskell program that autogenerates it for me.
>>
>> What's the best way to package this for Cabal? Just stick the
>> generated file in there? Or is there some (easy) way to tell Cabal
>> how to recreate this file itself?
>
>
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe




More information about the Haskell-Cafe mailing list