Hacker News new | ask | show | jobs
by elcritch 506 days ago
Oh how I enjoy trying to compile and use projects where they use some complex home brew codegen system often written in a different language entirely [1]. Luckily they often use Python as part of some core build step which never breaks compatability in their regex librwry [2]. </sarcasm>

Yes macros can be a pain and should be limited, but in my experience, a couple hundred lines of macros replaces many thousands of lines code generators with complicated baroque build system integrations (ahem ROS2). The tradeoff is even worse when the language supports templates and compile time operations which can usually replace macros with even less code and are easier to understand. Though at least Go supports codegen properly with support in its official tooling.

1: https://github.com/google/flatbuffers/blob/master/src/idl_ge... 2: https://github.com/python/cpython/issues/94675

1 comments

Bad code is bad code, but FWIW every time I've seen something that actually needs a "complex home brew codegen system", it's absolutely best expressed in a dedicated piece of software engineering and not within a macro environment. Zephyr leans heavily on that kind of engineering, actually.

The point is really that "macros" is a weird sandwich between "complicated metaprogramming you need to do from first principles" and "you really didn't need metaprogramming, did you?". And that over the years that sandwich has been getting thinner.

Lisp macros in the 60's were a revelation. They don't really have a home anymore.

> FWIW every time I've seen something that actually needs a "complex home brew codegen system", it's absolutely best expressed in a dedicated piece of software engineering and not within a macro environment. Zephyr leans heavily on that kind of engineering, actually.

I'd definitely agree with you about Zephyr's "I really want C macros to be real macros" system for it's device tree system. It's a huge pain to debug because you don't find issues until the linking step. However I'd counter with the fact that C macros _aren't_ real macros. Hence the pain.

Actually C's "macros" are literally just a separate codegen tool (m4 processor) just like what you're suggesting. It's a large part of what makes C code so hard to programmatically parse or automate.

Essentially Zephyr is doing meta-programming in an external codegen tool. Totally agree that a separate codegen tool specifically for device trees or whatnot could be better than that. However if C had a proper macro system (and compile time types), you could readily express the device tree system in the language at compile time and produce helpful errors.

> The point is really that "macros" is a weird sandwich between "complicated metaprogramming you need to do from first principles" and "you really didn't need metaprogramming, did you?". And that over the years that sandwich has been getting thinner.

They aren't really though. Homebrew codegen systems are much more of the weird sandwich between "you needed metaprogramming" and "you didn't have metaprogramming". Instead you build a system which is even more complicated in total, e.g. source and generated code gets out of sync, you have name clashes, the core API logic is spread out over different languages and code bases, etc.

Though I do agree the use cases for macros are shrinking, but more due to meta-programming via templates and compile time expressions becoming more powerful and usually preferable method to doing meta-programming.