Take the 2-minute tour ×

I have been reading about the libraries people have written for languages like Java and C# that make use of byte code weaving to do things like intercept function calls, insert logging code, etc. I have also been reading up on Lisp/Clojure macros in an attempt to better understand how to utilize them. The more I read about macros, the more it seems like they provide the same kind of functionality as byte code weaving libraries. By functionality, I mean the ability to manipulate code at compile time.

Examples of libraries I have been looking at would be AspectJ, PostSharp, and Cecil.

Is there anything that can be done with one and not the other? Do they actually solve the same problems or am I comparing apples and oranges?

share|improve this question
byte code weaving is a work-around when you need a dynamic language but are stuck with a statically typed language –  kevin cline Mar 31 '13 at 23:25
@kevincline are you seriously trying to start up this old fight? –  Jonathan Henson Apr 1 '13 at 4:16
add comment

3 Answers

up vote 10 down vote accepted

Byte code weaving and macros are two different things.

Byte code weaving is a way to intercept function calls, so that you can inject some sort of functionality (generally a cross-cutting concern such as logging) into a function call, either before or after the function is executed. Byte code weaving is done at the byte code level, which means that it occurs after compilation. The function itself is not affected. This is one of the techniques that Aspect Oriented Programming uses.

Macros are a way to extend the syntax of a language. In its simplest form, a macro is simply a way to record keystrokes, and then play them back using a hot key. Language macros work in a similar fashion; a keyword or other syntax construct substitutes for some sort of macro expansion. This is oversimplified, of course; a better example of a macro specific to Lisp can be found here.

share|improve this answer
+1 for mentioning that this is a key way of implementing AOP. –  Jonathan Henson Apr 1 '13 at 4:13
And transactions... let us not forget transactions. –  Jonathan Henson Apr 1 '13 at 4:17
LISP macros are nothing like 'a way to record keystrokes'. –  kevin cline Apr 2 '13 at 20:18
Well some fundamental concepts are missing to the answer IMO, those could be: AST, reflection, Metacircularity. –  AndreasScheinert Apr 3 '13 at 8:51
@AndreasScheinert: The OP didn't ask about any of those things. This isn't a dissertation; it's just an answer to the OP's question. –  Robert Harvey Apr 3 '13 at 14:24
show 1 more comment

Although they may be used to the same end, LISP macros are quite different from Java byte-code weaving plugins. LISP macros extend LISP syntax at the LISP source code level. Since LISP macros are written at the same level as other LISP code, they are a commonly used language feature.

Java byte-code weaving plugins operate at the JVM level. While many Java programmers may use byte-code weaving plugins written by others, very few Java programmers write their own byte-code weaving plugins.

Some of the work done by Java compiler plugins is very easily done in dynamic languages. Function-call interception is particularly simple.

share|improve this answer
I understand the technical differences between the two. I was attempting to look at the question from a high level point of view. Can both tools manipulate code to achieve the same goals? Are there any problems that macros can not solve that bytecode manipulation can (in a sane and cost efficient manner)? That is more what I was going for. –  mortalapeman Apr 3 '13 at 3:12
@mortalapeman: the manipulations possible in Java and C# via byte-code modification can all be done directly in languages like Lisp, Ruby, Python, Lua, Javascript... It is presumably possible to do everything that a LISP macro can do via byte-code manipulation, but in practice that does not happen. –  kevin cline Apr 3 '13 at 3:33
add comment

Lisp macros are operating at the source code level. If you wrap some macro around a piece of code, then you can do a lot of things. Including parsing the source code, inserting code, rewriting code, etc.

If you want to modify function calls, Lisp usually uses two mechanisms:

  • late binding symbols. You can modify the function bound to a symbol. Every function calling which goes through a symbol, then uses the new function.

  • Lisp implementations sometimes provide a feature called 'advice'. This allows to execute code before, after or around calls. For example in LispWorks: Advice.

Thus you can intercept calls without low-level code manipulation.

share|improve this answer
add comment

Your Answer


