Metaprogramming is absolutely necessary for a good (general purpose) programming language, CMV
It doesn't have to be full-blown macros, but some kind of metaprogramming, such a closures, is necessary to make the language sufficiently extensible.
Edit: well, one thing I learned is that people don't consider Higher Order Functions metaprogramming, which, to me, is weird, but I guess that's a thing.
Edit2: In fact, people really don't want to call HOFs metaprogramming.
Posted May 17, 2013, 10:18 AM UTC · edited
Sidenote: There's absolutely nothing meta about closures/higher order functions so I won't argue against them, metaprogramming should strictly mean staged code generation, even if the staging isn't as refined/powerful as MetaML/Racket/Scheme or even CL. I feel like I should do a CMV about this.
While metaprogramming is a really convenient, you can get by a lot with the right combination of higher order functions, purity, totality, (dependent) types and laziness.
Why HOFs are useful here, hopefully, should be preaching the choir. Constructs that required macros without them (while, for, ...) can be rewritten easily as a HOF.
Laziness helps for "short-circuiting" constructs such as if, and, or, ..., and is quite well known as well.
Purity and types let you encode many meta-ish constructs in the language itself. In Haskell you see often people talking about "base functors" and "
Fix", which let you represent datatypes and write generic programs on those datatypes (like generalizedfmap,fold, ...). With dependent types, you can encode a micro type system in the type system (called a universe), write generic programs on the representation of types, and bring them back into the "normal" types. Totality just helps with dependent types.As a point in my favor, Haskell's doing pretty well without metaprogramming, the most common use of Template Haskell is in the lens library, but even there it's just a convenience macro and not necessary.
I agree with most of that, except that I would claim closures are a kind of metaprogramming. First, there's the fact that they give many of the practical advantages that macros do. Secondly, on a more theoretical note, closures are the internal Hom-sets of a category, what could be more meta than that?
Well, that's cheating. Laziness also gives many of the same advantages, or even anonymous classes in Java, but I wouldn't call them meta.
Something that, taken as a logical construct, lets you encode the ω-rule, a metalanguage which can manipolate the syntax of the language in the language, a metatheory in the theory.
Laziness is, for the purposes we are talking about, slightly more convenient lambdas (for certain things). Anonymous classes in Java are, for the purposes we are talking about, much more inconvenient lambdas.
Depending on how you Curry-Howard the omega-rule, that can mean multiple things. Can I see an implementation using macros?
That's like saying that strings are really inconvenient anonymous functions because you can write an
evalfor strings that represent lambda terms. How much is too much?In MetaML/Agda-ish syntax, it would (probably, I'm not an expert) have one of these two types:
There are two kinds of metaprogramming here. One is code generation, like you can do in MetaML, Lisp, etc. The other is introducing syntactic sugar, like C macros, Lisp macros, camlp4, and I suppose closures and laziness can in some cases be used to similar effect. From a language design perspective, it's a good idea to separate the two. Code generation is purely about performance. Syntactic sugar is purely about convenience in expression.
Now it is the case that in some languages, you can express things with code generation that you cannot express without it. For example in template haskell you can generate new data types, and in that way you can express things that you couldn't otherwise. IMO that is a bad conflation of concerns. You should be able to remove the staging and end up with working code (except possibly slower). For example in dependently typed languages you can; since types are just values you can generate new types with ordinary expressions like you can with quotation expressions in template haskell.