4 ms·
I have to say, I do not understand what you are addressing in my comment: whether you are rebutting, agreeing, expanding, informing, thinking out loud, or simpl
by kmill 9y ago
I have to say, I do not understand what you are addressing in my comment: whether you are rebutting, agreeing, expanding, informing, thinking out loud, or simply expressing what you think is special about Lisp.
> The interface for EVAL and COMPILE is code as data, not text.
Is that essential? or is it just convenient? I'm not aware of anything in Common Lisp (other than the spec) that requires eval to accept s-expressions rather than strings. I'm assuming objects have string forms that when read give an object that is eql.
An aside: one could say eval and compile are hacks to deal with the fact that in Lisp, code is merely a kind of data. In a language like Mathematica, data is also a kind of code (there is no difference between code and data). This has logical issues, however, so I wouldn't take code=data as a design goal.
> The macro facility operates on code as data. ... code as data ... code as data
Sure, Lisp has a data type for code and it has an expressive language to manipulate code (what I was calling "autoiconicity"). Lisp also has staged metaprogramming that seamlessly invokes such code manipulators before evaluation/compilation. Many languages, with less expressivity, can also load, manipulate, and write code -- with the code represented as structured data of course.
> (or the less useful idea of homoiconicity) means code as data, but not as a string
But if you read my comments, you'd know I think "homoiconicity" does not mean "code as data," but "essentially the same representation internally and externally." It's a property of an implementation of a language and not the language itself. Alan Kay defines the word offhandedly and asserts Lisp is homoiconic in his thesis, and, except for some implementations of Lisp, it doesn't apply in general. This is the point of my thought experiment: every language has some implementation that is homoiconic. (And so what? That's also my point.)
> Interpreter operate on code as data. This enables sophisticated tracing and stepping (stuff which I would need to instrument in compiled code), self-modifying and inspecting code, easy access to source forms in the debugger, etc.
SBCL compiles everything to machine code, even with eval. It is not essential for an interpreter to directly operate on s-expressions, and whether one does or not is not observable. These things can all be implemented by a transformation of the code after macro expansion and before compilation. Or perhaps JIT compilation like PyPy through RPython.
On the other hand, we can take most languages and create interpreters that evaluate the AST, giving us such tracing, stepping, and access to source in a debugger.
(By the way, do you really mean self-modifying and self-inspecting code? Can you give a useful example of this in Common Lisp? I wasn't aware that Common Lisp requires an implementation to be able to give the definition of a function. I thought it was a property of the implementation and not the language.)
> No, s-expression-based Lisp code is not what I would consider to be an AST.
Great. Now would you care to define AST in a way that excludes s-expressions (and in a way that isn't ad-hoc)? It seems to me that s-expressions are a tree representing syntax abstractly; I'm not sure how it's not, or what you gain (inference-wise or practically) by excluding s-expressions. Are you drawing the distinction that it is only when an s-expression is paired with an interpretation that you get an AST? (By the way, this is a powerful idea that's used for nanopass compilers: lots of stages each with a slightly different interpretation for the constituent s-expressions.)
- lispm 9y ago> Homoiconicity ... same representation internally and externally That's why it makes little sense. Lisp does not use the same representation internally and externally. Externally programs may be characters in a file or on a display. They are interned by reading them into data structures. Running programs may use different representations and one popular is the internalized representation - which is used by Lisp interpreters. > SBCL compiles everything to machine code... If you use its compiler. If you use its interpreter, it doesn't. http://sbcl.org/manual/index.html#Interpreter http://sbcl.org/manual/index.html#Interpreter Sure, using an interpreter is observable. That's the reason why they exist. They offer different services to the user. Many Lisp systems offer hooks into the interpreter, which let you watch it working. > s-expressions are tree representing syntax... Actually s-expressions are a data format, not a format of the programming language Lisp. S-expressions know very little about Lisp - basically it provides an elaborate/hierachical form of a tokenizer output. The reader parses numbers into number objects, symbols into symbol objects, etc. But the reader does not know anything about the syntax of Lisp, which is defined on top of s-expressions. Thus the s-expression does for example NOT represent any syntactic informations about the source code: after READ it is not known what a symbol actually stands for. Is it a data object, a function, a special operator, a macro, a variable, a local function, a local variable, a package name, a goto tag, ...? The s-expressions does not tell us. We also don't know what are function calls and what not. Etc. From an AST I would expect that it represents syntactic information of the programming language Lisp. To contruct this one needs to traverse the s-expressions: using compilers, interpreters and/or code walker (tools which can traverse code, collect information, maybe transform it). The ANSI CL spec even lacks a way to access the syntactic information in macros. The facility for that didn't make it into the standard, though implementations provide a quasi-standard way. http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node102.html#SECTION001250000000000000000 http://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node102.html#S...
- kmill 9y agoI wasn't aware of SBCL's interpreter mode, but it does say "in SBCL interpreted code is not safer or more debuggable than compiled code." I haven't used it myself yet, though, so it's possible there are interesting differences to the user. But to be clear, when I said "observable," I meant "observable to the running program." The standard I'm using: if an implementation detail is not observable to the program (with some restrictions, like a program can't just measure how long it took to execute), it's not a property of the language itself. > That's why it makes little sense. Lisp does not use the same representation internally and externally. Externally programs may be characters in a file or on a display. It's a bit confusing to have you reiterate what I've said in this thread without your saying you are doing so and are in agreement. Let's go back to the very beginning of our discussion: > > I think Alan Kay using the word "homoiconic" for Lisp was a mistake. The syntax of Lisp really is not the same as the internal representation > A Lisp interpreter executes internalized s-expressions. "Syntax" as in "what the user of the language types." At the least, I meant sequence of characters vs s-expressions. But, I also did the confusing thing of saying "the internal representation" to mean a property that all Lisp implementations share. Some Lisp interpreters directly examine s-expressions, sure, but, given the context, I assumed that your pointing this out meant you thought it was evidence that I was mistaken to think Alan Kay was mistaken. > Actually s-expressions are a data format, not a format of the programming language Lisp. I take it the answer is "yes" to my question "Are you drawing the distinction that it is only when an s-expression is paired with an interpretation that you get an AST?" > Thus the s-expression does for example NOT represent any syntactic informations about the source code In Lisp, there are two levels of syntax: syntax classes from the source code, like symbols, numbers, lists; and syntax classes from the s-expressions, like what you go on to say. (Meta-question: am I coming across as someone who's ignorant about the design and implementation of Lisp? My experience observing lispers communicate is that they seem to assume nobody else is familiar with the details of Lisp and how it works!)