3 ms·
> But how is the output of a program containing a lisp macro for example. The use of the macro gets expanded at compile time and the expanded code then gets co
by lispm 4y ago
> But how is the output of a program containing a lisp macro for example.
The use of the macro gets expanded at compile time and the expanded code then gets compiled.
Lisp macros are designed in such a way that they are be expanded before runtime.
> evaluation at runtime
Evaluation at runtime does not mean the code gets not compiled.
The SBCL implementation of Common Lisp:
* (let ((fn-code (quote (lambda (a)
(* a 42))))) ;source of function as a list -> FN-CODE
(let ((fn (eval fn-code))) ; evaluation of that list FN-CODE ->eval-> FN
(prog1
(funcall fn 11)
(disassemble fn))))
; disassembly for (LAMBDA (A))
; Size: 36 bytes. Origin: #x700568E8E4 ; (LAMBDA (A))
; 8E4: AA0A40F9 LDR R0, [THREAD, #16] ; binding-stack-pointer
; 8E8: 4A0B00F9 STR R0, [CFP, #16]
; 8EC: EA030CAA MOV R0, R2
; 8F0: 8B0A80D2 MOVZ R1, #84
; 8F4: 3C9880D2 MOVZ TMP, #1217
; 8F8: BE6B7CF8 LDR LR, [NULL, TMP] ; SB-KERNEL:TWO-ARG-*
; 8FC: DE130091 ADD LR, LR, #4
; 900: C0031FD6 BR LR
; 904: E00120D4 BRK #15 ; Invalid argument count trap
462
You'll see that EVAL at runtime compiles the code on-the-fly and in-memory to ARM64 machine code.
- terminalcommand 4y agoYou are dissasembling inside the interpreter. Interpreter already reads, evaluates before generating the assembly code. How does EVAL work if the entire program is compiled AoT?
- lispm 4y ago> You are dissasembling inside the interpreter. What you see is no interpreter. It's an interactive interface, reading code, compiling it, executing it, printing the result. There is by default no interpreter. Everything is compiled in SBCL. A Lisp system typically includes an on-board compiler and/or interpreter.
- terminalcommand 4y agoREPL is the interpreter isn't it? When you type the code into sbcl you are using the REPL which is the interpreter. Try running sbcl without the REPL and produce an executable binary file. Maybe the binary representation changes into something with dynamic dispatch?
- lispm 4y agoREPL is a Read Eval Print Loop, which is a way to interact with a Lisp runtime. This is independent on how EVAL is implemented. A bunch of Lisp systems implement EVAL with an incremental compiler. An interpreter is a Lisp feature where code gets interpreted from source at runtime. Some implementations have one, some don't, some only have an interpreter, some only have a compiler, some have several compilers, some have both. > running sbcl without the REPL and produce an executable binary file The executable binary file in SBCL always includes the compiler. REPL: a user interface to execute Lisp code. Reads s-expressions, evaluates them and prints the results as s-expressions. EVAL: the interface to execute code. A function. Interpreter: an implementation of Lisp which interprets source code. Byte Code Interpreter: an implementation of Lisp which interprets byte code instructions. Compiler: an implementation of Lisp which can compile code to a) byte code, b) C code, c) machine code In-memory compiler: an implementation of Lisp where the compiler does not create files, but writes the executable code directly to RAM Whole-Program compiler: an implementation of Lisp, which only compiles whole programs and creates executables -> rare, but various examples exists
- terminalcommand 4y agoThank you for taking the time to explain. I now get it. SBCL includes the compiler in each binary and this is called incremental compiling. That explains the expressiveness. It is kind of like a JIT when needed. Compile everything you can AoT, leave dynamic parts to runtime compilation. It makes perfect sense. Thanks . I guess the difference is that in an interpreter you don't go down to assembly, you parse and run stuff. The moment you cross the line to generate bytecode/machine code or transpile into a different language you get a compiler.