9 ms·
One qualitative difference in expressive power comes from the fact that functions first evaluate all their arguments and macros don't.
by dfan 11y ago
One qualitative difference in expressive power comes from the fact that functions first evaluate all their arguments and macros don't.
- kazinator 11y agoAh, but that is not the case in some languages in which arguments are evaluated lazily. Usually the iron-man version of this question is: "if I have a non-strictly evaluated language with higher order functions, do I still need macros?" A part of the answer is: you probably don't need the kinds of macros which cover up machine-generated lambdas, which simulate non-strict evaluation in strictly evaluated Lisp programs! The compiler for your language already has these "macros" in its compiler. The argument why "you always need macros no matter what else you have" is that your language has "hard-coded macros": the grammar rules in a compiler, which match patterns and transform bits and pieces to produce AST fragments. If you don't have macros, then that set of "hard-coded macros" is all you have. So, even in a functional language with nonstrict evaluation, you're using macros. It's hard to make a convincing argument that they provide all the expressivity you would conceivably ever need. (And their existence and use defeats any argument that you don't need macros at all).
- the_af 11y agoI'm not entirely convinced. Which definition of "macro" are you using, if you equate lazy evaluation with a kind of "hardcoded macro"? More importantly, "it's hard to make a convincing argument that [these hardcoded macros] provide all the expressivity you would conceivably ever need" doesn't convince me. A better argument would be to produce a compelling example where these "macros" are not enough. And by compelling, I mean something that cannot be elegantly produced in a non-Lisp language.
- kazinator 11y ago> Which definition of "macro" are you using, if you equate lazy evaluation with a kind of "hardcoded macro"? That definition of "macro" equivalent with "phrase structure rule in your functional language's compiler" which takes the input structure and generates whatever code brings about the lazy semantics (which is not inherent in the x86 instruction set or what have you). > example where these "macros" are not enough An example is any instance of language extension where, say, the maintainers of the compiler for a functional language have to ship a new compiler to the users to get them to use the new feature. Functional languages with lazy evaluation are not finished, right? They are developed actively.
- the_af 11y ago> An example is any instance of language extension where, say, the maintainers of the compiler for a functional language have to ship a new compiler to the users to get them to use the new feature. > Functional languages with lazy evaluation are not finished, right? They are developed actively. Agreed, they are actively developed. Correct me if I'm wrong, but you seem to be saying "many interesting features can be implemented in a Lisp language with a macro, therefore Lisp programmers don't need to wait for a new release of their programming language when they want these features". I'm not convinced this is the case, or rather, that this is such a relevant case. Aren't Lisps actively developed too? Why is there such a multitude of Lisp implementations? Is any relevant real-world feature truly implementable with Lisp macros? Why is that more convenient than implementing them with functions in languages with lazy evaluation? Maybe I'm falling prey to the Blub paradox. I'm only passingly familiar with Racket, thanks to a course in Coursera, where they introduce macros and why they are so powerful in Lisp. But I still don't see the compelling "killer example"...
- kazinator 11y ago> Correct me if I'm wrong, but you seem to be saying "many interesting features can be implemented in a Lisp language with a macro, therefore Lisp programmers don't need to wait for a new release of their programming language when they want these features". That is correct. However, macros have to translate to something. From time to time you need an upgraded something for some macros to be feasible. E.g. it's hard to "macro your way" into having first-class continuations, if they aren't in the substrate. That is to say, without the macro treating all of its arguments as a self-contained language. You usually want the code which is in the macro forms to smoothly interoperate with outside code, such as make lexical references to surrounding bindings. This is the fuzzy limit. Macros have to write stuff in some language, which is no longer macro-expandable. That language has to be reasonably expressive in its semantics for what the macros want to do.
- rapala 11y agoOne could write a macro that allows infix notation for arithmetics: (arithmetics 1 + 2 - 3) = (- (+ 1 2) 3) These kind of syntactic transformations are what macros enable.