Hi,
I've been using Python and JavaScript extensively (during 15 years of career). I've been waiting typed script languages for a long time. I'm naive about compilation internals.
This would be something new. (or something close to Java performances, but without compilation friction in a development routine).
At this, Nim would not be "the best alternative in the shadow of Rust", but the best choice for web dev, and adminsys, and lua use-cases (character AI in games)…
And a way to code scripts, being proud of produced code.
Just use Nim already and stop thinking about irrelevant technical details like "it's the FASTEST interpreted language". That's like saying "this chocolate is the sweetest among the salted ones".
I don't use Python because it's slow, I don't use it because its scoping rules suck and dynamic typing sucks. You can make a Python implementation that beats Nim in every single benchmark and I still wouldn't want to use it. Just like I don't use LuaJIT.
How long does it take to compile it for you? For small programs it's already super fast. For big programs, there are strategies to get it down. We got the Unreal engine bindings (more than 1M line of code between Cpp and Nim) comp times under 3 seconds on superficial changes on a M1 Max. The comp without the trickery will be more than 2 minutes...
Im confident than once IC is there it will get even lower than that
I'll corroborate that Nim compiles to JS unreasonably fast compared to native. I've even used the JS backend for easy debugging.
Unfortunately it's not super fun for scripting as a substantial portion of Node.js libraries would have to be wrapped to deal with files etc and even then you might need sugar around them to match regular Nim's terseness.
You could use NimScript (Nim's compile time VM) but this is likely not going to be much faster than CPython. Even if NimScript had a JIT it might reflect on the memory footprint.
For small scripts that do a lot of work you can't go much better than regular nim r. Hell even a -d:release tag can pay off. JS or NimScript may have niche uses like testing big, pure libraries but there shouldn't be a position where they consistently overtake the native backend.
Unfortunately it's not super fun for scripting as a substantial portion of Node.js libraries would have to be wrapped
I think interpreted and JIT are a waste of time and money, Ruby throw a truckload of money into adding JIT, and for big real projects its still slow as before basically, Crystal confirms that for Ruby, WASM confirms that for JS, Cython confirms that for Python, etc (yes, they are different, but its basically the same re-imagined as AOT).
Focus on IC or multi-threading compiler.
Not sure what you mean by saying "interpreted and JIT are a waste of time and money"? Sometimes raw performance just isn't the primary concern, and you want / need other features which are hard to achieve will compiled programs (or sometimes, not needing to compile is a feature)
WASM confirms that for JS
JS is already JITed in most platforms, so its hard to improve further. WASM isn't "JS compiled" (you can't even do that), so that comparison makes little sense, but WASM is also JITed, and gets performances very close to native (I've seen as little as ~10% of overhead in WASM-ed nim programs)
Erlang JIT improved the runtime performance by as much as +130% for CPU heavy uses, so it's definitively not useless. Of course in practice, little are the applications using Erlang for CPU heavy processes, actual applications (like What's App) got something like 25%, which again shows that CPU perf just isn't that important to them.
...keeping my development routine (no compilation to wait for) but producing faster code, if Nim could be interpreted faster than native JavaScript, with efficient just-in-time compilation taking advantage of Nim typing
[Disclaimer: I have some experience with compilers but am not an expert, nor do I know the Nim compilers.]
My sense is that what you’re asking for isn’t feasible. The slow part of compiling Nim is probably the type checking and type inference, especially when generics/macros are involved. I know this is held up as a major part of the reason both Rust and Swift compile fairly slowly. And I know that C compilers are pretty fast.
Interpreting Nim probably isn’t going to get away from that, because the type analysis has to be done before code can be interpreted, and my intuition is that most of that work is global, that you can’t do it in bits and pieces as individual functions compile. (This is part of the reason that, in both Rust and Swift, compile time sometimes grows quadratically as the program size grows; and why it’s been challenging for both those languages to adopt incremental compilation.)
Nim is not “Python but with static types”. It’s never been presented that way (to my knowledge) by @araq or core Nim people.
Yes, Nim has some surface similarity to Python because they both use indentation instead of braces. That’s a really obvious thing when you look at code, but it’s pretty superficial, and there are so few similarities at other levels; I really can’t think of any.
Nim has much more in common with the Pascal/Modula/Oberon family of languages, as I think is acknowledged in the language docs.
T = int | float
a: list[T] = [1, 2, 3]
The Nim-like type-annotation was interduced in Python 3.5, long after Nimrod was released, but before it renamed to Nim.
Nim already could be used as kinda interpreted language, say like Ruby/Python, it's already fast enough, with comparable compile speed to Ruby / Python / TypeScript.
As far as I know there's (maybe even high priority?) work going on incremental compilation, it should make it much faster.
The problem with scripting mode is more like setting, as Nim out of the box comes with setting for "static" mode. You may want to change it, add "nim.cfg" to your project folder with the following content:
nim.cfg
# Hide build stats that are not needed for scripting mode
verbosity:0
# Give your project flexible structure, here's your paths.
path:"."
path:"./lib"
path:"./whatever-other-paths-you-need"
path:"./even-more-paths"
# don't want binary files to polute our project space,
# so put it in build and hide that folder in your IDE
outdir:build
listFullPaths:off
warning[UnusedImport]:off
warning[ObservableStores]:off
# Usually those are just annoying noise, hide it
hints:off
warnings:off
# Those are usefull warnings
objChecks:on
fieldChecks:on
rangeChecks:on
boundChecks:on
overflowChecks:on
floatChecks:on
nanChecks:on
infChecks:on
refChecks:on
And then just run nim r play.nim or even add shebang to the top of your nim file #!/usr/bin/env nim r and run it as ./play.nim, pretty much as ruby/python script.
I never used Nim in static mode, like building binaries etc, it's just easier to run it as nim r server.nim :)