Some Common Lisp implementations do compile down to machine code. An example of one I'm told is quite good is SBCL:
* (disassemble #'(lambda () (loop for i from 1 upto 10 summing i)))
; disassembly for (LAMBDA ())
; Size: 62 bytes. Origin: #x100306FE84
; 84: BB02000000 MOV EBX, 2 ; no-arg-parsing entry point
; 89: 31C9 XOR ECX, ECX
; 8B: EB21 JMP L1
; 8D: 0F1F00 NOP
; 90: L0: 48895DF8 MOV [RBP-8], RBX
; 94: 488BD1 MOV RDX, RCX
; 97: 488BFB MOV RDI, RBX
; 9A: 41BBA0010020 MOV R11D, 536871328 ; GENERIC-+
; A0: 41FFD3 CALL R11
; A3: 488BCA MOV RCX, RDX
; A6: 488B5DF8 MOV RBX, [RBP-8]
; AA: 4883C302 ADD RBX, 2
; AE: L1: 4883FB14 CMP RBX, 20
; B2: 7EDC JLE L0
; B4: 488BD1 MOV RDX, RCX
; B7: 488BE5 MOV RSP, RBP
; BA: F8 CLC
; BB: 5D POP RBP
; BC: C3 RET
; BD: CC0A BREAK 10 ; error trap
; BF: 02 BYTE #X02
; C0: 19 BYTE #X19 ; INVALID-ARG-COUNT-ERROR
; C1: 9A BYTE #X9A ; RCX
Keep in mind that's with full run-time type checking and other nice debugging features. You can hint the compiler to turn these things off in your hardened code sections for even smaller, tighter code.