I stumbled on this in my private notes, from February 2021 (edited for formatting and spelling mistakes). I’m mostly publishing because of the hilarious dream/hallucination at the end which I completely forgot in the past 3+ years (maybe swept away by a far stranger reality of 2021/2022/2023?)
CircleCompiler
Circle C++ compiler is “an extension of C++17 to support data-driven imperative metaprogramming”. In short, it is a way to write a program to write a program, a built-in code generator, much better than macros or templates, because it’s imperative in nature and doesn’t rely on what the compiler writer offer us. This is the first time I saw a compiled language with built-in compile-time interpreter to modify the output of the compilation.
- It reminds me of babel - add new features on top of the language. Would it be interesting to build a plugin ecosystem on top of Circle?
- It collapses two traditionally separate processes - building and execution - into a single entity. The program builds itself or at least helps builds itself.
Questions:
-
Is this what using Lisp macros feels like? Obviously in the interpretation time but still - what is the connection there?
-
Precisely so according to this https://wiki.c2.com/?LispMacro:
Lisp macros are very different to C macros. They are a way to transform lisp code.
This macro function can do arbitrary computation at macroexpansion time. The result of this call has to be again Lisp code.
Crucially, the macro language is Lisp itself, so the full power of the language is available. Contrast this with C macros, where a separate language (which doesn’t know how C works) is used.
- Could this approach be used for instrumentalization? Could that instrumentalization be used for something other than performance? Could this be integrated with compiler’s inner API and then leverage that into even more expressive language (or meta-language)? To keep compatibility such meta-language would have to be standardized of course.
What about Rust macros?
- Weaker than both Circle macros and List macros. See this as an example: https://z0ltan.wordpress.com/tag/rust-vs-lisp-macros/
The nice thing about Circle meta-language is that, as far as I understand right now, explicit in the parts that are evaluated during pre-compile time vs compile time which should solve the problem in the above mentioned article.
Btw, last night (2021-02-08 to 2021-02-09), I dreamt/hallucinated? of using Circle to implement double dispatch in C++. Very interesting on what I fixated (I haven’t thought about double dispatch in… a decade? more?)
- Hypnagogic hallucinations: https://en.wikipedia.org/wiki/Hypnagogia
- Double dispatch: https://en.wikipedia.org/wiki/Double_dispatch
- In C++: https://en.wikipedia.org/wiki/Double_dispatch#Double_dispatch_in_C++
- “The problem is that, while virtual functions are dispatched dynamically in C++, function overloading is done statically.”
- Now I’m wondering if I could actually implement “native” double dispatch with something like Circle + compiler API exposed to it; in principle sure, why not
- I also think that in my hallucination I didn’t really “implement” a) anything b) let alone double dispatch. IIRC it was a simple function overloading on two different types.
- In C++: https://en.wikipedia.org/wiki/Double_dispatch#Double_dispatch_in_C++
- Still - fascinating hallucination :)
Last modified on 2024-07-29