4 ms·
> "In a homoiconic language, the primary representation of programs is also a data structure in a primitive type of the language itself." I believe the author
by macmac 7y ago
> "In a homoiconic language, the primary representation of programs is also a data structure in a primitive type of the language itself."
I believe the author is misreading this definition.
> "First, consider that most languages have a primitive datatype for strings of text"
The defintion says "data structure", not "datatype". A string is a datatype, not a datastructure.
> "Second, for most languages, it is possible to write a parser in that language itself, that stores the resulting abstract syntax tree in a primitive type in the language."
This is completely besides the point as the definition references the "primary representation", not a represenation that can be built using a parser.
- DATACOMMANDER 7y agoSpot on. Even if you allow the string to be considered a (rather simple) data “structure”, when we talk about homoiconicity we (explicitly or implicitly) exclude strings from the set of data structures under consideration.
- amelius 7y agoThat feels a bit like cheating though.
- frou_dh 7y ago"Well, the whole source file is a single string" just seems like a vacuous gotcha. It's not an interesting enough point to settle the matter.
- Tomte 7y agoUnless we're talking about Tcl. Its homoiconicity is based on strings.
- fourthark 7y agoTRAC also. Probably why it was so slow, but a friendly language. See Ted Nelson's Computer Lib (p18) for a nice description of TRAC.
- JadeNB 7y agoA discussion of it is also linked from the main article: https://dl.acm.org/citation.cfm?doid=800197.806048 https://dl.acm.org/citation.cfm?doid=800197.806048 .
- thurn 7y agoI would reword it as "the primary representation is also a data structure literal in the language itself". I think "literal" is basically what they mean by "primitive type", i.e. there is first-class syntax to create the structure. Another example of a homoiconic language is XSLT, where the syntax of the language is based on XML, but it also has XML literals.
- reikonomusha 7y agoI think it’s less about strings vs not-strings and more about practicality of metaprogramming with native data types. You can cobble some oddities together with Python strings and eval, but it’s entirely inconvenient and impractical. As such I’m not inclined to cal Python “homoiconic”. I’m OK with homoiconicity simply being a subjective and slightly imprecise term.
- _8ljf 7y ago“I believe the author is misreading this definition.” Agreed. Author has tied self in knots from overthinking it. Homoiconicity has nothing to do with external [text] representation and parsing (deserialization). Homoiconicity in a programming language means that every complete program is a composition of the language’s core datatypes, and nothing more. OP’s suggestion that homoiconicity could be a sliding scale is nonsense. A language is either homoiconic, or it isn’t. Here’s a simple test: many languages have first-class functions/procedures/handlers, but most of them do not first-class commands. Any language which has commands which are not values cannot be homoiconic. A Lisp program is composed entirely of Lisp’s atomic types (`number`, `string`, `symbol`) and fundamental collection type (`list`). Lisp, being an exercise in extreme parsimony, does not define a discrete `command` type but instead overloads its `list` datatype to operate as either a command or a list according to context. Thus commands in Lisp can be created, manipulated, passed around, and evaluated at any time, using the exact same toolset as is used to create, manipulate, pass around, and evaluate Lisp lists. Or my own kiwi language defines six core datatypes—`null`, `text`, `name`, `list`, `command`, `tag`—from which all kiwi programs are composed. Command values can be created, stored, passed around, and evaluated just the same as any other value. e.g. Here’s a slightly contrived example which stores a list of arbitrary commands, then later retrieves and passes them as the argument to another command (`vowels`), which passes them on to a primitive procedure (`apply to pattern`) where they’re finally applied to the input data: R> store value (x, (case (upper), bold)) R> R> define rule (vowels (format), apply to pattern (“[aeiou]”, {$format})) R> R> ^^ hello world R> vowels ({$x}) # “hEllO wOrld” Compare and contrast to a C-family language such as Python. While some language structures (integer, string, list, function literals) do have native datatype representations, other structures (operators, statements, function calls) do not. While it’s still possible to manipulate Python program structures using Python’s `ast` APIs, or pass around sequences of hardcoded commands by wrapping them in lambdas, everything is second-class, with all the additional indirection and complexity that entails. Still, look at how popular and useful Python is, despite such expressive limitations, while Lisp, for all its meta-circular power, is stuck firmly on the fringes. . So how could homoiconicity be useful? Well, consider this thread: <https://news.ycombinator.com/item?id=20662232> https://news.ycombinator.com/item?id=20662232>, discussing the current challenges of building programs by voice dictation. Voice-coding languages such as C and Python require lots of special “control words” to input complex syntactic structures—operators, statements, punctuation, and so on. A language where all code structures are primitive data types only needs words to describe those data structures, and since fundamental data structures like quoted strings and lists are inherently self-describing, tedious mechanical details like precise punctuation can probably be inferred automatically from a combination context-aware autocomplete and voice cadence (e.g. meaningful pauses, end-of-sentence pitch changes). In the land of blind-dumb algorithms, Compositionality may yet be King.