Macros
Alan Bawden <[EMAIL PROTECTED]> writes: > A macro facility is like a pair of vise-grips (if you don't know what > those are, see http://www.technogulf.com/ht-vise.htm). I found myself laughing heartily at this apt analogy. I have heard vice grips described as "the wrong tool for every job." (My own experience with vice grips backs this up). That being said, there are a number of things one might want out of a macro facility, and I think they should be carefully distinguished: 1) The ability to name expressions without evaluating them, e.g. to cook up a facsimile of laziness. 2) The ability to parrot source code (and maybe source position) back at the user, e.g. Alan's assert macro, or its C equivalent. 3) The ability to create new binding constructs. 4) The ability to create new declaration constructs. (1) is pretty well covered by lazy evaluation. For (2), I wonder if a clever set of compiler-supplied implicit parameters might do the trick---after all, "the position of expression e" and "the source code of expression e" are dynamic notions that could be carefully defined. (3) is trickier. Contrast monadic code before and after "do" notation was introduced. Haskell made it possible---not even very hard---to do monadic binding, but there was a good deal of ugly syntactic noise. The introduction of "do" notation eliminated that noise. My instinct is that this isn't so easy for things that can't be shoehorned into a monad. For example, I use the Utrecht attribute grammar tool, and have trouble imagining how grammars could be coded in pure Haskell while preserving nice naming properties. (4) is harder still. Polytypic classes are a huge step in the right direction. What I most long for, though, is the ability to synthesize new types and new classes---not just simple instance declarations. As you can probably guess, I think (3) and (4) are the most profitable avenues of exploration. And I'm pretty sure I _don't_ want syntax macros for these. I'm still waiting to be convinced what I do want. -Jan-Willem Maessen Eager Haskell project [EMAIL PROTECTED] ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Implict parameters and monomorphism
Fri, 4 May 2001 16:16:29 -0400, Dylan Thurston <[EMAIL PROTECTED]> pisze: > I'm not sure I understand here. One thing that occurred to me reading > your e-mail was that maybe the implicit universal quantification over > type variables is a bad idea, and maybe type variables should, by > default, have pattern matching semantics. Only for type signatures on patterns and results. It's a ghc/Hugs extension. You can write: f' arr :: ST s (a i e) = do (marr :: STArray s i e) <- thaw arr ... These type variables have the same scope as corresponding value variables. The s,i,e in the type of marr refer to the corresponding variables from the result of f'. You could bind i,e to new names in marr, but not s. (Well, now I'm not sure why there is a difference...) Type variables from the head of a class are also available in the class scope in ghc. You use bound type variables in ordinary type signatures on expressions and let-bound variables in their scope. Unbound type variables in these places are implicitly qualified by forall, I don't want to change this. Some people think that type variables used in standard type signatures (expressions and let-bound variables) should be available in the appropriate scope. I don't have a strong opinion on that. -- __("< Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Macros
Date: Thu, 3 May 2001 18:09:01 -0500 (EST) From: Dan Knapp <[EMAIL PROTECTED]> > > (if (not (< x 3)) > > (assertion-failed '(< x 3))) > > This is a good example, which cannot be implemented in > Haskell. "Exception.assert" is built in to the ghc compiler, rather than > being defined within the language. On the other hand, the built in > function gives you the source file and line number rather than the literal > expression; the macro can't do the former. Yeah, it's a good example, but are there any other uses for such quoting? There are a few. But this isn't the -only- reason to still use macros. We could systematically go through all the macros I've written in the last few years, and for each one we could figure out what language feature would be needed in order to make that macro unnecessary. At the end of the process you would have a larger programming language, but I still wouldn't be convinced that we had covered all the cases. A macro facility is like a pair of vise-grips (if you don't know what those are, see http://www.technogulf.com/ht-vise.htm). You can do a lot of things with a pair of vise-grips, although usually there's a better tool for the job -- if you haven't got (say) a pipe-wrench, then a pair of vise-grips can substitute. Now the more tools you have in your tool box, the less often you will use your vise-grips. But no matter how bloated your tool box becomes, you will still want to include a pair of vise-grips for the unanticipated situation. I have one problem with my own analogy: If you find yourself using your vise-grips everyday for some task, you will probably soon go and purchase a more appropriate tool. But I think that in many circumstances macros do such a good job that I don't see the need to clutter up the language with the special-prupose features needed to replace them. Date: Fri, 04 May 2001 12:57:29 +0200 From: Jerzy Karczmarczuk <[EMAIL PROTECTED]> ... I think that they are less than popular nowadays because they are dangerous, badly structured, difficult to write "hygienically" Indeed, you can screw up pretty badly with a pair of vise-grips! A friend of mine used to say that programmers should have to pass some kind of licensing test before they would be allowed to write Lisp/Scheme macros. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Implict parameters and monomorphism
On Fri, May 04, 2001 at 07:56:24PM +, Marcin 'Qrczak' Kowalczyk wrote: > I would like to make pattern and result type signatures one-way > matching, like in OCaml: a type variable just gives a name to the given > part of the type, without constraining it any way - especially without > "negative constraining", i.e. without yielding an error if it will > be known more than that it's a possibly constrained type variable... I'm not sure I understand here. One thing that occurred to me reading your e-mail was that maybe the implicit universal quantification over type variables is a bad idea, and maybe type variables should, by default, have pattern matching semantics. Whether or not this is a good idea abstractly, the way I imagine it, it would make almost all existing Haskell code invalid, so it can't be what you're proposing. Are you proposing that variables still be implicitly quantified in top-level bindings, but that elsewhere they have pattern-matching semantics? Best, Dylan Thurston ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Macros (Was: Interesting: "Lisp as a competitive advantage")
Fri, 04 May 2001 12:57:29 +0200, Jerzy Karczmarczuk <[EMAIL PROTECTED]> pisze: > In Clean there are macros. They are rather infrequently used... I think they roughly correspond to inline functions in Haskell. They are separate in Clean because module interfaces are written by hand, so the user can include something to be expanded inline in other modules by making it a macro. In Haskell module interfaces are generated by the compiler, so they can contain unfoldings of functions worth inlining without explicit distinguishing in the source. -- __("< Marcin Kowalczyk * [EMAIL PROTECTED] http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Macros (Was: Interesting: "Lisp as a competitive advantage")
Jerzy Karczmarczuk <[EMAIL PROTECTED]> writes: > Macros in Scheme are used to unfold n-ary control structures such as COND > into a hierarchy of IFs, etc. Nothing (in principle) to do with laziness > or HO functions. Isn't this exactly the reason that macros are less necessary in lazy languages? In Haskell you can write myIf True x y = x myIf False x y = y and then a function like recip x = myIf (abs x < eps) 0 (1 / x) works as expected. In Scheme, (define myIf (lambda (b x y) (if b x y))) does *not* have the desired behaviour! One can only write myIf using macros, or by explicitly delaying the arguments. --KW 8-) ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Macros (Was: Interesting: "Lisp as a competitive advantage")
Discussion about macros, Lisp, laziness etc. Too many people to cite. Alan Bawden uses macros to write assertions, and Dylan Thurston comments: ... > > (assert (< x 3)) > > > > Which macro expands into: > > > > (if (not (< x 3)) > > (assertion-failed '(< x 3))) > > > > Where `assertion-failed' is a procedure that generates an appropriate error > > message. The problem being solved here is getting the asserted expression > > into that error message. I don't see how higher order functions or lazy > > evaluation could be used to write an `assert' that behaves like this. > > This is a good example, which cannot be implemented in > Haskell. "Exception.assert" is built in to the ghc compiler, rather than > being defined within the language. On the other hand, the built in > function gives you the source file and line number rather than the literal > expression; the macro can't do the former. > > --Dylan Thurston In general this is not true, look at the macro preprocessing in C. If your parser is kind enough to yield to the user some pragmatic information about the read text, say, __LINE etc., you can code that kind of control with macros as well. Macros in Scheme are used to unfold n-ary control structures such as COND into a hierarchy of IFs, etc. Nothing (in principle) to do with laziness or HO functions. They are used also to define object-oriented layers in Scheme or Lisp. I used them to emulate curryfied functions in Scheme. I think that they are less than popular nowadays because they are dangerous, badly structured, difficult to write "hygienically". Somebody (Erik Meijer?) asked: "Don't you get dynamic scoping as well with macros?" Well, what is dynamic here? Surely this is far from "fluid" bindings, this is a good way to produce name trapping and other diseases. In Clean there are macros. They are rather infrequently used... In C++ a whole zone of macro/preprocessor coding began to disappear with the arrival of inlining, templates, etc. I think that macros belong to *low-level* languages. Languages where you feel under the parsing surface the underlying virtual machine. You can do fabulous things with. My favourite example is the language BALM, many years before ML, Haskell etc., there was a functional, Lisp-like language with a more classical, Algol-like syntax, with infix operators, etc. The language worked on CDC mainframes, under SCOPE/NOS. Its processor was written in assembler (Compass). But you should have a look on it imple- mentation! Yes, assembler, nothing more. But this assembler was so macro- oriented, and so incredibly powerful, that the instructions looked like Lisp. With recursivity, parentheses, LET forms which allocated registers, and other completely deliciously crazy constructs. In fact, the authors used macros to implement the entire Lisp machine, used to process BALM programs. //Side remark: don't ask me where to find BALM. I tried, I failed. If *YOU* find it, let me know// Another place where macros have been used as main horses was the MAINBOL implementation of Snobol4. But when people started to implement Spitbol etc. variants of Snobol4, they decided to use more structured, higher-level approach (there was even an another, portable assembler with higher-level instructions "embedded"; these avoided the usage of macros). Jerzy Karczmarczuk Caen, France ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Interesting: "Lisp as a competitive advantage"
Hello! On Thu, May 03, 2001 at 06:09:01PM -0500, Dan Knapp wrote: > [...] > Yeah, it's a good example, but are there any other uses for such quoting? > If not, then implementing it as a builtin is perfectly adequate. (Not > trying to pick on Lisp; Lisp is great. Just hoping for more examples.) IMHO you can do all the things you'd do with separate preprocessing steps for other languages with Lisp macros, inclusing scanner/parser generating for some example. Or you could do the analogous thing to camlp4 in Lisp with Lisp's own standard features (reader macros + normal macros). You can e.g. also emulate Emacs Lisp in Common Lisp by slightly hacking up the readtable and defining a few macros and functions into a separate package. That's quite easy, in fact, the more complicated part would be offering all those primitive functions of Emacs Lisp, but if you had this, you could compile all those Emacs Lisp packages into fast code. Imagine GNUs *not* crawling like a snail on a Pentium 200 *g* Kind regards, Hannah. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe