2012-02-04 is sponsored by word "homoiconicity" http://en.wikipedia.org/wiki/Homoiconicity .
Background: I am about to choose which book about Clojure to buy -- either "Clojure in Action" or (incoming at the end of April) "Clojure Programming" (you can read it via O'Reilly Rough Cuts, half of the pages are visible). What struck me, that in both books this property -- homoiconicity -- got so much emphasis.
Since Clojure roots are Lisp-based, I referred "dead sexy" book is this really so big deal. Well, I can see macros explained in detail but I didn't catch the mentioned emphasis. Now compare to this (quote from "Clojure in Action")
This homoiconicity is also what makes Clojure’s macro system possible.
It almost looks like without it, macros wouldn't be possible. Even wikipedia statement (link above) is more balanced, but none of those sources (*) counts human factors in favour of English syntax.
If I am not mistaken, macro syntax (Lisp-like) could be possible in C# (for example), only with more effort from C# team. But it is cost of the designers team, not users (?). Second -- habbits matter. If in real life you think "a + b", and in computer world you constantly translate it to "+ a b", productivity suffer (I can see this for myself, when I went from C++ functors to C# lambdas).
This praise, that the Clojure programmer writes programs almost directly as AST, frightens me as reading that "thanks to writing the code directly in hex code, not only you learn hex system by heart, but you are closer to machine".
To sum up -- I love metaprogramming, I love Lisp-like macros (I am not a Lisper though), but I see two things here -- macros and homoiconicity. The first one is without a doubt great, the second -- not so much (as for my understanding), because it makes human fit computer needs, and it should be other way around.
Is homoiconicity really so beneficial for humans (end users of language) or it is actually almost solely beneficial to language designers? Examples are very welcome!
Or just in case I rephrase -- assuming given language has Lisp-macros, will "adding" homoiconicity improve productivity of end-user? Expresiveness? Or quite contrary?
(*) I cannot be 100% sure, because I see only a fraction of Clojure books, and I am not reading them, just evaluating them for purchase.
Thank you all for the answers, pity I had to pick only one as a solution :-), it does not mean I value others less, this one is most complete for me.
Homoiconicity. Homoiconic languages typically include full support of syntactic macros, allowing the programmer to express transformations of programs in a concise way. Examples are the programming languages Clojure (a contemporary dialect of Lisp), Rebol (also its successor Red ), Refal, and more recently Julia .
One advantage of homoiconicity is that extending the language with new concepts typically becomes simpler, as data representing code can be passed between the meta and base layer of the program. The abstract syntax tree of a function may be composed and manipulated as a data structure in the meta layer, and then evaluated.
All Von Neumann architecture systems, which includes the vast majority of general purpose computers today, can implicitly be described as homoiconic due to the way that raw machine code executes in memory, the data type being bytes in memory. However, this feature can also be abstracted to the programming language level.
Homoiconic languages typically include full support of syntactic macros, allowing the programmer to express transformations of programs in a concise way.
Homoiconicity is not strictly required for macros (example: the C/C++ preprocessor implements a compile time macro system).
However homoiconcity makes macros much more effective and easy to use:
As a small example, here's a macro that adds a Java/C# style "for" loop to Clojure.
(defmacro for-loop [[sym init check change :as params] & steps]
`(loop [~sym ~init value# nil]
(if ~check
(let [new-value# (do ~@steps)]
(recur ~change new-value#))
value#)))
;; Usage:
(for-loop [i 0 (< i 10) (inc i)]
(println i))
And that's it - a new language construct added in six lines of code. You can see the homoiconicity clearly in action - the whole "loop" form is just a quoted Clojure data structure. The init, check and change parameters are also homoiconic clojure data structures passed to the macro that represent the loop control expressions. There was no need to do any parsing to support my new syntax.
I think it would be very hard to do this as concisely or simply in any non-homoiconic language.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With