Homoiconicity Advantages

from MyNaiveAttemptAtUnderstandingHomoiconicity:

...as a matter of fact, maybe I never said so directly before, but being homoiconic can be a defect of some languages in some circumstances, as can potentially many other facilities for examining/manipulating code dynamically. It is well known that dynamic SQL and shell scripts, for instance, can be open to lethal security flaws, when it involves blindly evaluating strings dynamically.

For this sort of reason (amongst others that are off-topic here), it is very rarely considered good style in Lisp to eval arbitrary S-expressions, even though a lot of comments on these pages have sort of considered that to be the heart of homoiconicity (it's not, precisely, but it's closely related). Calling eval is a last resort.

Historically, one of the values of homoiconicity has been considered more in regard to things like the ease in creating code walkers and in prototyping (where creating a custom eval is a quick way to do one-off languages), not in calling eval all over the place in production programs.

There are other ways to do e.g. code walkers in other languages, so that virtue isn't limited to homoiconic languages. However, having single-handedly written a code-walker for C, let me tell you, that was a truly major pain, and a fairly big project, and C, at least, sucks in terms of ease of implementing code walkers by any means whatsoever.

I tend to be favorably impressed, not by homoiconicity per se, but by languages which are elegant enough such that writing a new code walker is easy, for whatever reason and however it is pulled off. The clumsier the mechanism, the less impressed I am, so I am least impressed by C and C++ (both use the C preprocessor, which introduces endless headaches, and parsing C++ in particular is not LALR(k), which means that simply writing e.g. a YACC/Bison grammar simply will not cut it).

For less syntactically damaged languages, there's still the question of how simple the syntax is, or at least whether there's some standard class for parsing the language. The latter goes a long way towards making up for complex syntax. -- DougMerritt

Ahh, I see, the advantages of homoiconicity are

or? Are there more? -- .gz

Other people may bring up further advantages, that are not coming to mind for me today, but I believe that captures the heart of it, yes. It was a fairly off the cuff comment, so if I think of something else later, I'll say so. -- Doug

Surely the biggest advantage is the ease of implementing a proper macro system? When code is data, it is trivial to extend the usual "tokenize -> parse -> compile" cycle into "tokenize -> parse -> run arbitrary macros over the resulting parse tree -> compile". That is an immensely powerful capability, opening up all sorts of amazing potential for automatic code generation, instrumentation, syntactic extension, etc.

Sure, it would be possible for a non homoiconic language to expose the parse tree in a similar way, but then you are effectively introducing an entirely new representation for the programmer to learn. Macros are only ever going to feel truly natural and easy to use when the representation they manipulate is the same as that used for the majority of the program (and for implementing the macro function itself, of course: repeat to the desired metalevel).

I'll buy that; that's a very strong point. But non-Lispers tend to not understand the point of Lisp macros and why they can be a thing of beauty and power, and in fact frequently confuse them with DougMcIlroy-style text macros, as in the C preprocessor, which are often considered outright evil. And of course even within the community there's the philosophical disagreements about hygene, Scheme vs. CommonLisp macros, etc. So although I strongly agree, I would expect confusion on this point. -- Doug

See also HomoiconicLanguageDrawbacks


EditText of this page (last edited November 13, 2014) or FindPage with title or text search