The less-familiar parts of Lisp for beginners — the

The newcomer to Lisp might not have seen the special operator the before.  This special operator allows the programmer to inform the compiler of the type returned by a form, in the event that the compiler cannot deduce it from context.  Note that this is not the same as a C or C++ static cast, the does not modify a type, and does not necessarily perform type checking (behaviour is undefined if you present it an object that is incompatible with the type declared by the), it merely tells the compiler what it should expect to get back from a form.  Compare this with the declare special operator, which can be used to tell the compiler what the types are of parameters passed to a function.

To demonstrate, I’ve written a function, remote-function, that simply returns the number 20.  I then have some code that uses this function, which I’m compiling for speed.  The compiler doesn’t know what remote-function does, and I could always change the function after compilation, so it can’t optimize fully without the the special operator.  The resulting disassembly listings show the difference.  In the first case, without the, the addition operator is a function call to generic-+, whereas in the second case the addition is made using straight integer arithmetic, with no function setup and call.

Without the special operator compiler hint:
the.lisp

(declaim (optimize (debug 0) (safety 0) (speed 3)))

(defun my-adder ()
  (+ 5 (remote-function)))

*slime-repl sbcl*
CL-USER> (disassemble 'my-adder)
; disassembly for MY-ADDER
; Size: 51 bytes
; 033CEADF:       488D5424F0       LEA RDX, [RSP-16]          ; no-arg-parsing entry point
;      AE4:       4883EC18         SUB RSP, 24
;      AE8:       488B05A9FFFFFF   MOV RAX, [RIP-87]          ; #<FDEFINITION object for REMOTE-FUNCTION>
;      AEF:       31C9             XOR ECX, ECX
;      AF1:       48892A           MOV [RDX], RBP
;      AF4:       488BEA           MOV RBP, RDX
;      AF7:       FF5009           CALL QWORD PTR [RAX+9]
;      AFA:       480F42E3         CMOVB RSP, RBX
;      AFE:       BF0A000000       MOV EDI, 10
;      B03:       41BBF0010020     MOV R11D, 536871408        ; GENERIC-+
;      B09:       41FFD3           CALL R11
;      B0C:       488BE5           MOV RSP, RBP
;      B0F:       F8               CLC
;      B10:       5D               POP RBP
;      B11:       C3               RET
NIL

With the special operator compiler hint:
the.lisp
(declaim (optimize (debug 0) (safety 0) (speed 3)))

(defun my-adder ()
  (+ 5 (the (integer 0 65535) (remote-function))))

*slime-repl sbcl*
CL-USER> (disassemble 'my-adder)
; disassembly for MY-ADDER
; Size: 41 bytes
; 0379FF5F:       488D5424F0       LEA RDX, [RSP-16]          ; no-arg-parsing entry point
;       64:       4883EC18         SUB RSP, 24
;       68:       488B05A9FFFFFF   MOV RAX, [RIP-87]          ; #<FDEFINITION object for REMOTE-FUNCTION>
;       6F:       31C9             XOR ECX, ECX
;       71:       48892A           MOV [RDX], RBP
;       74:       488BEA           MOV RBP, RDX
;       77:       FF5009           CALL QWORD PTR [RAX+9]
;       7A:       480F42E3         CMOVB RSP, RBX
;       7E:       4883C20A         ADD RDX, 10
;       82:       488BE5           MOV RSP, RBP
;       85:       F8               CLC
;       86:       5D               POP RBP
;       87:       C3               RET
NIL

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

反垃圾邮件 / Anti-spam question * Time limit is exhausted. Please reload CAPTCHA.