OCaml and Scala both have staged metaprogramming libraries, which provide a powerful way to generate code at compile or runtime. A description of the OCaml approach, called BER MetaOCaml, is here.
The basic idea is that we have a type Code : Type -> Type which represents program fragments. For example, Code Int is a program which, when run, will evaluate to a value of type Int. We have two basic operations to work with Code values: quoting and splicing.
Quoting constructs a Code value. 3 is a value of type int, whereas <3> is a value of type Code Int. Within a quote (and only within a quote) we can splice a value. For example, consider
z1 : Code Int
z1 = let x = 3
y = 2
in < x + y >
When evaluated, z1 will execute x + y and yield the result. Since those values are hardcoded, we can do the addition up-front. To do this we splice the result into the quote:
z2 : Code Int
z2 = let x = 3
y = 2
in < ~(x + y) >
z2 will then be a code fragment containing just the literal value 5.
We can write any arbitrary (pure) Kite expression inside quotes. MetaOCaml supports effects but we don't have to (maybe in future). There are lots of applications but the main ones I'm interested in are:
Using metaprogramming as a basis for a high performance streaming library. We can build all our usual stream/list processing stuff on top of this, and it will compile almost-perfectly to the best hand-written code. See here.
Using metaprogramming to implement data-generic programming (e.g. SYB, Generics, ...). See [here]. If we can do this via metaprogramming, that removes one of the main requirements for fancy typeclass stuff that I don't want to add to the language. We can keep our implicit resolution nice and simple.
A key requirement for staged metaprogramming is to have a compiler for Kite code that can be executed in Kite. This probably means we need to write a compiler for Kite in Kite. I think this is another point in favour of slimming down the language as much as possible.
OCaml and Scala both have staged metaprogramming libraries, which provide a powerful way to generate code at compile or runtime. A description of the OCaml approach, called BER MetaOCaml, is here.
The basic idea is that we have a type
Code : Type -> Type
which represents program fragments. For example,Code Int
is a program which, when run, will evaluate to a value of typeInt
. We have two basic operations to work withCode
values: quoting and splicing.Quoting constructs a
Code
value.3
is a value of type int, whereas<3>
is a value of typeCode Int
. Within a quote (and only within a quote) we can splice a value. For example, considerWhen evaluated,
z1
will executex + y
and yield the result. Since those values are hardcoded, we can do the addition up-front. To do this we splice the result into the quote:z2
will then be a code fragment containing just the literal value5
.We can write any arbitrary (pure) Kite expression inside quotes. MetaOCaml supports effects but we don't have to (maybe in future). There are lots of applications but the main ones I'm interested in are:
A key requirement for staged metaprogramming is to have a compiler for Kite code that can be executed in Kite. This probably means we need to write a compiler for Kite in Kite. I think this is another point in favour of slimming down the language as much as possible.