I really like his attitude on the turing-complete compile time metaprogramming feature:
'Yes you can shoot yourself in the foot, hang the compiler, and launch missiles at the same time. You're a good programmer or you wouldn't be using this language. So don't do that. If you do, don't do it again.'
That's not always a good attitude to have in software development, but a modern language that backs away from the "wrap us all in bubble wrap" philosophy is refreshing.
Are there any common languages that allow you to do compile time metaprogramming in the language itself? I'd like to write little miniprograms which output source code and get evaluated at compile time. For example:
and then at compile time that would get run and the source could generated would be:
int fib(int n) {
switch(n) {
case 0: return 0;
case 1: return 1;
case 2: return 1;
case 3: return 2;
case 4: return 3;
case 5: return 5;
case 6: return 8;
... etc up to i=29...
default: return fib(n-1) + fib(n-2);
}
}
Learn a Lisp (say, Scheme or Common Lisp). For Lisp family, this is bread and butter. Since the source code itself is at the same time a data structure, you can (and often end up doing it) easily generate code at read time, compile time or run time. The border between those three kind of starts to blur.
Your example could look like this in Common Lisp:
(defun fib (n)
(if (< n 2)
n
(+ (fib (- n 1)) (fib (- n 2)))))
(defmacro spliced-fibs (x n)
`(case ,x
,(map-iota (lambda (v) (list v (fib v))) n)))
(defun hardcoded-fib (num)
(spliced-fibs num 29))
spliced-fibs macro will generate you a full case block at compile time, so the hardcoded-fib will be basically one big switch/case block. map-iota call maps a function over a list of numbers from 0 to n. Note that a macro can call ordinary functions at compile time, which themselves can use other macros, etc. So a lot of code can be used both at compile and run time.
Have a look at D, its metaprogramming facilities are really something.
In particular string mixins will do what you want; they will also do much more, like for instance include external files written in domain specific languages and compile them in native D code; all this is done by the compiler, using language facilities, without external tools.
(These is not some theoretically cool feature; it's used in real world code, like dproto, which compiles protobuf definitions into native code, or HTML templating engines which compile templates to the equivalent of Java servlets)
Forth has always been able to do this sort of metaprogramming- in fact this approach is how most of the language is built. Constructs and syntax like conditionals, loops and comments are all just normal word definitions and it is easy and commonplace to extend the syntax of the language for a particular program. Forth is often described as "compiled AND interpreted" because "compiling" a program constantly swaps between interpreting pre-existing definitions and building up new definitions and allocations in memory.
Common Lisp is one of the languages with the best control over what gets executed at compile-time versus run-time. It also has a syntax which is extremely amenable to this kind of compile-time generation of code.
> allow you to do compile time metaprogramming in the language itself
That feature is called compile-time function evaluation, and there are a bunch of languages that support CTFE[1]. Blow's language has, from what I've seen, the cleanest CTFE syntax and most straightforward usage approach. In terms of what you can use today, check out D[2] (which has multiple competing ways to do CTFE).
To add to the (at this point rather large list), Haxe[0] allows this, although it prefers that you don't use the string-based method (which IIRC the docs, outside of the API reference, don't really mention, but does exist), but instead manipulate an AST-like object defined in its standard library.
It's macro facilities are actually fairly amazing, and allow for a lot of boilerplate code to be generated at compile time (think: the kind of things reflection is used for in other languages).
Sadly, it's a GCed language, so while it's very popular for game development, it's use is mainly in the indie scene, and so it's probably never something I'll use for anything other than a toy.
Are there any common languages that allow you to do compile time metaprogramming in the language itself?
I'm not sure what you mean by 'in the language itself', since isn't all compile-time metaprogramming in the language itself? But this question has an example of computing Fibonacci sequences in C++ templates:
The second part of the question is about how to turn that into a table which can be referenced at runtime, which would seem to be the same as your question.
Plenty of them. You don't even need a special language - with the right build system & build rules, you're more than welcome to have e.g. "make" build your generator, run your generator, and then build your generated code.
I occasionally write C# which writes C# (using .NET APIs to compile it at runtime, typically) and C# in T4 Text Templates which write C# (they integrate nicely into Visual Studio's build process right out of the box.)
Others have said LISP; if you're willing to manipulate ASTs then anything with macros will do (I love scala). If you want it to be more string-oriented then perhaps TCL (not that there's always a compile time per se)
'Yes you can shoot yourself in the foot, hang the compiler, and launch missiles at the same time. You're a good programmer or you wouldn't be using this language. So don't do that. If you do, don't do it again.'
That's not always a good attitude to have in software development, but a modern language that backs away from the "wrap us all in bubble wrap" philosophy is refreshing.