4 ms·
Common Lisp is an example of a compiled dynamic language.
by KC8ZKF 11y ago
Common Lisp is an example of a compiled dynamic language.
- bigtunacan 11y agoAs is JavaScript
- sklogic 11y agoNo, they're very far away from each other on the dynamism scale. There is absolutely no point in trying to compile JavaScript statically, but yet it works very well for Common Lisp. The opposite is also true, smart tracing JITs won't do much for Common Lisp, but shine for JavaScript.
- bigtunacan 11y agoI was just adding on that JavaScript is another example of a dynamic language that is compiled (using JIT in this case) rather than strictly interpreted such as the MRI implementation of Ruby.
- bigtunacan 11y agoSince both this and my parent post on JavaScript being compiled were downvoted without comment I can only make the assumption this is because someone came along who believes this is not the case. So first I will link out to this StackExchange doc that does a pretty good job of describing this. http://programmers.stackexchange.com/questions/138521/is-javascript-interpreted-by-design http://programmers.stackexchange.com/questions/138521/is-jav... The JavaScript specification says nothing about the language being interpreted or compiled. Today; most current versions of major browsers use a just in time compiler to handle JavaScript. V8 (Chrome & Nodejs), SpiderMonkey (Firefox), Chakra (InternetExplorer), Carakan (Opera), JavaScriptCore(Webkit/Safari) For more information take a look at the Wiki entry for EcmaScript engines. https://en.wikipedia.org/wiki/List_of_ECMAScript_engines https://en.wikipedia.org/wiki/List_of_ECMAScript_engines
- nemoniac 11y agoCould you elaborate on this point?
- xigency 11y agoAnd a rather opaque one at that. I've never heard of anyone discussing the implementation details of a Scheme or Lisp compiler, leading me to believe that they must have really complicated internal logic. I might be better served applying my time towards development on Chicken (Scheme).
- xigency 11y agoIn response to being downvoted — I would assume that tracking all of the records in function closures (first-class functions) would be a real headache, though slightly aided by the fact that garbage collection is available, and the question of whether to support eval raises a number of issues. In any case, compiled Common Lisp is not something that resembles other compiled languages... and the purpose of my article is to discuss either designing an interpreter or a compiler, not a dynamic compiler, recompiler, or compiled code that requires some kind of runtime interpreter as a side, all of which are extraneous use cases for hackers not people learning how to program. They also make for poor pedagogical tools.
- lispm 11y agoThere are books about Lisp implementations and papers about various Lisp compilers. Actually there is a whole bunch of literature about it. Personally I find that the article needs a bunch of improvements: static vs. dynamic vs. statically typed and dynamically typed These are different things. Either we are talking about runtime behavior (a dynamic language can change itself or the program at runtime) or we are talking about typing. For example Java is a statically typed language, but it allows the use of class loaders which can reload classes at runtime - which provides some dynamic features. On the other end of the spectrum are many compiled Lisp implementations which allow various changes to the programming language at runtime, for example via an extensive meta-object protocol. > Attempting to access a value that has not been named in a relevant scope leads to a syntax error issued at compile time. A syntax error? Really? Syntax? > So called dynamically typed languages are sometimes referred to as duck-typed or duck languages. Definitely not. Duck typing is a only a special form of dynamic typing, usually in an object-oriented language. Non object-oriented dynamically typed languages don't provide duck typing, because they lack OOP objects. Does compiled Lisp look different? Maybe... Let's look at SBCL on a 64bit Intel processor: * (defun calc (a b c) (+ (* 2 a) (* 3 b) (* 4 c))) CALC * (disassemble #'calc) ; disassembly for CALC ; Size: 118 bytes. Origin: #x1002EC2599 ; 599: 48895DE8 MOV [RBP-24], RBX ; no-arg-parsing entry point ; 59D: BF04000000 MOV EDI, 4 ; 5A2: 488BD1 MOV RDX, RCX ; 5A5: 41BBD0020020 MOV R11D, 536871632 ; GENERIC-* ; 5AB: 41FFD3 CALL R11 ; 5AE: 488BF2 MOV RSI, RDX ; 5B1: 488B5DE8 MOV RBX, [RBP-24] ; 5B5: 488975F0 MOV [RBP-16], RSI ; 5B9: BF06000000 MOV EDI, 6 ; 5BE: 488BD3 MOV RDX, RBX ; 5C1: 41BBD0020020 MOV R11D, 536871632 ; GENERIC-* ; 5C7: 41FFD3 CALL R11 ; 5CA: 488BFA MOV RDI, RDX ; 5CD: 488B75F0 MOV RSI, [RBP-16] ; 5D1: 488BD6 MOV RDX, RSI ; 5D4: 41BBD0010020 MOV R11D, 536871376 ; GENERIC-+ ; 5DA: 41FFD3 CALL R11 ; 5DD: 488BDA MOV RBX, RDX ; 5E0: 48895DF0 MOV [RBP-16], RBX ; 5E4: 488B55F8 MOV RDX, [RBP-8] ; 5E8: BF08000000 MOV EDI, 8 ; 5ED: 41BBD0020020 MOV R11D, 536871632 ; GENERIC-* ; 5F3: 41FFD3 CALL R11 ; 5F6: 488BFA MOV RDI, RDX ; 5F9: 488B5DF0 MOV RBX, [RBP-16] ; 5FD: 488BD3 MOV RDX, RBX ; 600: 41BBD0010020 MOV R11D, 536871376 ; GENERIC-+ ; 606: 41FFD3 CALL R11 ; 609: 488BE5 MOV RSP, RBP ; 60C: F8 CLC ; 60D: 5D POP RBP ; 60E: C3 RET NIL Now we can even define the types in Common Lisp: * (defun calc (a b c) (declare (fixnum a b c)) (the fixnum (+ (the fixnum (* 2 a)) (the fixnum (* 3 b)) (the fixnum (* 4 c))))) STYLE-WARNING: redefining COMMON-LISP-USER::CALC in DEFUN CALC * (disassemble #'calc) ; disassembly for CALC ; Size: 38 bytes. Origin: #x1002F4B802 ; 02: 48D1E1 SHL RCX, 1 ; no-arg-parsing entry point ; 05: 488D047F LEA RAX, [RDI+RDI*2] ; 09: 48D1F9 SAR RCX, 1 ; 0C: 48D1F8 SAR RAX, 1 ; 0F: 4801C1 ADD RCX, RAX ; 12: 48C1E602 SHL RSI, 2 ; 16: 48D1FE SAR RSI, 1 ; 19: 4801F1 ADD RCX, RSI ; 1C: 48D1E1 SHL RCX, 1 ; 1F: 488BD1 MOV RDX, RCX ; 22: 488BE5 MOV RSP, RBP ; 25: F8 CLC ; 26: 5D POP RBP ; 27: C3 RET NIL *