Live data from Hacker News

The Problem with Macros

ianthehenry.com

61–70 of 70 posts

Re: The Problem with Macros

#61
I'm probably late to the discussion, but if anybody finds this looking up macros later, I found the HOPL IV paper Hygienic Macro Technology[1] to be a thorough look at the subject that hardly gets mentioned. It turns out solving these sorts of problems elegantly isn't some technique that the author has missed, it's an active area of research. Newer Lisps compete by having new ways of constructing macros that avoid these problems (say, Racket's syntax-parse[2].)

[1] https://dl.acm.org/doi/10.1145/3386330

[2] https://docs.racket-lang.org/syntax/stxparse.html

Re: The Problem with Macros

#62

Earlier quoted context omitted.

Talking about Racket and macrology, I think OP should get in touch with the PLT/Racket team. Matthew Flatt made many talks and papers about macro layers and proper scoping.

Parent comment is likely referring to the wonderfully named "Advanced Macrology and the Implementation of Typed Scheme" paper [1] If you type macrology into Google you get the definition "Long and tedious talk without much substance; superfluity of words. noun." Perhaps accurate, but too vague ;-) [1]: https://www2.ccs.neu.edu/racket/pubs/scheme2007-ctf.pdf

I was lazy (sic) but here's a quick ddg induced list regarding Flatt(mapp)

https://duckduckgo.com/?t=ffab&q=matthew+flatt+macros&ia=web

Re: The Problem with Macros

#63

Syntactic closures are another hygine system that provides the same construction techniques as common lisp macros, while also allowing the macro author to choose which bindings should be set in the macro's lexical environment instead of the expansion's lexical environment (or vice versa). http://community.schemewiki.org/?syntactic-closures

Thank you for this. My brain is complete mush after days of reading papers about the history of lisp, but this is at the top of my reading stack once I can get my eyes to focus again.

HN not supporting notifications, I am forced (;-) to link you some names/topics that you might enjoy

https://news.ycombinator.com/item?id=28847236

Re: The Problem with Macros

#64

Earlier quoted context omitted.

My experience that a certain systems programming language of Unix origins featuring 1 namespace and an unhygienic token-based macro system also has few issues with function-name capture, even in code bases with seven digit LOCs. That makes me severely disinterested and skeptical about hygienic macros. They are too weird for the little benefit they provide. You can't look at a piece of code and know what it expands to…

All I know is that in Python, JS and Clojure is I’ve accidentally written code like: def foo(str): v = str(1) . . . Which resulted in head-scratching errors like “str is not a function”. EDIT: I agree that hygienic macros aren't the right way to solve this issue.

Macros don't appear in your code example, so they cannot solve anything.

Re: The Problem with Macros

#65
post #45

Earlier quoted context omitted.

All I know is that in Python, JS and Clojure is I’ve accidentally written code like: def foo(str): v = str(1) . . . Which resulted in head-scratching errors like “str is not a function”. EDIT: I agree that hygienic macros aren't the right way to solve this issue.

With Lisp-2 designs as discussed in the article this is not an issue, as variables and functions are in different namespaces: CL-USER> (defun foo (list) (list list)) FOO CL-USER> (foo 42) (42) In this case the function attached to the symbol LIST is applied to the argument with the same name, but that isn't a problem. To further illustrate, in the above example the LIST symbol is imported from the package COMMON-LISP…

Yeah, I’ve been writing Common Lisp for six years now: Lisp-2s, IMO, make the right trade-offs

Re: The Problem with Macros

#66

Earlier quoted context omitted.

I strongly agree here: my experience is that a Lisp-2 with namespaced symbols has very few issues with function-name capture. While, at one point, Lisp-2s may have been for performance or other implementation details, I find that Lisp-2s are much nicer to code in because you just don't worry about name collisions (as long as you know a handful of relatively simple rules about macros).

My experience that a certain systems programming language of Unix origins featuring 1 namespace and an unhygienic token-based macro system also has few issues with function-name capture, even in code bases with seven digit LOCs. That makes me severely disinterested and skeptical about hygienic macros. They are too weird for the little benefit they provide. You can't look at a piece of code and know what it expands to…

> My experience that a certain systems programming language of Unix origins featuring 1 namespace and an unhygienic token-based macro system also has few issues with function-name capture, even in code bases with seven digit LOCs.

The "certain systems programming language" with its unhygienic macros hides all the resulting horrible mess in reserved symbols that litter both the macro code itself and the code produced by the macros. This is perhaps tolerable so long as you're not maintaining any of those macros and you never need to look at the code after macro-substitution has occurred.

Re: The Problem with Macros

#67
post #56
post #38

Clojure alleviates this to a great extent by automatically namespace-qualifying symbols within quasiquoted forms, which prevents clashes between let-bound symbols (which are never qualified) and ones from the global scope. It’s still possible to shoot yourself in the foot (see https://blog.danieljanus.pl/2020/01/21/middleware/ for my personal story), but for that you need `binding`, `with-redefs` or `alter-var-root`,…

Time flies by when writing clojure on a train?

In case anybody's wondering what the heck I meant here, it's a reference to the song Time Flies By from Half Man Half Biscuit whose lyrics the title of the linked blog post also appears to be referencing.

Re: The Problem with Macros

#68
post #38

Clojure alleviates this to a great extent by automatically namespace-qualifying symbols within quasiquoted forms, which prevents clashes between let-bound symbols (which are never qualified) and ones from the global scope. It’s still possible to shoot yourself in the foot (see https://blog.danieljanus.pl/2020/01/21/middleware/ for my personal story), but for that you need `binding`, `with-redefs` or `alter-var-root`,…

This is a good example of why dynamic vars are dangerous. They are just as perilous as global state, but are more surprising and more difficult to understand. Prefer passing explicit arguments in all cases. You don't have to even think about the behavior, and you'll never spend 8 hours tracking down a missing binding in a commit from 2018.

Re: The Problem with Macros

#69

Earlier quoted context omitted.

I strongly agree here: my experience is that a Lisp-2 with namespaced symbols has very few issues with function-name capture. While, at one point, Lisp-2s may have been for performance or other implementation details, I find that Lisp-2s are much nicer to code in because you just don't worry about name collisions (as long as you know a handful of relatively simple rules about macros).

My experience that a certain systems programming language of Unix origins featuring 1 namespace and an unhygienic token-based macro system also has few issues with function-name capture, even in code bases with seven digit LOCs. That makes me severely disinterested and skeptical about hygienic macros. They are too weird for the little benefit they provide. You can't look at a piece of code and know what it expands to…

I'm confused about what you're saying about "breaking lexical scope". Lexical scope means that variable references refer to their lexically-enclosing bindings, ie references in A.lisp refer to bindings in A.lisp. That's exactly what hygenic macros do.
Post reply on HN