4 ms·
I'm not a lisp master, so please take the following with a grain of salt: One case where you'd want unhygienic capture is with anaphoric macros, which introduc
by lmohseni 10y ago
I'm not a lisp master, so please take the following with a grain of salt:
One case where you'd want unhygienic capture is with anaphoric macros, which introduce a binding (usually named `it` as in english). For example, using an anaphoric if called aif, we can transform:
(let ((result (big-long-calculation)))
(if result
(foo result)))
into:
(aif (big-long-calculation)
(foo it))
cf: http://www.bookshelf.jp/texi/onlisp/onlisp_15.html http://www.bookshelf.jp/texi/onlisp/onlisp_15.html
- aidenn0 10y agoAnaphora have been controversial in the common lisp community as long as I have been involved. I imagine the same is true of the scheme community.
- groovy2shoes 10y agoYeah, anaphoric macros are a neat trick, a novelty. They're rarely useful in practice. Additionally, any time one would be useful in practice, you turn your anaphoric construct into a binding construct, and suddenly you have hygiene. To lift an example from @davexunit up-thread: (aif (foo) (bar it)) becomes instead (let-if (it (foo)) (bar it)) A minuscule amount of extra typing to be explicit, and now you not only have hygiene, but you can properly nest such forms and even generalize the form to multiple bindings: (let-and ((x (foo)) (y (bar))) (baz x y))
- dang 10y agoAnaphoric macros are used frequently in the HN source code, so "rarely useful in practice" strikes me as incorrect on both counts. Used well, they make code both shorter and more readable. That's a win-win. The arguments against them, by contrast, seem largely theoretical. Win-wins, a.k.a. having your cake and eating it too, are rare in programming, so those of us who think this way will choose that over theoretical purity any day. These arguments boil down to little more than personal preference and, above all, habit. Anaphoric macros are the kind of thing you like if you like that kind of thing. http://quoteinvestigator.com/2015/09/09/like-sort/ http://quoteinvestigator.com/2015/09/09/like-sort/
- groovy2shoes 10y agoTo clarify, I mean that the percentage of macros which are usefully anaphoric is small, not that any given anaphoric macro isn't useful in practice. A macro like `aif` is useful quite often in practice, but there aren't very many macros like `aif`. You're right that it's a personal preference. My own preference is to always be explicit (which also explains my relative distaste for Perl...). With my students, I'm constantly emphasizing that "programs must be written for people to read, and only incidentally for machines to execute"[1]. I feel as though explicity goes hand-in-hand with legibility, while I'll admit it's really just a matter of learning what `aif` does, the same way you have to learn what anything else does, I'd argue that a programmer who has never seen `let-if` before would be able to decipher its meaning from the context, whereas a programmer who's never encountered `aif` will be wondering `wtf`. [1]: Preface to the first edition of SICP.
- dang 10y agoOh yes, it's true that there are aren't many different anaphoric macros, though I occasionally run across a useful new one. But the core ones (in Arc: aif, awhen, aand) are useful in many places. I don't see that famous SICP as applying to this the way you do. Anaphoric macros obviously don't exist to make programs easier to execute—they're there entirely for humans to read, though obviously the humans don't agree about them. To my mind, wanting a program to be readable by someone who hasn't learned its idioms is like wanting a newspaper to be readable by someone who hasn't learned its words. Some words are easy to guess from context, and that's nice. But others require learning, especially when a text isn't in your native language, and that doesn't make them unreadable.
- groovy2shoes 10y agoWell, newspapers are written at a middle-school reading level, or so I'm told. I disagree that anaphora are for readers. I think they're primarily for writers, as a convenience to save them some typing. The extra time spent reading `let-if` vs. `aif` is negligible, a small fraction of a second at worst. But, perhaps the disagreement comes from a fundamental difference in what each of us considers "readable". In my mind, readability is measured by the percentage of readers who comprehend what was written without aid. The amount of obviousness that such a goal demands not only requires explicity, but in my opinion it increases the ease of comprehension even for experts (so long as it's not something surprising to them -- e.g., I wouldn't go out of my way to write `let-if` in Arc since (iirc) it already provides `aif`, and that's what's expected by Arc programmers). On the other hand, I get the feeling that you rather view readability as the maximum of the ease of which each reader could comprehend what was written (not to put words in your mouth, please correct me if I'm wrong). I think that's an equally valid conception of the term, just not one that I share (or even really thought about before, to be honest).
- davexunit 10y agoAh yes, that is a use-case. Though, if I were to implement something like that, I would add an extra set of parens around (big-long-calculation) and specify the name to bind the value to: (aif (it (big-long-calculation)) (foo it))
- groovy2shoes 10y agoYep, that's how I do it in Scheme myself, though I've called the construct `let-if` :)