Yes, Common Lisp stores the s-expression. And you can get at it by applying an operation (in your case, `function-lambda-expression`) to some opaque handle.
The function itself isn't stored as its s-expression. Neither does any reasonable interpreter work by walking the s-expression. (Doing so would be very slow.)
Yes, I'm having trouble getting precisely to what you are talking about. Do you mean something like SBCL compiling to machine code, for example? If so, how does that affect using Common Lisp to implement some DSL, in the sense that it takes away the power of s-expressions for achieving this?
I am saying that S-Expression aren't any kind of 'primary' representation of your program in a modern Lisp. Especially a compiled one.
S-Expressions (or more precisely, the AST) is just one representation amongst many that's in use during the different stages of the compilation process.
They are still a great syntax choice for the kind of languages that Lisps are. Totally agreed.
My point was that homoiconicity is a surface level property that you could bolt on to eg C or Cobol, via a simple pre-processor, and it wouldn't change those languages much.
Just like you could bolt on using Python-style significant indentation to C or Fortran or Lisp, and it wouldn't change those languages much. (Apart from changing their syntax, of course.)
> I am saying that S-Expression aren't any kind of 'primary' representation of your program in a modern Lisp. Especially a compiled one.
Besides pointing out like others have that pretty much all Lisps have an interpreter that stores programs as s-expressions, why do you think compilation makes making a DSL in Lisp harder? Do you think you somehow need a parser all of a sudden?
> My point was that homoiconicity is a surface level property that you could bolt on to eg C or Cobol, via a simple pre-processor, and it wouldn't change those languages much.
Writing in C instead of assembly does not make your processor more powerful. Similarly, when designing languages, homoiconicity allows you to work directly with the AST in a way that is most ergonomically simple. Saying this is a surface level thing is an understatement
The nested list objects, whose printed representation is called S-expression, are the representation of the source code of Lisp. This is important and primary in multiple senses of the word.
In version control jargon, only primary objects should (ideally) be tracked in a repository, not secondary/derived ones. The most common example of primary objects are source code files; and of secondary/derived objects, compiled files.
Programs first exist as source code; primary means first. The semantics of the language is defined with reference to the syntax, whose description refers to the source code form. Everything begins with the semantics: it is primary. Other forms, like compiled, have to produce the same results like the reference evaluation model over the source code. Expansion of macros is defined over the source code. Other tooling is based on source code, like text editing, tags generation and whatnot.
Compiled code is not primary in any way. It is non-portable, sometimes not even fully documented, and supports almost no useful operations beyond invoking it (calling a compiled function or loading a compiled file) and disassembling compiled code.
The representation of compiled code can change between releases of a Lisp; the worst that happens is that users have to recompile their code since old compiled files do not load any more. If you break the source language, there will be gnashing of teeth.
The basis of portability among implementations of the same dialect is always the source code.
Lisp programs can quote pieces of themselves as literal constants. Atoms can be quoted, as well as symbols and entire lists. These quoted lists have to survive into the compiled form. Thus, the syntax is important because any piece of it can potentially be a literal which has to retain its shape and content no matter how the program is translated.
Textual source code contains valuable information not found elsewhere: formatting and comments.
In Lisps that have programmable readers, like Common Lisp, only the source code contains instances of the original read syntax. For instance, in some implementations of the backquote syntax, the reader expands it, and this may be done in such a way that the resulting object cannot be printed as backquote syntax any more. Application-defined read syntaxes usually do not support printing back in the original form. Thus they appear only in the textual source code.
Primary information is already lost when we have merely read an expression into memory without doing anything else, like expanding and compiling it.
Yes, Common Lisp stores the s-expression. And you can get at it by applying an operation (in your case, `function-lambda-expression`) to some opaque handle.
The function itself isn't stored as its s-expression. Neither does any reasonable interpreter work by walking the s-expression. (Doing so would be very slow.)