views:

149

answers:

5

What exactly is the difference? It seems like the terms can be used somewhat interchangeably, but reading the wikipedia entry for Objective-c, I came across:

In addition to C’s style of procedural programming, C++ directly supports certain forms of object-oriented programming, generic programming, and metaprogramming.

in reference to C++. So apparently they're different?

+1  A: 

Generic programming usually refers to functions that can work with many types. E.g. a sort function, which can sort a collection of comparables instead of one sort function to sort an array of ints and another one to sort a vector of strings.

Metaprogramming refers to inspecting, modifying or creating classes, modules or functions programmatically.

sepp2k
+7  A: 

Metaprogramming, in a broad sense, means writing programs that yield other programs. E.g. like templates in C++ produce actual code only when instantiated. One can interpret a template as a program that takes a type as an input and produces an actual function/class as an output. Preprocessor is another kind of metaprogramming. Another made-up example of metaprogramming:a program that reads an XML and produces some SQL scripts according to the XML. Again, in general, a metaprogram is a program that yields another program, whereas generic programming is about parametrized(usually with other types) types(including functions) .

EDITED after considering the comments to this answer

Armen Tsirunyan
Yes, you can think of a template as a metaprogram, but you can't really do the same with e.g. java generics. So I would say: generic programming can be achieved using metaprogramming, but that's not the only way.
sepp2k
@sepp2k: Well, I specified templates in C++. But I agree that in other languages generic programming must not necessarily involve metaprogramming
Armen Tsirunyan
@sepp2k: this is a good point which I only implied in my answer as well. IMO an even better example than Java generics (which involve at least some cooperation from the compiler in type erasure) are generic functions in Common Lisp, in which dispatch is accomplished purely by inspection of the runtime type (IIRC, I'm not a Lisp expert, so correct me if I'm wrong).
Derrick Turk
@Derrick: The Lisp example sounds like methods in the Common Lisp Object System. There's macros, which do metaprogramming, but they expand at compile time. I'm not sure what "generic functions" means in CL.
David Thornley
@David Thornley: we're talking about the same thing. As I understand it, generic functions are defined/declared by `defgeneric` and implemented by methods (on a class-by-class basis) with `defmethod`. In other words, CLOS uses "generic function" to mean what most people mean by "method" or "virtual function" and "method" to mean the specific implementation.
Derrick Turk
+5  A: 

I would roughly define metaprogramming as "writing programs to write programs" and generic programming as "using language features to write functions, classes, etc. parameterized on the data types of arguments or members".

By this standard, C++ templates are useful for both generic programming (think vector, list, sort...) and metaprogramming (think Boost and e.g. Spirit). Furthermore, I would argue that generic programming in C++ (i.e. compile-time polymorphism) is accomplished by metaprogramming (i.e. code generation from templated code).

Derrick Turk
+2  A: 

Its best to look at other languages, because in C++, a single feature supports both Generic Programming and Metaprogramming. (Templates are very powerful).

In Scheme / Lisp, you can change the grammar of your code. People probably know Scheme as "that prefix language with lots of parenthesis", but it also has very powerful metaprogramming techniques (Hygenic Macros). In particular, try / catch can be created, and even the grammar can be manipulated to a point (For example, here is a prefix to infix converter if you don't want to write prefix code anymore: http://github.com/marcomaggi/nausicaa). This is accomplished through metaprogramming, code that writes code that writes code. This is useful for experimenting with new paradigms of programming (the AMB operator plays an important role in non-deterministic programming. I hope AMB will become mainstream in the next 5 years or so...)

In Java / C#, you can have generic programming through generics. You can write one generic class that supports the types of many other classes. For instance, in Java, you can use Vector to create a Vector of Integers. Or Vector if you want it specific to your own class.

Where things get strange, is that C++ templates are designed for generic programming. However, because of a few tricks, C++ templates themselves are turing-complete. Using these tricks, it is possible to add new features to the C++ language through meta-programming. Its convoluted, but it works. Here's an example which adds multiple dispatch to C++ through templates. http://www.eptacom.net/pubblicazioni/pub_eng/mdisp.html . The more typical example is Fibonacci at compile time: http://blog.emptycrate.com/node/271

Dragontamer5788
+4  A: 
  • Programming: Writing a program that creates, transforms, filters, aggregates and otherwise manipulates data.
  • Metaprogramming: Writing a program that creates, transforms, filters, aggregates and otherwise manipulates programs.
  • Generic Programming: Writing a program that creates, transforms, filters, aggregates and otherwise manipulates data, but makes only the minimum assumptions about the structure of the data, thus maximizing reuse across a wide range of datatypes.

As was already mentioned in several other answers, the distinction can be confusing in C++, since both Generic Programming and (static/compile time) Metaprogramming are done with Templates. To confuse you even further, Generic Programming in C++ actually uses Metaprogramming to be efficient, i.e. Template Specialization generates specialized (fast) programs from generic ones.

Also note that, as every Lisp programmer knows, code and data are the same thing, so there really is no such thing as "metaprogramming", it's all just programming. Again, this is a bit hard to see in C++, since you actually use two completely different programming languages for programming (C++, an imperative, procedural, object-oriented language in the C family) and metaprogramming (Templates, a purely functional "accidental" language somewhere in between pure lambda calculus and Haskell, with butt-ugly syntax, since it was never actually intended to be a programming language.)

Many other languages use the same language for both programming and metaprogramming (e.g. Lisp, Template Haskell, Converge, Smalltalk, Newspeak, Ruby, Ioke, Seph).

Jörg W Mittag