
How to Define New Intrinsics in SBCL - chiachun
http://www.pvk.ca/Blog/2014/08/16/how-to-define-new-intrinsics-in-sbcl/
======
agentultra
TIL: a solid CL implementation can provide safe maps from high-level intrinsic
types to low-level implementation types at run-time. Also, SBCL has at least
two IRs with each able to provide optimization hints to the code generator and
compiler. So cool.

I love reading Paul's posts. His bit on Tobasco sort[0] was amazing.

[0] [http://www.pvk.ca/Blog/2012/08/27/tabasco-sort-super-
optimal...](http://www.pvk.ca/Blog/2012/08/27/tabasco-sort-super-optimal-
merge-sort/)

 _update: link_

~~~
_delirium
That is indeed a good post; thanks for linking it. Beyond the sort itself,
there's a nice illustration at the end of dynamically scoped ("special")
variables being useful on occasion for something other than the usual example
of temporarily shadowing a configuration variable (e.g. the destination of
stdout, or logging level).

------
eudox
In certain ways, the difference between (Common) Lisp and other languages is
the difference between Linux and Windows. When you have a fundamental problem
in Windows, your only solution is to wait for a fix then reformat/reinstall.
Similarly, when there's a problem in, say, a C compiler, all you can do is
code around it, open an issue and wait for a fix in the next release.

In Common Lisp? Well, the compiler's right there under these floorboards. Have
a long-running web application that's affected by this bug, and don't want to
restart it? Just run this in the REPL.

~~~
jlas
Not sure exactly what you're trying to say here but there are plenty of open
source C compilers [1], including GCC, which allow anyone to fix bugs as they
see fit.

To your second point about not restarting a long running web applications —
running code in a REPL won't fix your web app since it's a separate process.
You might need a remote debugging mechanism to connect a console to the app,
but at that point it may be much easier to restart the app.

[1]
[http://en.wikipedia.org/wiki/List_of_compilers#C_compilers](http://en.wikipedia.org/wiki/List_of_compilers#C_compilers)

~~~
eudox
>running code in a REPL won't fix your web app since it's a separate process.

In the server you have a script that fires up a Lisp process and starts a
Swank[0] server on port whatever. Then the developers, from their own
machines, fire up Emacs and SLIME[1] into that port and run something along
the lines of

    
    
      > (myapp.server:start :port 8000)
      <#server process>
    
      > (... some work ...)
    

[0] [http://common-
lisp.net/project/slime/doc/html/Lisp_002dside....](http://common-
lisp.net/project/slime/doc/html/Lisp_002dside.html#Lisp_002dside)

[1] [http://common-lisp.net/project/slime/](http://common-
lisp.net/project/slime/)

~~~
aardvark179
This is a great feature of Lisp, Smalltalk, and similar languages, in
development. In production however it can be extremely bad since the source
code you believe is needed to reconstruct an image may not be what is actually
in there, or some bootstrapping may have been done by hand and incorrectly
captured later on. If the image has been saved with this anomaly a couple of
decades ago then it's really fun trying to sort it out.

I've spent more time than I'd like to think doing software archeology to find
out just why two systems behaved differently, so I would seriously recommend
that if you do perform hot fixes in this manner then you reproduce the problem
on a system built from source, apply and test the hot fix, make the change in
the source and build your test system again to test, apply the hot fix to
production, and schedule a redeploy.

Fixing a live system can also be hazardous if you are replacing a function
that may be on the stack at the moment, or if you are in any sort of
multithreaded/process environment. Bugs become much harder to reason around
and fix in those cases because there can be race conditions about which
functions actually get called while you're applying your fix.

TL;DR You can, but probably shouldn't.

~~~
lispm
Providing patches as compiled code loadable into applications is fairly common
(!) in Lisp.

~~~
kazinator
But usually those patches are already validated. Providing validated patches
is one thing; developing them on the live system is another.

~~~
lispm
You would develop it in some live system anyway. That's the usual way to
develop in Lisp. It does not mean that the 'live system' is also a 'production
system'.

------
talder
Does the SBCL compiler use a separate third-party assembler? Otherwise, how
does it know the POPCNT opcode/encoding? I didn't see the author specify it in
the post.

~~~
sedachv
SBCL comes with its own assembler:
[https://github.com/sbcl/sbcl/blob/master/src/compiler/assem....](https://github.com/sbcl/sbcl/blob/master/src/compiler/assem.lisp)

~~~
_delirium
And the instructions themselves are defined here (e.g. for x86-64):
[https://github.com/sbcl/sbcl/blob/master/src/compiler/x86-64...](https://github.com/sbcl/sbcl/blob/master/src/compiler/x86-64/insts.lisp)

I think the question might've been how you can just write things like (instr
popcnt...) and expect SBCL to know how to emit the right machine code for
popcnt. It's mentioned briefly at the top, but the answer is that this post
isn't _adding_ the instruction (it would indeed not work if it were a new
instruction SBCL doesn't yet know about). The example is just walking through
modifying how it's generated by the VOPs, the code-generation level that sits
a level above the assembler. The popcnt instruction itself had already been
added to SBCL some time ago, with the _define-instruction_ seen in the link
above.

