Earlier quoted context omitted.
Because macros let you control code in a way libraries don't^1. Java now has this way to iterate over a collection of things: for(String exclamation: exclamations) { System.out.println("I yell " + exclamation + " at you"); } But this was only added in 2004!^2 So for almost 10 years, you had to manually iterate over stuff. How would you implement this as a library? Well, you could write a function that lets you write:…
Agreed about your Java example. However, for the purpose of this discussion, let's assume we're talking about modern, well-designed languages without ugly kludges and with access to nice features such as lazy evaluation and real closures. > Macros can be viewed as libraries that act on the language itself. There isn't a difference between language-level features and "library functions" in a language with macros. I si…
transaction { // everything in here is in one transaction } commit { // do stuff if the commit is successful } rollback { // do stuff if we rollback }
All the try's and catch's can be stuff into the macro. It can be made to nest transactions within transactions.
For all practical purposes, you can't add that to Java. You'll always have to wrap up your transactions in boilerplate.
The Lisp equivalent of what I want, the resulting code would look like:
(transaction (do-stuff) (do-stuff-if-commit-successful) (do-stuff-if-rollback))
There are languages where I could define three blocks of code and pass them:
transaction(stuff, commit-stuff, rollback-stuff)
But that separates their definitions from their implementations.
How could you write the Lisp transaction expression in another language so that it looks like it's part of the language? (serious question, CL is the only language I use capable of being that close) Maybe I could torture Ruby to come close, but it would be far more difficult than the macro I had to write for Lisp.