''[Brought here from LispSucks, since that page already had more clutter than it needed...]'' Don't you mean "'''at''' assembly"? And isn't an editorial comment to that effect called for? We may have a variety of reactions to the asm below; it doesn't entirely speak for itself. ''Negative. This page was abstracted from the original LispSucks page and brought here just to keep the yards of assembly listings out of the main stream of ThreadMode conversation (read, bickering). Therefore, "Lisp sucks, in assembly."'' This still isn't clear English, even given your explanation. This amounts to something like "Lisp sucks: assembly examined" or some such? ''Not really. It could have been, "Lisp sucks, in Swedish" or "Lisp sucks, in Klingon" but it's in assembly. Eh?'' ---- ''Isn't blazing fast? I guess you aren't talking about CommonLisp then.'' I agree that Lisp is faster than most of the popular languages today - JavaLanguage and PythonLanguage. I was really '''only''' talking about CeeLanguage and CeePlusPlus, which are still the dominant languages for programming things like servers and large GUI based applications. It's worth pointing out that in both of those cases it has been found useful to embed Lisp in the program. ''For my own code, which tends to be highly numeric and nothing like business apps, I usually find Lisp to range around +- 20% of c++ (yes, sometimes it is faster). Sometimes, however I find it is a factor of 2-5 slower on the same code where c++ had a particularly clever optimization I can't get my lisp compiler to make. On the other hand, sometimes my lisp is a factor of 2-5 faster, if I implement an algorithmic improvement which is simply too much trouble in c++. Of course, YourMileageMayVary, but I would expect that raw execution speed is almost never a compelling argument for c++ over CL, for 'normal' applications. I myself touch on some applications (large-scale simulations) where raw execution speed is crucial, but in that case you run on special hardware and expect to jump through many hoops to get that speed, including things like re-implementing in fortran or c++ with compiler-specific extensions etc. Large server apps may have similar constraints, but we are hardly talking about mainstream development now.'' ComputerLanguageBenchmarksGame Without exception, every proprietary Lisp implementation on the market has a native compiler that puts out good machine code and respects optimizing declarations. And some free ones do also. Some Lisps, like Conan Lisp, do not even contain an interpreter! Every expression processed by Conan Lisp is converted into 80x86 machine code and then executed as such. ''And many Lisps are not afraid to get you close to the metal. The ''disassemble'' function is a nice example (this is in CMUCL):'' * (defun sum (n) (loop for i from 1 to n sum i)) SUM * (sum 5) 15 PJB: how convenient an example. Rather, try: (sum 5000000000). See also: https://groups.google.com/forum/message/raw?msg=comp.lang.lisp/a36NKUYogvI/KWBtYkb-SXoJ (compare Lisp and C with factorial instead of sum). * (disassemble #'sum) Compiling LAMBDA (N): Compiling Top-Level Form: 48131B90: .ENTRY "LAMBDA (N)"(n) ; (FUNCTION (T) NUMBER) BA8: POP DWORD PTR [EBP-8] BAB: LEA ESP, [EBP-32] BAE: MOV EDI, EDX BB0: CMP ECX, 4 BB3: JNE L2 BB5: MOV [EBP-12], EDI BB8: MOV DWORD PTR [EBP-16], 4 ; No-arg-parsing entry point BBF: MOV DWORD PTR [EBP-20], 0 BC6: JMP L1 BC8: L0: MOV EDX, [EBP-20] BCB: MOV EDI, [EBP-16] BCE: CALL #x100001C8 BD3: MOV ESP, EBX BD5: MOV [EBP-20], EDX BD8: MOV EDX, [EBP-16] BDB: MOV EDI, 4 BE0: CALL #x100001C8 BE5: MOV ESP, EBX BE7: MOV [EBP-16], EDX BEA: L1: MOV EDX, [EBP-16] BED: MOV EDI, [EBP-12] ;;; [4] (LOOP FOR I FROM ...) BF0: CALL #x10000460 BF5: MOV ESP, EBX BF7: CMP EDX, #x2800000B ; NIL BFD: JEQ L0 BFF: MOV EDX, [EBP-20] C02: MOV ECX, [EBP-8] C05: MOV EAX, [EBP-4] C08: ADD ECX, 2 C0B: MOV ESP, EBP C0D: MOV EBP, EAX C0F: JMP ECX C11: NOP C12: NOP C13: NOP C14: NOP C15: NOP C16: NOP C17: NOP C18: L2: BREAK 10 ; Error trap C1A: BYTE #x02 C1B: BYTE #x19 ; INVALID-ARGUMENT-COUNT-ERROR C1C: BYTE #x4D ; ECX ''Note that ''disassemble'' is a standard feature. Here's how it works in CLISP, a bytecode-interpreting implementation:'' [1]> (defun sum (n) (loop for i from 1 to n sum i)) SUM [2]> (disassemble #'sum) Disassembly of function SUM (CONST 0) = 0 (CONST 1) = 1 1 required arguments 0 optional arguments No rest parameter No keyword parameters 0 (CONST&PUSH 0) ; 0 1 (CONST&PUSH 1) ; 1 2 (JMP L12) 4 L4 4 (LOAD&PUSH 1) 5 (LOAD&PUSH 1) 6 (CALLSR&STORE 2 54 1) ; + 10 (LOAD&INC&STORE 0) 12 L12 12 (LOAD&PUSH 0) 13 (LOAD&PUSH 4) 14 (CALLSR&JMPIFNOT 1 49 L4) ; > 18 (LOAD 1) 19 (SKIP&RET 4) # ''CommonLisp ain't for QuicheEaters!'' ---- By the way, if anyone's looking at the disassembled x86 machine code for the SUM function above and thinking "yeccch, that's ten times worse than it would be in C", here's what you get if you throw in some type declarations (like you need all the time in C) and tell the compiler to prefer speed over safety (like you get all the time in C). 48081060: .ENTRY SUM(n) ; (FUNCTION (FIXNUM) FIXNUM) 78: POP DWORD PTR [EBP-8] 7B: LEA ESP, [EBP-32] 7E: MOV EAX, 4 ; No-arg-parsing entry point 83: XOR ECX, ECX 85: JMP L1 87: L0: ADD ECX, EAX 89: ADD EAX, 4 8C: L1: CMP EAX, EDX 8E: JLE L0 90: MOV EDX, ECX 92: MOV ECX, [EBP-8] 95: MOV EAX, [EBP-4] 98: ADD ECX, 2 9B: MOV ESP, EBP 9D: MOV EBP, EAX 9F: JMP ECX A1: NOP A2: NOP A3: NOP A4: NOP ;;; [7] (LOOP FOR I FIXNUM ...) A5: NOP A6: NOP A7: NOP Of course, a ''really'' smart compiler could produce 480C65D0: .ENTRY SUM(n) ; (FUNCTION (FIXNUM) (SIGNED-BYTE 29)) 5E8: POP DWORD PTR [EBP-8] 5EB: LEA ESP, [EBP-32] 5EE: LEA EAX, [EDX+4] ; No-arg-parsing entry point 5F1: SAR EDX, 2 5F4: IMUL EDX, EAX 5F7: SAR EDX, 1 5F9: AND EDX, 4294967292 5FF: MOV ECX, [EBP-8] 602: MOV EAX, [EBP-4] 605: ADD ECX, 2 608: MOV ESP, EBP 60A: MOV EBP, EAX 60C: JMP ECX 60E: NOP 60F: NOP instead ... ------ I saw the title and initially envisioned something that looked like this :-) (EAX (JMP (SAR EPX NOP) ESP LEA) MOV (ADD EBP)) JLE EBP) ---- CategorySucks CategoryLisp