Virtually all programming languages have functions of some sort (whether they are called functions, procedures, subprograms, methods, messages, routines, or even processes); the function is a concept derived from mathematics and a good way to factor out commonality. Many (though not all) programming languages also have macros (some, like CeePlusPlus, have multiple macro systems - C++ has two; one type of macro is introduced with #define, the other type with template<>).
Functions are not a controversial feature (though some in the OO camp feel that they should be made subservient to objects; nobody suggests getting rid of them.) Macros are a bit more controversial; many computer scientists are known to dislike and distrust "preprocessors". Much of this has to do with the CeePreprocessor, widely regarded as one of the worst macro processors in widespread use. Other programmers, particularly those from a Lisp background, love macros - and both CommonLisp and SchemeLanguage have very powerful (though differing) macro systems.
This page lists key differences between functions (including "member functions" in OO languages) and macros (including CeePlusPlus templates).
- Function arguments are either passed using StrictEvaluation (most imperative/OO languages) or LazyEvaluation (certain lazy functional languages; optional in SchemeLanguage) semantics. Macro arguments are generally passed with NormalOrderEvaluation semantics (also known as CallByName); meaning the argument is re-evaluated each time it is used. Normal order is quite powerful; it can be very tricky to use and have surprising effects (this is why min (a++,b++) and such don't do what the user expects in CeeLanguage). Normal order also requires use of CallByThunk when used with functions. Only one language I'm aware of (AlgolSixty) has implemented normal order with functions; this has long been regarded as a mistake. This was done, incidentally, to simulate macros. SmalltalkLanguage, by use of blocks, provides a nice, convenient, and OO-friendly way of rolling-your-own thunks (SmalltalkBlocksAreThunksInDisguise); thus allowing messages to conveniently simulate usually-inline control structures such as conditionals or loops.
- The body of a function is always a separate scope, both from its caller(s) and from the scope it was defined in. Many languages allow FreeVariables? in functions; but few implement shallow binding or DynamicScoping; thus are very limited in how they can inspect and manipulate the context surrounding the function call. (Which is widely considered a GoodThing). Macro invocations usually don't introduce a new scope (unless the macro definition explicitly creates one); most macro systems act similarly to ShallowBinding. Scheme's HygienicMacros are unusual in that they use DeepBinding - cleaner in most ways; though occasionally ShallowBinding is what you want.
- Macros are more tightly coupled to their invokers than are functions. A routine can call a function without knowing how it is implemented - even without knowing that it exists. A macro's definition must be available at the point where it is invoked.
- Function evaluation is generally deferred to run-time; though many language implementations will evaluate functions at read-time/compile-time (as an optimization) if it is known that this can be done correctly. Macro evaluation is (almost?) always done at read time. Even in languages which can compile new code at runtime; macro processing is done while the code is read, not while the code is run.
- Functions work at the semantic level of the language; macros work at either the syntactical level of the language (LispMacros, C++ templates) or at the lexical level (CeePreprocessor). Macros are generally untyped; though modern macro systems, as found in <Bigwig> or NeedleLanguage, can use "syntax types" (nonterminals in the grammar) as types. In their most general form, macros are essentially functions that produce program code (as text or in AbstractSyntaxTree form) as output.
- In some languages, individual macros can consist of ill-formed program fragments, provided the resultant program as a whole is well-formed. As a trivial case, consider a trick to make C look a bit more like Pascal:
#define begin {
#define end }
Obviously, begin and end in isolation are not well-formed program fragments; consisting of unbalanced curly braces. Used together, they are fine. Functions certainly cannot do this sort of thing.
- Functions can support dynamic binding. Macros, no (given that they are evaluated at compile-time, dynamic binding wouldn't make sense anyway).
- Excluding languages with eval() (can compile and run program fragments at runtime), macros are always evaluated at CompileTime/read-time. As such, many like to use macros as a hand-optimization; on the other hand, macro results cannot depend on program inputs.
Are macros only for efficiency?
No; since macros work at the syntactical or lexical level; they can be used in contexts where functions cannot; and can accept arguments that functions cannot. Use of macros solely for efficiency is probably an AntiPattern - at least in more modern languages that either support inline declarations or perform inlining as an optimization.
My personal opinion: Use functions when you can, macros when you have to. However, there are times when you have to; so eliminating macros entirely weakens a language. That said, many powerful languages have no macro facility whatsoever.
In addition to the usual gripes about the CeePreprocessor, BertrandMeyer makes some arguments against macros in ObjectOrientedSoftwareConstruction. Don't have my copy handy at the moment... WillFillInLater?.