Re:It's 2023, so of course I'm learning Common Lisp
by lispm on Thursday July 27, 2023 @05:37AM
(#36891101)
> But compilers I am an expert in and what you're implying is impossible
> it is either resolved statically or at runtime
Just tell Lisp which calls to statically resolve, inline, optimize. Overwrite the global default.
(defun foo (a)
(declare (inline +)
(optimize (speed 3))
(type (integer 0 100) a))
(* 10 (+ 3 a)))
Above tells Lisp to inline the + function, optimize for speed and declares the type of a to be an integer in the range 0 to 100. * (disassemble #'foo)
; disassembly for FOO
; Size: 32 bytes. Origin: #x7006DC8544 ; FOO
; 44: 40190091 ADD NL0, R0, #6
; 48: 5C0180D2 MOVZ TMP, #10
; 4C: 0A7C1C9B MUL R0, NL0, TMP
; 50: FB031AAA MOV CSP, CFP
; 54: 5A7B40A9 LDP CFP, LR, [CFP]
; 58: BF0300F1 CMP NULL, #0
; 5C: C0035FD6 RET
; 60: E00120D4 BRK #15 ; Invalid argument count trap
As you can see in the machine code, Lisp then uses the native machine code ADD and MUL instructions.
Re:It's 2023, so of course I'm learning Common Lisp
by tsimionescu on Thursday July 27, 2023 @06:17AM
(#36891417)
What you're missing is that, unlike any other commonly used language runtime, compilation in CL is not all-or-nothing, nor is it left solely to the runtime to decide which to use. A CL program can very well have a mix of interpreted functions and compiled functions, and use late or eager binding based on that. This is mostly up to the programmer to decide, by using declarations to control how, when, and if compilation should happen.
Re:It's 2023, so of course I'm learning Common Lisp
by regularfry on Thursday July 27, 2023 @09:56AM
(#36893574)
To be fair, any dynamic language with a JIT will mix interpreted and compiled functions, and will probably claim as a strength not leaving to the programmer the problem of which to compile.
Opinions may vary on that point.
Re:It's 2023, so of course I'm learning Common Lisp
by whartung on Thursday July 27, 2023 @02:17PM
(#36897928)
It should also be noted that by spec symbols in the system package (like + and such) should not be redefined. This offers “unspecified” behavior and lets the system make optimizations out of the box.
Outside of that you can selectively optimize definitions to empower the system to make better decisions at the cost of runtime protection or dynamism. However these are all compiler specific.
>Next you can find out what optimizing compilers do to avoid it, where possible or where wanted.
But compilers I am an expert in and what you're implying is impossible - either you have dynamic linkage, which means symbol resolution is deferred until call (and possibly guarded) or you have the equivalent of RTLD_NOW ie early/eager binding. There is no "optimization" possible here because the symbol is not Schrodinger's cat - it is either resolved statically or at runtime - prefetching symbols with some lookahead or cabinet is the same thing as resolving at calltime/runtime because you still need a guard.