Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Common Lisp is an example of a compiled dynamic language.


And 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).


In 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.


There 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
    *


Overkill.

This article isn't a dictionary entry, an encyclopedia, or a research paper. It describes what's necessary to build a programming language for someone who has the necessary skills, which is someone who programs.

The entire premise of this programming language isn't based on as rigorous ideas as what you're criticizing, and that's been the reaction since the first time I posted about it.

As for what I was talking about, I'm only interested in dynamically typed languages that are compiled and provide support for 'eval in this case, because I don't believe that this is possible without providing a complete library for an interpreter with a compiled executable. For every other case, who really cares? Being able to replace every variable declaration with the keyword `auto' does not a new (or useful) programming language make. Additionally, all of these other gray areas in-between are not something I am interested in.

For this purpose, when speaking of the Duck programming language, dynamicism refers to being able to literally manipulate types and data in any way imaginable, both in terms of runtime behavior AND typing. In any case, it is designed to be the most dynamic language, as the union of all of these features, and as such that invalidates a huge number of complaints.

>> 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?

This is a very minor complaint and mirrors 99% of the criticism I've received.

I wish I could get more interesting feedback for the content of my writing rather than the semantics.


As is JavaScript


No, 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.


I 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.


Since 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-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


Could you elaborate on this point?


The biggest gain of the tracing JITs is elimination of dynamic dispatch. CL does not use it to an extend comparable to JavaScript, Python or Smalltalk.


That depends largely on the implementation and libraries. Some make extensive use of CLOS in I/O for example.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: