kind of argument that might be convincing. The source code of the Viaweb editor was probably about 20-25% macros. Macros are harder to write than ordinary Lisp functions, and it's considered to be bad style to use them when they're not necessary. So every macro in that code is there because it has to be. What that means is that at least 20-25% of the code in this program is doing things that you can't easily do in any other language. However skeptical the Blub programmer might be about my claims for the mysterious powers of Lisp, this ought to make him curious. We weren't writing this code for our own amusement. We were a tiny startup, programming as hard as we could in order to put technical barriers between us and our competitors.” Paul Graham, Beating the Averages
to define and combine! increasingly powerful abstractions:! Data abstractions! Functional abstractions! Syntactic abstractions! Macros enable syntactic abstractions! (you can define your own special forms)!
go to http://try-clojure.org! Or…! 1) Check that your machine has Java! 2) Download the latest Clojure from http://clojure.org! 3) Open a REPL (Read-Eval-Print Loop):! > java -jar clojure.jar Clojure 1.2.0 user=> 4) At the REPL prompt, begin to play:! user=> (+ 2 2) 4
user=> (defn hello [name] (prn (str "Hello, " name))) #'user/hello user=> (hello ”Twin Cities Code Camp") "Hello, Twin Cities Code Camp” nil Note that prn prints out a string as a side effect,! and returns nil. Clojure guides you towards! functional programming.!
! - including functions – ! which gets evaluated at runtime! EXCEPT…! Macros are evaluated at compile time,! returning expressions which are ! in turn evaluated at runtime!
code generation facilities! But only in Lisp are functions themselves ! also Lisp data structures! Lisp programs are their own abstract syntax trees! ⇒ We can use Lisp to make Lisp!
the code generated by the macro! user=> (macroexpand-1 '(rev 2 1 +)) (+ 1 2) user=> (macroexpand '(rev 2 1 +)) (+ 1 2) macroexpand recursively expands all macros! Normally you only want to see what your macro is doing; for that you call macroexpand-1!
sure about that?! “Programming languages teach you not to want what they cannot provide. You have to think in a language to write programs in it, and it’s hard to want something you can’t describe.” Paul Graham, ANSI Common Lisp
notion of hygienic macros,! which prevent unwanted variable capture! This is probably more trouble than it’s worth! More importantly, they also prevent ! wanted variable capture!
in the house…! user=> `(0 x 4) (0 user/x 4) user=> `(0 ~'x 4) (0 x 4) Note that Clojure wants to express fully namespace- qualified symbols. That’s why we need the weird syntax to do anaphoric macros in Clojure. !
languages! The Clojure community discourages anaphoric macros, and seems to fear macros in general! Good thing: The Clojure community does not carry the baggage of the Common Lisp community! Bad thing: The Clojure community does not carry the wisdom of the Common Lisp community!
are endless!! Common macro uses:! Defining new syntacic abstractions that can’t be encaspulated in functions due to special form behavior! Increasing performance by executing code! at compile-time instead of at run-time !
about macros is how much day-to-day coding in other languages consists of manually generating macroexpansions... When there are patterns in source code, the response should not be to enshrine them in a list of ‘best practices’, or to find an IDE that can generate them. Patterns in your code mean you're doing something wrong. You should write the macro that will generate them and call that instead.” Paul Graham, Arc Tutorial
value few parts as a manifestation of simplicity! I value a complex part which! eliminates a large number of other parts! You may value different things…!
specifics of Clojure! ANSI Common Lisp! Paul Graham! http://www.amazon.com/dp/0133708756! Practical Common Lisp! Peter Seibel! http://gigamonkeys.com/book!
IDEA with La Clojure plugin! Comprehensive categorized listing at! http://www.clojure-toolbox.com! Clojure should work fine on .NET, but there’s no tooling –! anyone care to write a Visual Studio plugin…?!