Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Fear of Macros (greghendershott.com)
129 points by tosh on July 29, 2018 | hide | past | favorite | 11 comments



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


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.


C macros are to be feared. Not Racket macros.


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/


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


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.


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.


No. :)

Continuations are in the category of things best explained by burrito analogies.


Are burrito analogies catamorphisms of continuations?


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




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: