So I've never heard about metaprogramming until I started learning Nim, and I'm not sure I understand the idea properly.
Am I correct in the assumption that you can use metaprogramming to implement for example a scripting language, in that it can take an input (File, for example), process it and turn it into Nim code, which is then executed? (So not a converter, no compilation)
I did find the Brainfuck interpreter, but I don't quite understand it. I'll be studying it more though, to see if I can figure out how it works.
From the description I saw, Brainfuck can run brainfuck code as an interpreter, OR create a Nim output file.
If that is so, it opens up some very interesting possibilities to implement a new, or mimic an existing, programming language in a Nim format, essentially taking it from script to native binary, which should make it quite a bit speedier.
Basically you can write something in Nim which changes what the compiler sees while it compiles your code.
I think one easy to understand example is that you can write a macro which gets to read the remaining Nim Code and can replace its own call by something new. This macro could simply get a string with comma separated values and generate an enum out of it:
import macros
macro stringToEnum(name: string, options: string): stmt =
parseStmt("type " & name.strVal & " = enum " & options.strVal)
stringToEnum("test", "one, two, three")
#type test = enum one, two, three
var x:test = one
case x:
of one: echo "one"
of two: echo "two"
of three: echo "three"
This can grow incredible complex. You could have multiple macros all creating code "in the background" relying on each others output. This can be used for optimisations or to create a DSL which then constructs a Nim AST "on the fly".
There is another property which is related. If you are declaring something const it will be evaluated at compile time. This means you even can write const a = someProc(somedata) which then will evaluate the proc and assign the result to the const at compile time.
Nim actually has a Nim "interpreter" (the VM) which the compiler runs on the AST to eventually produce the final AST which gets "rendered" to the target language (I do not really know what I talk about though :).
You could read about templates and macros in the Nim documentation. I think that is quite nice. But the talk by @Araq about Metaprogrammint at InfoQ is superb to understand whats "behind" the idea for real.
One of the biggest example for macros I found so far is emerald a HTML template engine. To bad it does not work with the current compiler. I tried to update it but did not finished it yet.
P.S.: People correct me if I am wrong. I am still exploring this stuff myself.
This is quite exciting, so that would be a yes then!
If I were to process a file, converting it to Nim AST, which can then be run live using the VM, this means it's acting exactly like an interpreter, as well as the potential to save the result to disk, which can then be compiled to a binary if you want to.
If I can figure out how to do this, I will be incredibly happy, as it's the beginning steps in creating or implementing a scripting/programming language, which when coupled with a web server opens up some interesting capabilities.
I believe this is what the Brainfuck interpreter does (It offers to run as interpreted, or save to Nim file).
@Daimon After reading your last post I think it is more a "no" then a "yes" but still another "yes" :)
The VM is (imho) only capable to run code (from the AST) to modify the AST. It basically "recodes" the existing AST into another AST. You can't use this as a language for a web server. The result needs still to be compiled.
It is more like this: You could write an interpreter for some language in Nim and implement the same language as macros/templates which will then compile the code to Nim (aka the AST of the Nim compiler). This is what the Brainfuck example does.
I probably would prefer to write full Nim code and have some cool graceful restarting server frontend which lets me hot-plug new code into it without interruption.
@OderWat, I'm watching the video in the link, and I understand better now what the capabilities are.
For me, step one will be to implement a few simple templates, essentially implementing a scripting language/interpreter.
Taking the webserver example the idea would be to get a request for a file, read the file, process it according to the templates, then return the finished html output.
I'm still watching the video, but I'm very impressed and intrigued by the possibilities.
One really cool thing about using a DSL for the template system is that you can have checks at compile time.
Like ember had some basic checks for the correct tag and attribute structure.
To me this was also what makes Hamlet cool in my eyes. At the time I read about it that was just "cool" in second thought, cause I have my own template engine for many years which works more like mustache.
At first I thought it is much better to have a quick way to just change some files to update a site. But I seldom do that and with Hamlet / compiled templates you do not only get faster templates but you can also have type safety for them!
If you never read about this you may find this an interesting read: http://www.yesodweb.com/book/shakespearean-templates