
Lisp Meta-Programming for C++ Developers: First Macros - deque-blog
https://deque.blog/2017/05/09/lisp-meta-programming-for-c-developers-first-macros/
======
hacker_9
Imagine the power of your whole programming language available to you at
compile time. That is a Lisp macro. It gives you the ability to write simple
and elegant code, which can then be compiled down into the unreadable nasty
code after, while still being as fast as if you wrote the nasty code by hand.
Another term for this is zero-cost abstraction. What is nice in Lisp is you
can also use the (macroexpand ) function to see what Lisp code will actually
be generated.. it's Lisp all the way down!

If you look at the Servant library [1] for ClojureScript, they wrapped the
callback-hell mess that is Javascript web workers (read: the only way to
actually multi-thread on the web), into beautiful Go-style channels, via the
use of macros.

[1]
[https://github.com/MarcoPolo/servant](https://github.com/MarcoPolo/servant)

~~~
hellofunk
Typically you are limited at compile time because Lisps -- especially Clojure
-- do not allow the same computing resources you get at runtime to be used at
compile time, so there are some clear limits.

This can be true in C++ as well, but those limits are quite high and are
easily set to something else. Perhaps Clojure also allows you to reset what
these limits are.

~~~
kazinator
Sometimes the situation is completely reversed: you get a lot more computing
resources on the development system where the code is compiled, than on the
target system where it ultimately runs (e.g. small, embedded target).

The computing resources required to process the code (macros, and whatever) is
usually unrelated to the computing resources of the application.

A program that works with gigabytes or data might need only megabytes during
its compilation.

(It's not easy to imagine _practical_ circumstances where it would be
reversed, with those exact numbers. Some algorithms you might want to use at
compile time do explode in memory size, I suppose.)

~~~
Someone
That is getting quite normal nowadays; training a model in machine learning
typically takes way more resources than running it.

However, if you need gigabyte to expand your macros, it is likely you need
megaseconds, too, and then, it is wise to use 'precompiled headers', and save
your 'preprocessor output'.

------
Johnny_Brahms
Defmacro is convenient. Debugging when the lack of hygiene leads to weird
errors is not.

It happens once ever blue moon, but every time I would kill for a proper
syntax-case for CL. Racket's is fine, but I'd be happy with a one like the
plain R6RS as well

~~~
progman
Side effects are no issue if every local variable name in a defmacro is
generated with (gensym).

~~~
TeMPOraL
And if you're tired of doing that by hand, you can... write a macro that'll do
that for you. In fact, those were already written, and are available in many
libraries as well as featured in many books.

See e.g. Alexandria[0] for with-gensyms (automatically binding your variables
to gensyms) and once-only (similar, but ensures the value will be evaluated
only once).

Also note that lack of hygiene is actually a useful feature - it allows macros
to capture variables from code passed to it as well as the environment they
expand it. Some cool stuff can be done that way (some uncool foot-shooting
too, though).

\--

[0] - [https://common-
lisp.net/project/alexandria/draft/alexandria....](https://common-
lisp.net/project/alexandria/draft/alexandria.html#Macro-Writing)

~~~
sedachv
> Also note that lack of hygiene is actually a useful feature - it allows
> macros to capture variables from code passed to it as well as the
> environment they expand it. Some cool stuff can be done that way (some
> uncool foot-shooting too, though).

Doug Hoyte's excellent book _Let Over Lambda_ has a lot of examples.

~~~
TeMPOraL
Oh yes. This book is very fun, in the "what on Earth did he just do here" kind
of way.

------
krylon
I remember trying to explain the power of Lisp macros to a friend who at the
time knew C++. I did not even know template-metaprogramming was possible, back
then; that probably would have made it a lot easier.

