6 ms·
Most of the complaints in this article boil down to "macros are too powerful." I think this is the key part of the argument: "A smart programmer is not necessa
by lkrubner 13y ago
Most of the complaints in this article boil down to "macros are too powerful." I think this is the key part of the argument:
"A smart programmer is not necessarily an empathetic language designer; they are occupations that require different skillsets. Giving any programmer on your team the ability to arbitrarily extend the compiler can lead to a bevy of strange syntax and hard-to-debug idiosyncrasies."
There are at least 2 counter-arguments to this:
1.) in the simplest case, just restrict the use of macros. A team can easily adapt the rule that only the most experienced engineer on the team is allowed to write or approve macros. (And in my experience, the need for macros is fairly rare. I think my ratio is something like 100 or 200 normal functions for every macro that I write.)
2.) macros allow all kinds of interesting type checking, and data structure validation, and therefore they make it surprisingly easy to validate data and types as your data and/or vars get passed around your system. Consider all of these very interesting tools you can use in the world of Clojure:
Prismatic Schema which allows validation that a data structure matches a schema of (possibly nested) types:
https://github.com/prismatic/schema https://github.com/prismatic/schema
and this now offers coercion, which makes this fantastic for importing JSON from other sub-systems or outside vendors:
http://blog.getprismatic.com/blog/2014/1/4/schema-020-back-with-clojurescript-data-coercion http://blog.getprismatic.com/blog/2014/1/4/schema-020-back-w...
(I assume you could easily validate before giving data to Liberator to export your data while conforming to your schema: http://clojure-liberator.github.io/liberator/ http://clojure-liberator.github.io/liberator/ )
There is work being done on an optional type system:
https://github.com/clojure/core.typed https://github.com/clojure/core.typed
Much effort has been made to make contract programming easy in Clojure:
https://github.com/clojure/core.contracts https://github.com/clojure/core.contracts
But also I find the built-in syntax for writing pre and post assertions is clean and easy to use:
http://blog.fogus.me/2009/12/21/clojures-pre-and-post/ http://blog.fogus.me/2009/12/21/clojures-pre-and-post/
In short, there are an abundance of mechanisms available with Clojure which help facilitate the enforcement of any kind of schema or contract, and some of these tools are enabled (and their syntax is made clean) thanks to macros.
In short: macros can be used for evil, but they can also be used for good. They are very powerful, so everyone should be judicious about their use, but there is no reason to argue that macros render a Lisp unfit for programming in the large.
Having said all that, I'll remind everyone that the ultimate counter-argument is offered by Paul Graham, in his essay "Beating the averages":
http://www.paulgraham.com/avg.html http://www.paulgraham.com/avg.html
If that essay does not convince you of the value of macros/lisp, then nothing will.
- _delirium 13y agoI mostly agree but fwiw, the usual counterargument on #2 is that those should be language facilities instead, which allows them to be carefully designed and then taken advantage of by the compiler. For example, in Racket (formerly PLT Scheme) you have: http://docs.racket-lang.org/guide/contracts.html http://docs.racket-lang.org/guide/contracts.html
- nickik 13y agoThe problem with this argument is, that you will never have the amount of independned development on every feature. There are usually only a relativly small amount of people at the core of a langague. If I want a new feature in the language is very hard to get it in and once its in its in. With macros diffrent people can do there own thing and indepently develop it. Look for example at core.match, in every other language something like it would have been a new language feature. Clojure now has a state of the art pattern matcher without Rich or anybody doing anything.
- philh 13y agoI'm not sure how well that specific example works. Are contracts built in to the language on a fundamental level, or are they just part of the standard library? Given that they're not included in racket/base, and given how flexible racket's core is, I would guess the latter, but I'm not sure.
- innguest 13y ago"Are contracts built in to the language on a fundamental level, or are they just part of the standard library? " One of the points of Lisp is that that difference doesn't matter. But besides that, in this case it couldn't possibly matter. You write contracts for your functions. If they're violated at runtime you'll get a clear error that stops execution to contain damage, and assigns blame to the contract violator. At what point in that process does it matter whether contracts are "built into the language"?
- philh 13y ago