In the SBCL user manual there are several references to the term "open code". Common Lisp hackers also use this term when referring to optimizing code.
Could you please explain what it means to "open code" something and give an example of how it works?
It is open source / free software, with a permissive license. In addition to the compiler and runtime system for ANSI Common Lisp, it provides an interactive environment including a debugger, a statistical profiler, a code coverage tool, and many other extensions.
Example: Step 1: After logging into a CUIT machine, enter "lisp" after the $ shell prompt and then hit <return>. Another way is to run lisp via emacs: Meta-x run-lisp (i.e. hit 'esc' followed by 'x', type "run-lisp" and you'll be in lisp mode from which you can load files of lisp code...)
You as a programmer can invoke the compiler, for example in Common Lisp with the functions COMPILE and COMPILE-FILE . Then Lisp code gets compiled. Additionally most Lisp systems with both a compiler and an interpreter allow the execution of interpreted and compiled code to be freely mixed.
Features of Common LISP It provides high level debugging. It provides advanced object-oriented programming. It provides a convenient macro system. It provides wide-ranging data types like, objects, structures, lists, vectors, adjustable arrays, hash-tables, and symbols. It is expression-based.
Open-coding, AKA inlining, means replacing function calls with inline assembly.
The idea is that funcall
is expensive (it requires saving and restoring the stack &c) and replacing it with the few operations which constitute the function can be beneficial.
E.g., the function 1+
is a single instruction when the argument is a fixnum (which it usually is in practice), so turning the funcall into the two parallel branches (fixnum
and otherwise) would be a win.
They user can control this optimization explicitly by the inline
declaration.
The user can also influence this optimization by the optimize
declaration.
Both will affect inlining the code of a function defined just as a function (see below).
The "old" way is to implement the function as a macro. E.g., instead of
(defun last1f (list)
(car (last list)))
write
(defmacro last1m (list)
`(car (last ,list)))
and last1m
will be always open-coded. The problem with this approach is that you cannot use last1m
as a function - you cannot pass it to, say, mapcar
.
Thus Common Lisp has an alternative way - compiler macros, which tell the compiler how to transform the form before compiling it:
(define-compiler-macro last1f (list)
`(car (last ,list)))
See also the excellent examples in the aforelinked CLHS page.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With