5 ms·
I forgot about lenses, thanks. About non-locality of macros vs. functions: Macros, being functions, provide this kind of assurance, too at the syntax tree lev
by ICWiener 12y ago
I forgot about lenses, thanks.
About non-locality of macros vs. functions:
Macros, being functions, provide this kind of assurance, too at the syntax tree level: you only operate on the local, current subtree.
They can indeed modify the meaning of symbols in that subtree, but I think you are taking things to the extreme. Off course, an arbitrarly nasty macro "far up in the tree" (how deep are the typical functions, anyway?) could do horrible things. Also, we must ban sugar because if someone eats too much sugar, that someone dies.
However, the average usage is more subtle.
For example, when you DEFUN a function, you are registering a function in your current environment (side-effects) through a macro, which does not dramatically change the semantics of the body of the function, compared to, say, an anonymous LAMBDA (the only change is, I think, the ability to RETURN-FROM a named function).
CL is not a functional language: you can loop over lists or across vectors, you can setf special variables and mutate strings. You have static and dynamic non-local exits (return, throw/catch, signal) and even goto's (tagbody). That does not mean that you should use them all and go against best practices and common sense.
Just because a feature could be misused does not make it irrelevant.
For the record, I have nothing against functional languages (or any other language, really (except of course PHP ;-)). It just seem unfair to attack macros. They should be avoided whenever possible, but they have some uses: C (macros), C++ (templates), and even Haskell and Scala try to have them:
http://scalamacros.org/usecases/index.html http://scalamacros.org/usecases/index.html
https://downloads.haskell.org/~ghc/7.6.1/docs/html/users_guide/template-haskell.html https://downloads.haskell.org/~ghc/7.6.1/docs/html/users_gui...
http://neilmitchell.blogspot.fr/2007/01/does-haskell-need-macros.html http://neilmitchell.blogspot.fr/2007/01/does-haskell-need-ma...
Finally: macros are not a hack used to fix a supposedly missing feature of the language (e.g. "I don't need macros because I have lazy evaluation", etc.). Macros allow programmers to interact with the compiler (reader macros, compiler-macros): they are the primitive provided to perform meta-programming tasks.
- lmm 12y agoYeah, I think they're a mistake in Scala too. Hopefully I'm wrong. I think "the primitive" is a good characterization; I view writing a macro the same way I view using a mutex directly, or as I said, goto (or, less trollishly, manually expressing a program in continuation-passing-style). That is, these things are occasionally necessary, but it's usually a sign that your higher-level constructs are inadequate.
- agentultra 12y ago> That is, these things are occasionally necessary, but it's usually a sign that your higher-level constructs are inadequate. Could you clarify with some examples? What constructs are you referring to that are inadequate?
- lmm 12y agoIf you're using a mutex directly, it's because your higher-level concurrency constructs - task queues, actors etc. - are inadequate. If you're using goto, it's because your higher-level control flow constructs - if/for/while, exceptions - are inadequate. Likewise if you're using macros, I'd argue it's usually because your within-language constructs are inadequate; things like LINQ (which I've seen people use macros to emulate in other languages) are important and common enough that there should be a standard way of doing them in the language.
- agentultra 12y agoMaybe I'm not seeing the forest for the trees here but I still don't understand what constructs you are referring to which are inadequate. Most Lisps are built from a very small selection of "special forms" and the rest is built in Lisp itself. From this perspective it's not a very large language at all. Is there a specific construct you had in mind? Mutexes, goto... I'm afraid I don't understand. CL, for example, is an ANSI specification and makes no mention of threads or threading. That hasn't stopped implementations from providing OS support for threading and library authors from maintaining cross-implementation compatibility libraries. Mutexes are just one well-known method for solving a very specific problem with shared-memory threads. It's not even a primitive in the language itself. Macros helped us make threading possible without having to call together a new ANSI committee to extend the language specification. In a similar vein I'm sure there are plenty of LINQ packages available in CL with all of the attendant parallelization patterns, etc.
- lmm 12y ago> Is there a specific construct you had in mind? No, what I have in mind is the things people use macros for. I've talked about assignment or LINQ; maybe you should talk about a specific case where you think macros are a good solution? > Macros helped us make threading possible without having to call together a new ANSI committee to extend the language specification. ANSI committees aren't just for fun. Maybe you should've called one - threading is a pretty fundamental language feature and worth standardizing across all implementations.