Date: Sat, 24 Oct 2026 13:06:51 -0700
Hello all,
A few years ago, I posted here about adding support for bindings
generation, and was left thinking that wasn't an area the standard should
be responsible for. Now we have function attributes, attribute reflection,
and sophisticated compile time code generation. Suddenly, modern C++
bindings generation is starting to look like it is on the way to some new
era.
Please allow me to provide a quick case study that still motivates me, as a
way of describing requirements that I would like to see addressed.
In my opinion, the embedded command processor is one of the most overlooked
design patterns in C++. The default implementation is to map a utf-8 line
to a command by splitting it into tokens using something like ::isspace(),
treating arg[0] as a command key, and then forwarding the remaining args.
As type information has become easier to manipulate in C++, and more of
this can be generated at compile time, this construct has become even more
accessible.
The embedded command processor pattern I am describing allows functions to
be registered from within individual translation units before main(). Then
it enables those functions to be called from the command line on the very
first line of main() in order to configure the entire program before it
runs. Or they can be called from a settings file during program
initialization, or they can be used interactively from a debug shell. And
all of these ways can use automatic parsing generated from the function's
type info. I'll elide a description of a 10KiB interpreter implemented
using this strategy and modern C++ but would be happy to unpack that.
I only have one major complaint that is unresolved in the online
discussions around attributes proposals that I have read:
At least until I hear back from this list, the path of least resistance for
me to locate a global function for use in an embedded command processor is
still to hook the global variable initialization array. Because I can do
that in one line, with a macro using a template to declare a global
variable. E.g. using this single line: "declare_fn(some_fn);" in global
scope. ("Hi, I'm from games.")
That is my primary reservation. That the actual registration hook still has
to exist at all, and the later it runs the less useful it is. Could
everyone, please take this design pattern into consideration when designing
"bindings" attributes. Arguably its implementation provides a minimum set
of requirements to target for solving in a clean way. Something the
standard should be good at.
Thanks for reading this far,
Adrian
A few years ago, I posted here about adding support for bindings
generation, and was left thinking that wasn't an area the standard should
be responsible for. Now we have function attributes, attribute reflection,
and sophisticated compile time code generation. Suddenly, modern C++
bindings generation is starting to look like it is on the way to some new
era.
Please allow me to provide a quick case study that still motivates me, as a
way of describing requirements that I would like to see addressed.
In my opinion, the embedded command processor is one of the most overlooked
design patterns in C++. The default implementation is to map a utf-8 line
to a command by splitting it into tokens using something like ::isspace(),
treating arg[0] as a command key, and then forwarding the remaining args.
As type information has become easier to manipulate in C++, and more of
this can be generated at compile time, this construct has become even more
accessible.
The embedded command processor pattern I am describing allows functions to
be registered from within individual translation units before main(). Then
it enables those functions to be called from the command line on the very
first line of main() in order to configure the entire program before it
runs. Or they can be called from a settings file during program
initialization, or they can be used interactively from a debug shell. And
all of these ways can use automatic parsing generated from the function's
type info. I'll elide a description of a 10KiB interpreter implemented
using this strategy and modern C++ but would be happy to unpack that.
I only have one major complaint that is unresolved in the online
discussions around attributes proposals that I have read:
At least until I hear back from this list, the path of least resistance for
me to locate a global function for use in an embedded command processor is
still to hook the global variable initialization array. Because I can do
that in one line, with a macro using a template to declare a global
variable. E.g. using this single line: "declare_fn(some_fn);" in global
scope. ("Hi, I'm from games.")
That is my primary reservation. That the actual registration hook still has
to exist at all, and the later it runs the less useful it is. Could
everyone, please take this design pattern into consideration when designing
"bindings" attributes. Arguably its implementation provides a minimum set
of requirements to target for solving in a clean way. Something the
standard should be good at.
Thanks for reading this far,
Adrian
Received on 2026-10-24 20:07:19
