I think this is not quite Matthias's point about laziness. The point is that Haskell programmers generally (are supposed to) program as if they don't care what order things are evaluated in, so the ability of macros to change that order isn't relevant to them. (Of course, this is foolish for a number of reasons -- serious Haskell programmers to have to care what order things are evaluated in (cf seq).)
That said, I also think this thread is kind of heading down the wrong path. This way of thinking about what is important about macros was the best understanding we had a decade or two ago. I think that our experience with racket, however, has proven that the right way to think about the value of macros is to think of them as giving access to an extensible/open compiler and thus we can more easily design and build new programming languages. In other words, it's all about acknowledging that there is no best language so what we really need is the ability to more easily build new ones that fit new kinds of computations we want to do. Robby On Fri, Apr 8, 2016 at 8:27 AM, Alex Knauth <alexan...@knauth.org> wrote: > >> On Apr 8, 2016, at 7:10 AM, Norman Gray <nor...@astro.gla.ac.uk> wrote: > >>>> I'd like to propose that there are three disciplined uses of macros: >>>> >>>> 1. data sublanguages: I can write simple looking expressions and >>>> [...] >>>> >>>> 2. binding constructs: I can introduce new binding constructs with >>>> [...] >>>> >>>> 3. evaluation reordering: I can introduce constructs that delay/postpone >>>> [...] >>>> [Note: In Haskell, you don't need that one.] >> >> This is a seriously naive question, because I have only trivial experience >> with Haskell (and by extension other lazy languages), but aren't each of >> these things that you can do with a lazy language? >> >> If I can control when an expression is evaluated, then I can obviously do >> (3), > > For "evaluation reordering," it means that with macros, you could take a > strict language and make it lazy, *or* take a lazy language and make it > strict. Or you could probably do other, weirder things that I can't think of > right now. Haskell has forms for making specific things strict, but it's not > the default. Whatever the default is, you can change it with macros. So in > Haskell this category of macros would still exist, but `delay` wouldn't be > one of them. I think macros like `do` that that insert monad threading would > also be in this category? > >> but supposing I can also control the environment within which it's >> evaluated, can't I also do (2) > > In a language with static scope, no, I don't think so. In racket, haskell, > and most other languages, you always know at compile time what identifiers > are bound. You could never have an identifier that could be bound at runtime, > because the compiler would have seen that identifier and raised an error, at > compile time. > > It's because of this compile-time knowledge that programmers can look at a > program without running it, and still understand it. And also it's because of > this that DrRacket can look at a program without running it, but still draw > check-syntax arrows, or safely rename identifiers, jump to a definition, or > lookup documentation. > > Since macros that define new binding constructs are normally defined in terms > of existing binding constructs, the programmer still has all of this > knowledge at compile time, and DrRacket can still provide all those tools. > Because of that, both programmers and DrRacket can understand programs. > > If this could change at runtime, most of this would go away. But to use > laziness to create new binding constructs without macros, that's what you > would have to do. > > Alex Knauth -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.