
Fear of Macros - tosh
http://www.greghendershott.com/fear-of-macros/
======
ozten
Great resource, previously on HN:

[https://news.ycombinator.com/item?id=7601506](https://news.ycombinator.com/item?id=7601506)

[https://news.ycombinator.com/item?id=9692499](https://news.ycombinator.com/item?id=9692499)

------
GavinMcG
This is a great intro. After reading it, I wrote up an outline to approach the
same subject from a different angle:
[http://www.gavinmcg.com/2016/02/03/racket-
macros.html](http://www.gavinmcg.com/2016/02/03/racket-macros.html)

------
tomcam
Greg Hendersott isn’t a typical hacker. He’s the creator of Cakewalk, a
digital audio workstation that ruled the Windows roost for about 20 years.
Hendershott is the John Carmack of music creation software.

------
qubax
C macros are to be feared. Not Racket macros.

------
hyperion2010
For those looking to get into Racket macros, the Racket School [0] from this
year is now also an excellent place to start.

0\. [https://summer-school.racket-lang.org/2018/plan/](https://summer-
school.racket-lang.org/2018/plan/)

------
avmich
There are continuations mentioned in the preface, right? Are we going to talk
about them next? :)

~~~
shawn
A continuation is best understood by trying to implement an evaluator that can
pause.

An evaluator is just a function that takes in some JSON and spits out a
result. [if [> 2 1] 8 9] would produce 8.

Say you wanted to pause during the evaluation of the [> 2 1] condition. What
do you do? How would you resume it later? Well, you have the original JSON.
Meaning you have the whole program code. You know where you are in that
program code. And you know the current state of the program. So you save those
somewhere, return from your evaluator, then restore the values later and tell
your evaluator to start from a specific location.

One non intuitive aspect of this, though, is that “the current values of your
program” includes “what the evaluator should do at each step”. Imagine
evaluating [if [> 2 1] 8 9]. In your eval function, you check “if the first
thing in the list is “‘if’”, call the ‘eval-if’ subroutine.” Your two options
here are to either (a) have eval-if evaluate the condition and then return the
result, or (b) pass the condition and both branches to the function, and have
that function evaluate the condition and one of the branches.

The latter form is called continuation passing, and it’s much easier to pause
and resume. But you’re restricted to tail calls only. You can do it the other
way by saving a stack.

~~~
avmich
Thank you. I think there is more in it, though. When you only talk about
ability to pause, you still don't change the sequence of execution - you only
can inspect it at arbitrary moments. The sequence itself remains immutable.
It's not so clear when you use continuations themselves within that sequence.
Say, you save current continuation as an object in memory and then return to
it - not immediately but after some other actions are done. In this case you
have more questions about how perfect is your return to the state when that
continuation was saved is. Indeed a perfect return would mean the whole memory
state of the machine is restored exactly as it was when the continuation was
taken, and, barring side effects, the execution will repeat what was done
after the continuation was taken but before it was returned to.

I'd like to hear more about control flow state and data flow state here.

------
hashkb
This is the _only_ resource with which I had success getting started with
Racket's macros.

