Hacker News new | past | comments | ask | show | jobs | submit login

> because ordinary Lisp functions are limited in how they can work with "context-dependent code fragments" passed as arguments. Rebol attacks this problem by making bindings of individual symbols "travel along" with their code fragments. The result is that many cases requiring macros in Lisp can be written as ordinary Rebol functions.

Bzzt, no. "Context dependent code fragments" are "lambdas" in mainstream Lisp dialects, which carry the environment (i.e. bindings of symbols) via lexical closure.

Now, indeed, one of the uses of macros is to provide some (usually mild) sprinkling of syntactic sugar to conceal lambda syntax.

> But packing code into a [functional/lambda] "black box" creates barriers to transformations that are a big part of the appeal of using a homoiconic language.

The history of Lisp has recorded considerable experience with the FEXPR approach to language extension. Lispers had worked out decades ago that this largely sucks, and so interest in FEXPRs waned. They do not appear as a feature in Scheme or Common Lisp, and it's not for lack of knowledge or experience.

Essentially, Lisp performed a "Rebol-ectomy" on its semantics by the end of the 1960's or thereabouts.

Anyway, to understand macros fully, you have to step out of the role of language user and put on a "compleat hacker" hat. Suppose you have complete control at your disposal: you can hack any aspect of the language, as deeply in the implementation as you want. You can add new features that cannot be made out of anything which is already there. In spite of that control, you still want macros. Because macros let you separate the concern of designing the low-level abstractions that are the most convenient for a given feature, and a user interface to them which is nice for the user. (Without macros, you face the annoyance of having to extend the repertoire of special operators, even in situations when it is obvious that these new ones should just expand to some other syntax in terms of functions, plus the old ones).

If I'm extending a language deeply at the implementation level, I'm doing something that can't be done with macros or functions anything else; yet macros help in a specific way that other things don't. I still want them in spite of having total control. If I add non-strict evaluation into the language core, I want macros. If I add continuations, I want macros. If I add functional reactive programming, I still want macros, etc. Macros mean I don't have to go into the compiler, or code walker or elsewhere and add new cases to handle special operators. I don't have to go into the grammar of some parser generator to add the syntax, where the parser action is just "construct a node for this new syntax, exactly like some equivalent longer expression would generate".

(If you say you already have all the syntax you would ever need and everything else is just done with that syntax, then you are not wearing the "compleat hacker" hat.)

Applications are open for YC Summer 2021

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