TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Homoiconicity Revisited

49 点作者 vanschelven将近 5 年前

11 条评论

fiddlerwoaroof将近 5 年前
I think this is close, but sort of missing the point: it’s possible to extend Common Lisp to take code in the form of Python source code (clpython), JavaScript source code (cljs) or many other textual syntaxes: originally, the iconic s-expression syntax of lisps was intended to be a sort of IR dump for m-expressions.<p>What makes CL homoiconic has nothing to do with the textual syntax, but rather the existence of a function READ that takes _some_ textual syntax and produces the code to be evaluated in the form of the language’s ordinary datastructures: EVAL and friends consume a representation of the code that is neither just a blob of bytes nor some exotic AST objects, it’s lists, hash-tables, strings, vectors, and all the types of things programmers manipulate every day.<p>The implication of this is that intercepting and modifying the code between READ and EVAL doesn’t really require any special knowledge: you have to know the semantics of your language, and how to manipulate its basic datastructures, but you don’t need to understand any special “metaobjects” for representing code.
评论 #23427631 未加载
评论 #23426318 未加载
评论 #23426131 未加载
评论 #23426236 未加载
tom_mellior将近 5 年前
I think this definition makes sense, though I agree with <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=23426047" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=23426047</a> that the notion of homoiconicity, and therefore a precise definition of it, is not really useful.<p>What I&#x27;m disappointed by is the analysis of the examples and counter-examples, which even for a cursory analysis is somewhat sloppy. For example: &quot;S-expressions are trees, and the nesting of items is immediately apparent: ( denotes the start of a child, and ) its end.&quot; Not really, as I would say that &quot;(f x y z)&quot; either has four children, or one distinguished function symbol and three children. But there is only one pair of parentheses. Even if you take the reductionist view that there really are two children, namely &quot;f&quot; and &quot;(x y z)&quot;, there is only one pair of parentheses in the original.<p>Further: &quot;JavaScript has strong language support for composable, tree-like, structures (bullet 1) and the structure is immediately apparent by looking at the pairs of { and } brackets (bullet 3).&quot; It&#x27;s more complicated than that, since &quot;f(g(x + y * z))&quot; is also highly structured, and much of the structure is immediately apparent, but some of it isn&#x27;t because it uses precedence rules. Also, no {} in sight. And then: &quot;Java has no strong language support for literal representation of simple composable data in the language (bullet 1) and also fails to meet the other criteria.&quot; I don&#x27;t see how Java fails bullet 3 if JavaScript is claimed to pass it. The syntax uses {} and other grouping and expression forming mechanisms in essentially the same way. If anything, Java makes structure a tiny bit more explicit since it requires explicit semicolons to delimit statements.
评论 #23430576 未加载
评论 #23426602 未加载
foobar_将近 5 年前
I wonder where tcl falls on that list. It&#x27;s sorta like everything is a command &#x2F; list of commands and a command is a list of strings ?
DonaldPShimoda将近 5 年前
&gt; let’s say a word means what the people who use it mean by it.<p>This is how words work, so I don&#x27;t know why the author says &quot;let&#x27;s say&quot;. There is no &quot;correct&quot; definition of a word; the dictionary which you might consult to obtain such a definition is itself just recording what is the most commonly-used meaning of the word among people who use it most natively.<p>I make this point not out of pure pedantry, although that may play a part, but also because nobody seems to know what &quot;homoiconicity&quot; actually is — nor does it seem to actually be very important for us to find out! When people cannot agree on what a word means, I think it&#x27;s reasonable to say that that word doesn&#x27;t really <i>have</i> a meaning.<p>Some time ago, I had the opportunity to talk to Matthias Felleisen — the progenitor of the Racket project (a derivative of Scheme, itself a derivative of Lisp). When I asked whether he felt homoiconicity was an important quality of a language, he indicated something to the effect of (heavily paraphrasing) &quot;I don&#x27;t know what that word means, and you don&#x27;t know what that word means, but whatever you think it means is not important. It doesn&#x27;t matter.&quot;<p>Shriram Krishnamurthi, a former student of Felleisen&#x27;s and one of the original members of the Racket project, can be found to disparage the word whenever he finds it on Twitter. He also consistently refers to it as h11y (that&#x27;s &quot;H-eleven-Y&quot;), not just to save characters in tweets, but also, I think, because the word itself is not very important. I&#x27;ve seen multiple exchanges where he challenges peoples&#x27; attempts at defining the term precisely, and invariably they give up. (One such exchange is visible at [0].)<p>Another Racketeer, Matthew Flatt, recently started a push to build a new Racket language (now called Rhombus, I think) which abandons s-expressions almost altogether, but without losing any of the benefits of Racket.<p>If these people, who are all everyday Lispers, and who are widely known and respected in the programming language community, don&#x27;t have a solid definition of &quot;homoiconicity&quot; and, further, don&#x27;t think it&#x27;s worth investing the time to define it... maybe we should stop getting articles like this, and maybe we should instead tell people to abandon their search for the One True Meaning.<p>(I do want to say that I think this is one of the better articles about the topic that I&#x27;ve read, and the author did a good job. I just think the topic is not as interesting as the author expects their readers to find it.)<p>Homoiconicity doesn&#x27;t matter. Nobody can define it very precisely, so no two people will have the exact same definitions in their head when discussing it, so any talk regarding it will be necessarily lossy (or, in the worst case, completely non-productive). If the literal representation of your language happens to evoke some imagery in your mind of the secret machinations of the underlying forms or something, that&#x27;s great! But I don&#x27;t think it&#x27;s worth pursuing this quality specifically. What syntax works this way for you may not work well for others, or vice versa.<p>I think that, instead, it is better to focus on more specific goals. Maybe your language is very tree-oriented, so you make it easy to represent trees directly. Something like that. But the specific goal of &quot;homoiconicity&quot; — whatever that means to <i>you</i> — is perhaps not worthwhile, nor should we be seeking to define it. We should leave it by the wayside and move on!<p>[0] <a href="https:&#x2F;&#x2F;twitter.com&#x2F;ShriramKMurthi&#x2F;status&#x2F;1046944950531829760" rel="nofollow">https:&#x2F;&#x2F;twitter.com&#x2F;ShriramKMurthi&#x2F;status&#x2F;104694495053182976...</a>
评论 #23426294 未加载
评论 #23427296 未加载
评论 #23426429 未加载
评论 #23426226 未加载
评论 #23427112 未加载
remolacha将近 5 年前
Maybe off topic, but I find the styling of this website so pleasant. The colors and fonts really improve my reading experience.
评论 #23426192 未加载
empath75将近 5 年前
It seems like there&#x27;s two ways to go from here -- abandon it, or formalize it. Just because formalizing a concept is difficult, that doesn&#x27;t make it impossible. I think everyone agrees that there is _something_ that distinguishes lisps from other languages, even if it&#x27;s hard to say exactly what it is.
nemoniac将近 5 年前
An article about homoiconicity without once mentioning either the word &quot;transform(ation)&quot; or &quot;macro&quot;. I can&#x27;t quite make my mind up whether this is a tour de force or if it misses the point entirely.
galaxyLogic将近 5 年前
Isn&#x27;t the idea of homoiconicity in its simplest form that every data-structure can also be interpreted as a program?
评论 #23430600 未加载
mirekrusin将近 5 年前
Maybe it&#x27;s just: 1. code is written in ast, and 2. (macros) you can construct objects that can be interpreted as ast
DonHopkins将近 5 年前
PostScript is homoiconic, and semantically quite Lisp-like, when it&#x27;s not being syntactically somewhat Forth-like.<p><a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=21968842" rel="nofollow">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=21968842</a><p>&gt;[...] PostScript and Lisp are homoiconic, but Forth is not. The PSIBER paper on medium goes into that (but doesn&#x27;t mention the word homoiconic, just describes how PS data structures are PS code, so a data editor is a code editor too).<p><a href="https:&#x2F;&#x2F;medium.com&#x2F;@donhopkins&#x2F;the-shape-of-psiber-space-october-1989-19e2dfa4d91e" rel="nofollow">https:&#x2F;&#x2F;medium.com&#x2F;@donhopkins&#x2F;the-shape-of-psiber-space-oct...</a><p>Also, here is a metacircular PostScript interpreter, ps.ps: a PostScript interpreter written in PostScript! Since PostScript is homoiconic and so much like Lisp, it was as easy as writing a metacircular Lisp interpreter (but quite different in how it works, since PostScript and Lisp have very different execution models).<p><a href="https:&#x2F;&#x2F;donhopkins.com&#x2F;home&#x2F;archive&#x2F;psiber&#x2F;cyber&#x2F;ps.ps" rel="nofollow">https:&#x2F;&#x2F;donhopkins.com&#x2F;home&#x2F;archive&#x2F;psiber&#x2F;cyber&#x2F;ps.ps</a><p>The heart of the metacircular interpreter, &quot;iexec&quot;, uses some dynamically defined macros like MumbleFrotz, PushExec, Popexec, containing embedded literal references to data (a dictionary representing the interpreter state, and ExecStack, and array representing the execution stack).<p><pre><code> % interpretivly execute an object &#x2F;iexec { % obj =&gt; ... 100 dict begin % This functions &quot;end&quot;s the interpreter dict, executes an object in the % context of the interpreted process, and &quot;begin&quot;&#x27;s back onto the % interpreter dict. Note the circularity. &#x2F;MumbleFrotz [ % obj =&gt; ... &#x2F;end load &#x2F;exec load currentdict &#x2F;begin load ] cvx def &#x2F;ExecStack 32 array def &#x2F;ExecSP -1 def &#x2F;PushExec [ % obj =&gt; - &#x2F;ExecSP dup cvx 1 &#x2F;add load &#x2F;store load ExecStack &#x2F;exch load &#x2F;ExecSP cvx &#x2F;exch load &#x2F;put load ] cvx def &#x2F;PopExec [ % obj =&gt; - ExecStack &#x2F;ExecSP cvx &#x2F;get load &#x2F;ExecSP dup cvx 1 &#x2F;sub load &#x2F;store load ] cvx def &#x2F;TraceStep { iexec-step } def PushExec { ExecSP 0 lt { nullproc exit } if % nothing left to execute? goodbye. ExecStack 0 ExecSP 1 add getinterval TraceStep pop % pop top of exec stack onto the operand stack PopExec % is it executable? (else just push literal) dup xcheck { % obj % do we know how to execute it? dup type &#x2F;&#x2F;iexec-types 1 index known { % obj type &#x2F;&#x2F;iexec-types exch get exec % ... } { % obj type % some random type. just push it. pop % obj } ifelse } if % else: obj } loop % goodbye-proc currentdict &#x2F;MumbleFrotz undef % Clean up circular reference end exec % whoever exited the above loop left a goodbye proc on the stack. } def </code></pre> It also has a &quot;vexec&quot; function that executes arbitrary PostScript code, and prints out another text PostScript program to draw an animated trace diagram of the operand stack depth -vs- execution stack depth. That&#x27;s another simpler kind of macro that produces text instead of structures. So I was using the metacircular PostScript interpreter to visualize one structural PostScript program&#x27;s execution, by producing and executing the resulting text PostScript program in another PostScript interpreter!<p>I don&#x27;t currently have the PS output or rendered images decoded and online, but here&#x27;s a readme:<p><a href="https:&#x2F;&#x2F;donhopkins.com&#x2F;home&#x2F;archive&#x2F;psiber&#x2F;cyber&#x2F;twist.readme" rel="nofollow">https:&#x2F;&#x2F;donhopkins.com&#x2F;home&#x2F;archive&#x2F;psiber&#x2F;cyber&#x2F;twist.readm...</a><p>This is a plot of the execution stack (x-axis) and the operand stack (y-axis) during the execution of the PostScript &#x2F;quicksort routine. Each successive picture is more twisted than the last. Twisting is accomplished by rotating the coordinate system clockwise slightly around the center of each of the dots as they are drawn. The rotation around each plotted point accumulates to make the whole drawing curl up. The more twisted away from the original orientation a point is, the later it occurred in time. In the first picture, the untwisted version, up corresponds to a deeper operand stack (pushing things on the stack moves you up), and right corresponds to a deeper execution stack (procedure calls and control structures move you right). The lines follow changes in the state of the stack between steps of the interpreter. (This was made possible by a PostScript interpreter written in PostScript.)<p>To see the twist animation, run monochrome NeWS, type &quot;psh&quot; to the shell, then type &quot;(&#x2F;wherever&#x2F;you&#x2F;put&#x2F;it&#x2F;twist.ps)run&quot;. The reason you can&#x27;t just psh the file directly is that NeWS 1.1 psh does $1 $2 $3 arg substitution, even on binary data! (X11&#x2F;NeWS psh should work, so you can just go &quot;psh twist.ps&quot;)<p>What the file twist.ps contains is a short header defining the function &quot;c&quot;, which reads a canvas and displayed it on the framebuffer. That is followed by a series of &quot;c&quot;&#x27;s each followed by a 1 bit deep 1152x900 sun raster files.<p>-Don Hopkins (don@brillig.umd.edu)
vanschelven将近 5 年前
somewhat off-topic, but as both the author and original poster of this article, it&#x27;s interesting to note that the article appears here as though it was posted 3 hours ago, even though I actually posted it 23 hours ago (when it gathered no attention).
评论 #23426286 未加载
评论 #23426710 未加载