4 ms·
Eh, in lazily-evaluated languages such Haskell, there is much less need for macros.
by wnoise 15y ago
Eh, in lazily-evaluated languages such Haskell, there is much less need for macros.
- raganwald 15y agoTrue, but can't we say that about every non-trivial PL feature? For example, we could say that: In OOP languages such as Smalltalk, there is much less need for macros. The author's point is that programming languages are great when you're cutting with the grain, when you're working in the domain the author optimized the language around. But when you leave the domain, macros are an important tool. Don't get me wrong, I think that lazy evaluation is an incredibly valuable tool for separating what from how. But I wonder how it obviates the need for macros any more so than a well-defined OO system or any other non-trivial language feature.
- wnoise 15y agosedachv actually got my point. The standard need for macros rather than functions is to handle staged computations, distinguishing between names and objects. Lazy evaluation really does strike right at the heart of this, unlike something like "object system".
- kenjackson 15y agoClosures give you this (staged computations). Macros really give syntactic abstraction. That's it. That's nice, but you get the rest via other mechanisms.
- sedachv 15y agoClosures can't do partial evaluation, macros can.
- kenjackson 15y agoI wasn't trying to imply you can do everything with closures. But rather you could do lazy evaluation with it (I guess staged computations could include various forms of pre-rutime evaluation).
- dfox 15y agoIn my opinion, Smalltalk is prime example of language that is desperately missing macros. Most of Smalltalk code is boilerplate that is automatically generated by IDE, replacing this automatic generation with macros seems like natural thing to do. Smalltalk community seems to prefer to build complex tools to automatically generate and modify code in it's textual form, which I think is generally solving the wrong problem.
- sedachv 15y agoLazy evaluation gets rid of the need for one common macro pattern (conditional evaluation of an expression) and makes the macro/function mismatch go away (the (reduce #'macro arguments) kind of thing - although fexprs also avoid this problem). However, you need monads to express other patterns of control flow (exceptions and dynamic scoping, for example) that are possible with macros. The problem is that you have to do everything through bind. Macros don't have that restriction. But the one thing that makes macros irreplaceable is the fact that they can operate at compile-time. This is what I meant to emphasize when I wrote about automating programming.
- wnoise 15y agoI was in fact thinking of such common uses as the loop macro. > But the one thing that makes macros irreplaceable is the fact that they can operate at compile-time. "Sufficiently smart compiler" is the standard strawman argument. It's not a sufficient response, but it is actually pretty astounding what can be handled at compile time.
- sedachv 15y ago"I was in fact thinking of such common uses as the loop macro." Smalltalk has always done iteration this way with blocks (closures), and because of the syntax it works and looks nice. Of course this needs the "sufficiently smart compiler" to be efficient. But there's no way to program domain-specific knowledge into the compiler like you can with macros. For example Gerald Sussman has done a lot of work in optimizing numerical code symbolically (http://repository.readscheme.org/ftp/papers/berlinsurati-pepm94.pdf http://repository.readscheme.org/ftp/papers/berlinsurati-pep...), I think _On Lisp_ has a chapter about doing partial evaluation on Bezier curves, and there's some regex-specific tricks in CL-PPCRE that I don't think can be matched by generic partial evaluation.
- wnoise 15y agoI will have to take a look at these. I loved the flexibility they allowed when I first used them, but these days they often feel to me like going down a level in that more needs to be expressed. Yeah, if your tools can't efficiently handle your current case, that escape hatch is incredibly valuable.
- jpr 15y agoIn eagerly-evaluated languages such as almost-anything-other-than-Haskell, there is much less need for monads or other weird contraptions that make it difficult to reason about the behavior of the program. When Haskell fits the problem, it's very good, when it doesn't, you probably need to employ non-portable compiler tricks.
- Peaker 15y agoMonads are not related to laziness in any meaningful way. Monads are just a generalization of a commonly recurring pattern. All imperative languages can be said to have "monads" in the sense of having a "semicolon operator" (in some languages, that's just newline) that is the monadic bind. You're programming in one "ambient monad" whose power is fixed by the language itself. Haskell has an overridable semicolon, and that gives you a lot of DSL power. Instead of one "ambient monad", you have lots of user-defined monads useful for different purposes. Besides overridable semicolons, monads are just a plain useful abstraction of data structures. Monads are incredibly useful in a huge variety of programming tasks (non-determinism, effects, exceptions, parsing, and much more). They make Haskell code utilizing them far more broadly useful than code I've seen in any other language.