Alright, since I've ran out of critical issues on my TODO, here's Neat!
https://github.com/neat-lang/neat
The syntax will seem very familiar to people here. :) It's sort of like D1 circa 2003 but with macros instead of CTFE and a very underpowered template engine. Note that while all the features I want are in there, some (such as templates) are only 10% there. Still, it's usable as it stands, and it's self-hosting.
The biggest divergences to D are probably that it's reference-counted rather than GC, the macro support, and variables being (head) immutable and unreferenceable by default.
It also has built-in: tuple types, sumtypes with implicit conversion, named parameters and format strings. But D will have all of those eventually. (Any year now...!!) So how about I show you something cool that will probably never be in D:
How do you encode two structs to JSON?
module test;
macro import std.json.macro;
macro import std.macro.assert;
import std.json;
struct B {
A first, second;
}
struct A {
int v;
}
JSONValue encode(B b) {
return JSONValue({
"first": encode(b.first),
"second": encode(b.second)
});
}
JSONValue encode(A a) {
return JSONValue({ "v": a.v });
}
void main() {
assert(encode(B(A(2), A(3))) == JSONValue({
"first": {"v": 2},
"second": {"v": 3}
}));
}
"So you have hashmap literal syntax, like D?" No, I don't. Look again. The parameter passed to JSONValue is a genuine JSON expression, with embedded Neat expressions. No JSONValue()
spam required. If it were XMLValue, it could just as easily be XMLValue(<tag attribute=$variable>$(encode(body))</tag>)
.
Macros, fuck yes!