It is strange that the term macro is used to denote the chief metaprogramming facility in .Net. After all, macros in C++ are a lot weaker – they cannot manipulate the AST, in fact, they cannot even manipulate code internally or do compile-time evaluation.

Indeed we, as developers, can use the macro facilities in languages such as Boo in order to produce C-style macros. For example, here’s how one would instrument a Boo repetition macro in C style:

macro RepeatCStyle(c as int):
  return [|
    for i in range($c):
      $(RepeatCStyle.Body)
  |]

This macro simply serves as a syntactic shortcut, which means that if you call it with

RepeatXxx 3:
  print "Go"

you’ll basically get the following C# code:

int ___temp14 = 0;
while (___temp14 < 3)
{
  int i = ___temp14;
  ___temp14++;
  Console.WriteLine("Go");
}

You could have used an ordinary helper function in this case. The beauty of macros is in compile-time evaluation and effective inlining of code. Consider the following macro:

macro RepeatInline(c as int):
  body = RepeatInline.Body
  yieldAll body for i in range(c)

This macro is more interesting because it effectively returns three copies of the same statement as an IEnumerable. The end-result is the following C# equivalent:

Console.WriteLine("Go");
Console.WriteLine("Go");
Console.WriteLine("Go");

This is certainly much closer to the macros’ purpose as a metaprogramming tool.