Hacker News new | past | comments | ask | show | jobs | submit login

NewtonScript 2.0 introduced a mechanism to manually JIT code, functions marked as native get compiled into machine code.

Had the Newton not been canceled, probably there would be an evolution from that support.

See "Compiling Functions for Speed"

https://www.newted.org/download/manuals/NewtonToolkitUsersGu...




this is great, thanks! but it sounds like it was an aot compiler, not a jit compiler; for example, it explains that a drawback of compiling functions to native code is that they use more memory, and that the compiler still produces bytecode for the functions it compiles natively, unless you suppress the bytecode compilation in project settings


Yeah, I guess if one wants to go more technical, I see it as the first step of a JIT that didn't had the opportunity to evolve due to market decisions.


i guess if they had, we would know whether a jit made newtonscript faster or slower, but they didn't, so we don't. what we do know is that an aot compiler sometimes made newtonscript faster (though maybe only if you added enough manifest static typing annotations to your source code)

that seems closer to the opposite of what you were saying in the point on which we were in disagreement?


I guess my recolection regarding NewtonScript wasn't correct, if you prefer that I put it like that, however I am quite certain in regards to the other languages in my list.


i agree that the other languages gained a lot for sure

maybe i should have said that up front!

except maybe common lisp; all the implementations i know are interpreted or aot-compiled (sometimes an expression at a time, like sbcl), but maybe there's a jit-compiled one, and i bet it's great

probably with enough work python could gain a similar amount. it's possible that work might get done. but it seems likely that it'll have to give up things like reference-counting, as smalltalk did (which most of the other languages never had)


Note that interpreter in the Lisp world by default has a different meaning.

A "Lisp interpreter" runs Lisp source in the form of s-expressions. That's what the first Lisp did.

A "Lisp compiler" compiles Lisp source code to native code, either directly or with the help of a C compiler or an assembler. A Lisp compiler could also compile source code to byte code. In some implementations this byte code can be JIT compiled (ABCL, CLISP, ...).

The first Lisp provided a Lisp to assembly compiler, which compiled Lisp code to assembly code, which then gets compiled to machine code. That machine code could be loaded into Lisp and functions then could be native machine code.

The Newton Toolkit could compile type declared functions to machine code. That's something most Common Lisp compilers do, sometimes by default (SBCL, CCL, ... by default directly compile source code to machine code).

SBCL:

    * (defun add (a b) (declare (fixnum a b) (optimize (speed 3))) (+ a b))
    ADD
    * (disassemble #'add)
    ; disassembly for ADD
    ; Size: 104 bytes. Origin: #x7006E1789C                       ; ADD
    ; 89C:       0000018B         ADD NL0, NL0, NL1
    ; 8A0:       0A0000AB         ADDS R0, NL0, NL0
    ; 8A4:       E7010054         BVC L1
    ; 8A8:       BD2A00B9         STR WNULL, [THREAD, #40]        ; pseudo-atomic-bits
    ; 8AC:       BC7A47A9         LDP TMP, LR, [THREAD, #112]     ; mixed-tlab.{free-pointer, end-addr}
    ; 8B0:       8A430091         ADD R0, TMP, #16
    ; 8B4:       5F011EEB         CMP R0, LR
    ; 8B8:       E8010054         BHI L2
    ; 8BC:       AA3A00F9         STR R0, [THREAD, #112]          ; mixed-tlab
    ; 8C0: L0:   8A3F0091         ADD R0, TMP, #15
    ; 8C4:       3E2280D2         MOVZ LR, #273
    ; 8C8:       9E0300A9         STP LR, NL0, [TMP]
    ; 8CC:       BF3A03D5         DMB ISHST
    ; 8D0:       BF2A00B9         STR WZR, [THREAD, #40]          ; pseudo-atomic-bits
    ; 8D4:       BE2E40B9         LDR WLR, [THREAD, #44]          ; pseudo-atomic-bits
    ; 8D8:       5E0000B4         CBZ LR, L1
    ; 8DC:       200120D4         BRK #9                          ; Pending interrupt trap
    ; 8E0: L1:   FB031AAA         MOV CSP, CFP
    ; 8E4:       5A7B40A9         LDP CFP, LR, [CFP]
    ; 8E8:       BF0300F1         CMP NULL, #0
    ; 8EC:       C0035FD6         RET
    ; 8F0:       E00120D4         BRK #15                         ; Invalid argument count trap
    ; 8F4: L2:   1C0280D2         MOVZ TMP, #16
    ; 8F8:       0AFBFF58         LDR R0, #x7006E17858            ; SB-VM::ALLOC-TRAMP
    ; 8FC:       40013FD6         BLR R0
    ; 900:       F0FFFF17         B L0
    NIL
I've entered a function and it gets ahead of time compiled to non-generic machine code.

Calling the function ADD with the wrong numeric arguments is an error, which will be detected both a compile and at runtime.

    * (add 3.0 2.0)

    debugger invoked on a TYPE-ERROR @7006E17898 in thread
    #<THREAD "main thread" RUNNING {70088224A3}>:
      The value
        3.0
      is not of type
        FIXNUM
      when binding A
Redefinition of + will do nothing to the code. The addition is inlined machine code.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

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

Search: