News for hackers. Stuff that matters.
Re:Nim 1.6 by turminal on Tuesday October 19, 2021 @07:32AM (#28916972)
> Why use Nim? > One language to rule them all: from shell scripting to web frontend and backend, scientific computing, deep learning, blockchain client, gamedev, embedded, see also some companies using Nim.

Does that work in practice? I can't really imagine a single language that would be a good choice for "everything".

Re:Nim 1.6 by sp33der89 on Tuesday October 19, 2021 @07:41AM (#28917036)
Well no language is perfect, but Nim can be used in almost every domain because of it's compilation targets(C, C++, JS) and it's fast compile times(who needs interpretation when compile times are that fast!):

* Shell scripting, I still assume most people will just use Bash tho: https://github.com/Vindaar/shell

* Frontend: https://github.com/karaxnim/karax or you could bind to an existing JS library.

* Backend: For something Flask-like: https://github.com/dom96/jester or something with more defaults https://github.com/planety/prologue

* Scientific computing: the wonderful SciNim https://github.com/SciNim

* Blockchain: Status has some of the biggest Nim codebases currently in production https://github.com/status-im?q=&type=&language=nim&sort=

* Gamedev: Also used in production: https://github.com/pragmagic/godot-nim and due to easy C and C++ interop, you get access to a lot of gamedev libraries!

* Embedded: this is a domain I know very little about but for example https://github.com/elcritch/nesper or https://github.com/PMunch/badger for fun Nim+embedded stuff!

Most of the disadvantages come from tooling and lack of $$$ support.

Re:Nim 1.6 by pathsjs on Tuesday October 19, 2021 @08:43AM (#28917457)
> who needs interpretation when compile times are that fast!

Well, interpretation is pretty useful for a REPL. And a REPL is not just useful to avoid compilation, but also as a way to explore a new API. And, most importantly, to preserve the results of long computations when you do not know yet what to do with it. If computing a value takes half an hour, you certainly don't want to recompute it each time you change something. Rather, you keep an open session, such as a REPL or a notebook, and keep computing with the already existing value

Re:Nim 1.6 by short_sells_poo on Tuesday October 19, 2021 @08:50AM (#28917510)
This is exactly right. What is the REPL story with NIM? Having used a REPL, I cannot even imagine doing research & analytics without one.

FWIW, this comparison between R, Pandas and Nim dataframes is quite encouraging: https://gist.github.com/Vindaar/6908c038707c7d8293049edb3d20...

This is one of the aspects that self professed R/Python datascience contenders often get wrong. The very bare minimum is a well supported and thought out dataframe library. Without that, the language is basically dead in the water. Nim seems to have a very well thought out API that also avoids many of the annoying aspects of Pandas (e.g. the huge waste coming from eagerly computing each vectorized operation into separate arrays).

Re:Nim 1.6 by pietroppeter on Tuesday October 19, 2021 @09:35AM (#28917922)
I did quench (most of) my thirst for a Repl building a notebook system (plug): https://github.com/pietroppeter/nimib

Based on that and using a book theme, scinim getting started documentation is being built, e.g.: https://scinim.github.io/getting-started/basics/data_wrangli...

Re:Nim 1.6 by sp33der89 on Tuesday October 19, 2021 @08:54AM (#28917546)
My statement was mostly an exaggeration, than an absolute truth. REPLs are really nice, but it's story with Nim is less nice.

There is: https://github.com/inim-repl/INim and the builtin `nim secret`.

There is also a Jupyter kernel: https://github.com/stisa/jupyternim

Re:Nim 1.6 by poulpy123 on Tuesday October 19, 2021 @12:48PM (#28920273)
Actually, the bare minimum is a well supported and centralised numeric library providing arrays, matrix and the base tools
Re:Nim 1.6 by short_sells_poo on Tuesday October 19, 2021 @02:16PM (#28921458)
Perhaps for some things.

Most of my work is time series analysis and I refuse to use an environment where samples are not explicitly labelled/timestamped and where the tooling does not support seamless operations that take this labeling into account.

So for my use case, a fully featured dataframe library is indeed a must.

Re:Nim 1.6 by sp33der89 on Tuesday October 19, 2021 @08:57AM (#28917564)
See my comment from the other reply on this question for potential solutions, but as an fyi for those curious, Nim does come with a VIM that comes in very handy for such purposes: https://nim-lang.org/docs/nims.html
Re:Nim 1.6 by h2odragon on Tuesday October 19, 2021 @10:42AM (#28918623)
> don't want to recompute it each time you change something

True... May I introduce you to the filesystem?

Re:Nim 1.6 by pathsjs on Tuesday October 19, 2021 @11:33AM (#28919253)
Wow, what a great invention I have been missing! You made my day! :-)
Re:Nim 1.6 by h2odragon on Tuesday October 19, 2021 @01:09PM (#28920558)
Had a project once where 70% or so of the 8 month runtime was de/serialization. 800gb or so data wad and 16gb of ram; all messily multiply interlinked and not even the indexes would fit into ram. it sucked.

but the architecture that imposed meat we were surprisingly resilient to power outages.

Re:Nim 1.6 by tyingq on Tuesday October 19, 2021 @09:17AM (#28917730)
I looked at the emitted JS when the last Nim story came out. It needs some work there. Lots of globals with names that would likely collide with other existing JS.
Re:Nim 1.6 by dom96 on Tuesday October 19, 2021 @10:22AM (#28918387)
Yeah, we definitely need to resolve this and it sounds like a fun project! If you or someone else has the time for this I (and I'm sure the rest of the community too) would love to help lead you in the right direction :)
Re:Nim 1.6 by DennisP on Tuesday October 19, 2021 @09:37AM (#28917933)
Also one of Ethereum's proof-of-stake clients is written in Nim: https://nimbus.team/docs/index.html
Re:Nim 1.6 by michaelsbradley on Tuesday October 19, 2021 @09:50PM (#28925911)
Re:Nim 1.6 by rgrmrts on Tuesday October 19, 2021 @07:54AM (#28917114)
I haven’t used nim outside of some hello world toying a few years back. Is compiling actually that fast? I thought the nim compiler compiled to C and then called gcc (or whatever system compiler), isn’t that slow in practice?

Any large nim projects that anyone can point me to would be helpful too, I’ll give the compiler a shot later today!

Re:Nim 1.6 by sp33der89 on Tuesday October 19, 2021 @08:01AM (#28917163)
The proof is in the link!

> Fast compile times: a full compiler rebuild takes ~12s (Rust: 15min, gcc: 30min+, clang: 1hr+, Go: 90s) [2].

The compiler is really big and self-hosted too.

For large nim projects check out: https://github.com/mratsim/Arraymancer or https://github.com/treeform/pixie (personal faves).

Re:Nim 1.6 by rgrmrts on Tuesday October 19, 2021 @08:04AM (#28917185)
Thanks for the links, I’ll check those out.
Re:Nim 1.6 by kevin_thibedeau on Tuesday October 19, 2021 @10:42AM (#28918617)
When using Nim for "scripting" it is recommended to use TCC for rapid compilation. It is genuinely fast.
Re:Nim 1.6 by enthus1ast on Tuesday October 19, 2021 @11:01AM (#28918823)
* Backend: For something Jinja/Twig-like: https://github.com/enthus1ast/nimja
Re:Nim 1.6 by haxscramper on Tuesday October 19, 2021 @07:49AM (#28917084)
Adjacent comment already has a list of concrete libraries/frameworks for large number of areas, so I just want to mention that nim has a very good metaprogramming capabilities, and if the /language/ itself does not feel up to the task you have a lot more freedom when it comes to implementing things. So it really comes down to the community size and amount of money poured in the development, and not fundamental problems with the language design.

This is mostly an argument about "technically you can write anything with anything", except in nim's case it is also backed by extremely high flexibility.

EDIT: by flexibility I mean

- different backends they covet very huge ecosystems (Js and C, and by extension anything they you can interface with using C (like python))

- already mentioned metaprogramming

- support for low-level convenience features like custom operators

- different memory management options. If you want you can turn off automatic mm completely and write code that deals with pointers and stuff like that directly

- more niche things like support for embedding nim interpreter in your programs https://peterme.net/using-nimscript-as-a-configuration-langu...

Re:Nim 1.6 by sp33der89 on Tuesday October 19, 2021 @07:57AM (#28917129)
Yes, this is something I should have mentioned as well, Nim does a lot of things just right and adds all the right things so it stays out of your way, is not too verbose but still has enough safety guards where you can just do what you want to do.
Re:Nim 1.6 by 1_player on Tuesday October 19, 2021 @08:50AM (#28917507)
> I can't really imagine a single language that would be a good choice for "everything".

Full stack Javascript enthusiasts are nowhere to be seen in this thread, but are writing their backend, frontend, desktop and mobile JS, WASM, Ethereum backend and the next ARM instruction set to speed up JS code natively, silently working towards total world domination. The nanomachines that will bring forth the end of the world will be running Node.js.

But I agree with you.

Re:Nim 1.6 by pchanda on Tuesday October 19, 2021 @09:57AM (#28918116)
Re:Nim 1.6 by rattray on Tuesday October 19, 2021 @09:09AM (#28917655)
JS is also great for scripting, but really isn't popular for ML or data science (no pandas/numpy/scipy equivalents I think, other than tensorflow.js).

I'm curious how Nim fares for DS/ML.

Re:Nim 1.6 by arc776 on Tuesday October 19, 2021 @10:38AM (#28918575)
Nim has a popular ML library "inspired by Numpy and PyTorch": https://github.com/mratsim/Arraymancer

One of the advantages of the language for DS/ML is the native "C like" performance with very low developer friction.

Another advantage from a library perspective is being able to automate fast, low level boiler plate code from easy to use DSLs using AST macros. For example a DSL could generate bespoke code for different data layouts and pipelines etc., giving you the best possible performance without the user worrying about it.

Re:Nim 1.6 by rattray on Tuesday October 19, 2021 @11:15AM (#28918995)
Nice! That definitely sounds enticing.
Re:Nim 1.6 by chubot on Tuesday October 19, 2021 @09:45AM (#28918011)
JS is also not fast enough at string manipulation to express its own dev tools, at least if you want to build in seconds and not minutes.

The latest incarnation of JS tools seem to be written in Go and Rust (esbuild and another one), not JS.

GC is an issue for compilers, or even just front ends, which create huge, fine-grained, linked data structures

Re:Nim 1.6 by rattray on Tuesday October 19, 2021 @09:57AM (#28918117)
Sure, JS isn't ideal for compilers, but it is quite good - typescript is a better and more performant compiler than many languages have, as just one example.

You wouldn't be crazy for choosing JS for a new compiler project, even for work that had nothing to do with JavaScript.

(You would be pretty crazy to choose js to build a rich data science backend, in comparison).

I do agree the GC rules out some use-cases like many gaming applications.

Re:Nim 1.6 by 1_player on Tuesday October 19, 2021 @10:10AM (#28918248)
Please don't write a compiler, that has nothing to do with JavaScript, in JavaScript. It needs correctness, safety and speed, none of which are JS (nor TS) strengths.

You can, but that's a prerogative of all Turing-complete languages.

There are much better languages fit for the purpose, which is the point of this comment thread.

Re:Nim 1.6 by rattray on Tuesday October 19, 2021 @10:38AM (#28918563)
Hmm, we're discussing "just how general-purpose can your general-purpose language be?", no? Ie, if a company wanted to use one language for everything, where would they be essentially unable to?

Keep in mind "a compiler" may not be for "a widely used general purpose programming language" but something smaller with a specific use, especially in the context of a company.

JS has many quality libraries for parsing grammars etc, and is Fast Enough for the purpose unless you need incredible perf - Python or Ruby, for example, might be much worse choices.

Even C++ might be a worse choice depending on your project's objectives (sure it might be faster but it might be a lot less maintainable, especially compared to TS). I also don't buy the argument that TS would make it harder to write a correct/safe compiler than C++.

Rust and Haskell may be sexy for the purpose but would be much slower to get started with, especially if your team isn't already staffed with experts. The Sorbet team at Stripe chose C++ over Rust because they felt developing with the latter would be too slow.

Keep in mind that most people are sticking with pure-JS build stacks even as esbuild et al are coming on to the scene. And the TS team has stuck with a Node compiler despite having the resources and know-how to use something totally different.

Please don't tell people to avoid writing a compiler in JS/TS unless you really know the specifics. :)

Of course, all of this does make me curious how Nim is for compilers (I imagine it'd be very, very nice).

Re:Nim 1.6 by Zababa on Tuesday October 19, 2021 @09:01AM (#28917593)
I think Nim is in the sweet spot for it. You start with basically OCaml, which is already a great start, add some knobs for tweaking memory management, some for high performance, and you're in a great places. Compiling to native and to JS allows you to do web, cli tooling, applications, high level gamedev. Fast compilation is important for scripting, high level gamedev, exploratory programming, scripting. High performance allows you to do low level gamedev, deep learning, stuff like that. Being bootstapable from C and compiling to it with the memory management tweaks opens you the world of embedded.

There's also the fact that not all language are perfect. If they all are, the general language would always lose to the specific in every niche, so you need to do different things for the general to be worth. But languages aren't perfect, and you could prefer the general language even in niches.

Re:Nim 1.6 by haxscramper on Tuesday October 19, 2021 @09:18AM (#28917748)
I can't remember exact place where I've seen this discussion (I think it was on the nim IRC), but if I recall correctly, the original line of thought with nim was to take C (because fast/compiled/available-everywhere) and LISP (because flexible/extensible/good-ideas) and add more syntax sugar, so that user would not have to reimplement most of the syntax from scratch (using reader macros/special functions and so on).

There are of course a lot of other languages that influenced the syntax and semantics (like Ada, python, C++ and so on), and I omitted a huge number of extra considerations.

Re:Nim 1.6 by dom96 on Tuesday October 19, 2021 @10:03AM (#28918175)
Indeed, in fact the original line of thought was[1]:

> [combining] Lisp's power with Python's readability and C's performance.

I'd say Nim still satisfies this very well.

1 - https://web.archive.org/web/20110704041631/http://force7.de/...

Re:Nim 1.6 by Zababa on Tuesday October 19, 2021 @11:31AM (#28919231)
Interesting, I think Julia was close to that too:

> We want a language that's open source, with a liberal license. We want the speed of C with the dynamism of Ruby. We want a language that's homoiconic, with true macros like Lisp, but with obvious, familiar mathematical notation like Matlab. We want something as usable for general programming as Python, as easy for statistics as R, as natural for string processing as Perl, as powerful for linear algebra as Matlab, as good at gluing programs together as the shell. Something that is dirt simple to learn, yet keeps the most serious hackers happy. We want it interactive and we want it compiled.

https://julialang.org/blog/2012/02/why-we-created-julia/

Re:Nim 1.6 by Zababa on Tuesday October 19, 2021 @12:20PM (#28919898)
Interesting. No mention of Pascal or its descendants, specifically Modula 2 or 3? From what I understood, that's where Nim got its fast compilation and modules, like OCaml.
Re:Nim 1.6 by xigoi on Tuesday October 19, 2021 @06:47PM (#28924703)
If you ignore the whitespace sensitivity, Nim's syntax is actually more similar to Pascal than to Python.
Re:Nim 1.6 by systemvoltage on Tuesday October 19, 2021 @11:59AM (#28919602)
Comparing with Julia, which claims to be a do-all fit-all language, I'd take Nim any day. I've used Julia in production for many years and it is an absolute nightmare to maintain.

Nim seems to be what python should have been from the beginning. It is a breath of fresh air.

Re:Nim 1.6 by benob on Tuesday October 19, 2021 @08:38AM (#28917409)
C interop is very easy, so you can do embedded dev by disabling memory management and standard lib, and staying very close to the generated C code.

Or you can do high level stuff thanks to well though generics and meta programming.

The js backend is not mature enough to cover high performance web apps. It is more like a gimmick currently. Maybe a wasm layer could be as successful as rust's...

Re:Nim 1.6 by auxym on Tuesday October 19, 2021 @02:49PM (#28921898)
> Or you can do high level stuff thanks to well though generics and meta programming.

Metaprogramming is also surprisingly useful for low-level, embedded programming. Eg, using compile-time logic (branching, looping) to decide which bit in which register you want to twiddle, instead of doing it at runtime, which saves computation and (sometimes) code size.

Re:Nim 1.6 by mst on Tuesday October 19, 2021 @09:05AM (#28917630)
It's not necessarily the best choice for everything for any given team, but in the same way you'll see e.g. shops that have bought in heavily to using go by default using go for writing scripty tools as well as their main applications, using nim as 'the default language unless there's a use case specific reason to use something else' is surprisingly doable.
Re:Nim 1.6 by coliveira on Tuesday October 19, 2021 @09:10AM (#28917669)
This is not a new concept, decades ago computer scientists started working on general purpose languages, that were supposed to be good for (almost) everything. The idea that a language has to serve a niche is a modern construction.
Re:Nim 1.6 by mumblemumble on Tuesday October 19, 2021 @09:37AM (#28917944)
The probable gaps I see are embedded and certain branches of gamedev, and shell scripting. Regardless of what Nim says in its sales pitch, it is a garbage collected language, and garbage collection is not really optional. The closest options are nothing, automatic reference counting (ARC), and automatic reference counting with cycle deletion (Nim calls this one ORC).

Nothing at all might be fine for cloud lambda functions and command line utilities, but it generally isn't acceptable for long-running processes such as video games and firmware. ARC will still leak memory when there are cycles, so it can work if you are very careful about how you manage data. But it's trickier than what you get out of modern C++, and more resource-hungry than full manual memory management, so I can't really see this option being ideal for gamedev or embedded. And ORC is basically just Python's garbage collection algorithm, with all its strengths and weaknesses.

For shell scripting, at the end of the day, it is still a statically typed, compiled language. This just doesn't hit the sweet spot for a scripting language. In that context, the performance of the language itself doesn't really matter, the entire operating context is irredeemably weakly typed, and nothing you do will ever grow large enough for static types to help much with maintainability. I'd much rather have the fast edit-test cycles of an interpreted dynamic language.

That said, what I have successfully used Nim for is writing command-line tools that I interact with from shell scripts. But there, it's not replacing sh or perl or python, it's replacing C.

Re:Nim 1.6 by PMunch on Tuesday October 19, 2021 @09:53AM (#28918072)
Nim works super well for embedded. The thing is that you can turn off the garbage collector and do manual memory allocation if you want to. Or simply use ARC which works a treat on embedded. I wrote my own keyboard firmware in Nim (and did a presentation of it during NimConf 2021: https://www.youtube.com/watch?v=dcHEhO4J29U). It runs super fast and the code size is smaller than some simple "Hello world" level programs using the Arduino system.

As for gamedev the ability to tune the GC by turning off automatic collection and then running it with a time-limit is perfect for preventing lag-spikes when a lot of stuff is going on (looking at you Java..). Nim actually performs very well, and the garbage collector does a great job of just getting out of the way and letting your programs fly.

Your point about shell-scripting is kind of valid, it is indeed a weakly typed world. But with how fast Nim compiles the edit-test cycle feels as fast as Python, and you save a lot of time from having a silly typo that you only encounter after having run your script for a little while.

The reason why Nim is good for pretty much anything is that the speed of the compiler and the garbage collection will rarely if ever stand in your way, and the flexibility of the syntax that stems from meta-programming allows it to be molded perfectly to the use-case.

Re:Nim 1.6 by elcritch on Wednesday October 20, 2021 @01:08AM (#28926967)
Nim does work very well for embedded. From small stack only memory management, possible with value types and basic Nim proc's. Or use ARC for MCUs with 100's kB of RAM, which are fairly common nowadays.
Re:Nim 1.6 by DeathArrow on Tuesday October 19, 2021 @11:58AM (#28919590)
But garbage collection is really optional. You can use manual memory management: https://play.nim-lang.org/#ix=3uVt

You even have smart pointers if you need: https://nim-lang.github.io/fusion/src/fusion/smartptrs.html

Re:Nim 1.6 by arc776 on Tuesday October 19, 2021 @12:32PM (#28920069)
> it is a garbage collected language

GC has to be explicitly attached to types. By default everything is a value type allocated on the stack, and managed by scope. Nim is also clever enough to optimise away copies for value types (such as passing immutable parameters). GC is only really used for reference semantics.

> garbage collection is not really optional

Sure it is. Some of the stdlib uses GC for dynamic lists, but if you're after ultimate control you can easily make your own dynamic lists using manual memory management thanks to the type system and move semantics.

> ARC will still leak memory when there are cycles, so it can work if you are very careful about how you manage data.

If you have cycles and want GC, as you mention, you'd use ORC. As a point of comparison, Rust references also leak with cycles https://doc.rust-lang.org/book/ch15-06-reference-cycles.html

> But it's trickier than what you get out of modern C++, and more resource-hungry than full manual memory management, so I can't really see this option being ideal for gamedev or embedded.

I'm curious how ARC/ORC are tricky to use? Currently it's just a compile switch (soon to become default). There's not really any 'usage' at all, it just switches assignment to move semantics where possible.

> I can't really see this option being ideal for gamedev or embedded.

My personal experience is that ARC/ORC are extremely performant. They don't "stop the world" like Java/Python and are designed to be suitable for embedded work.

In particular ARC offers "deterministic performance for hard realtime systems". For ORC and other GCs you can manually step collection and define soft-realtime collection pause limits. You can even plug in other GC implementations, or create your own if you have specific requirements.

The memory model https://nim-lang.org/docs/gc.html states:

    Nim provides multiple paradigms for needs ranging from large multi-threaded applications, to games, hard realtime systems and small microcontrollers.
As an example of a large and complex project running on embedded and using GC, see the Nimbus Ethereum client. Embedded is actually a big use case for Nim specifically because of how memory and CPU efficient the language can be, and how tunable everything is.

Besides, generating a lot of garbage each frame is a design issue in gamedev. Normally you'd preallocate or at least chunk allocate.

> ORC is basically just Python's garbage collection algorithm

ARC is more similar to Rust's move semantics or C++'s smart pointers, and ORC just adds a cycle collector on top. You can also mark types as `acyclic` to remove cycle collection by type.

What makes it ideal for gamedev is high productivity, run time execution speed, interfacing with C/C++ natively, and tools like AST macros.

> For shell scripting, at the end of the day, it is still a statically typed, compiled language. This just doesn't hit the sweet spot for a scripting language ... the entire operating context is irredeemably weakly typed, and nothing you do will ever grow large enough for static types to help much with maintainability.

I think scripting being "irredeemably weakly typed" is a matter of opinion. With good type inference, you get almost all of the advantages of dynamic types, such as fast edit-test cycles, without the pain of not knowing what anything is. Weak typing is ultimately just how you define converters, and I prefer making that explicit rather than lenient (libraries can make typing effectively 'weaker', e.g., https://nim-lang.org/docs/lenientops.html ).

There's nothing you can't do in statically typed languages that you can in dynamically typed languages. The only disadvantage Nim has over, say, Python, is it's weaker REPL support for now (hot code reloading is WIP: https://nim-lang.org/docs/hcr.html ).

The nimscript subset of the language available at compile time is actually really good for scripting on its own, and is used for scripting builds without needing a separate language: https://nim-lang.org/docs/nims.html

Re:Nim 1.6 by benttoothpaste on Tuesday October 19, 2021 @09:15AM (#28917711)
I heard PL/I was the original language for “everything”. It’s not a new concept :)
Re:Nim 1.6 by kettunen on Tuesday October 19, 2021 @07:46AM (#28917063)
Yeah, these kind of statements feel very “empty” to me. That’s probably true that you could do everything with Nim, it’s also true that you can do everything with every language. Should you? That is another question.
Re:Nim 1.6 by GavinMcG on Tuesday October 19, 2021 @07:53AM (#28917102)
You say "empty", but each of the listed uses links to a project as evidence, and the claim is followed up with specific evidence about small binaries, fast compile times, native performance, multiplatform targeting, etc.

Given all that, what are you still looking for to make the statement non-empty?

Re:Nim 1.6 by xet7 on Tuesday October 19, 2021 @08:03AM (#28917176)
Unfortunately, it's not possible to do everything with every programming language. If thinking of rewrite of some software, it depends does all dependencies, database drivers, authentication, etc exist for some other programming language.
Re:Nim 1.6 by arc776 on Tuesday October 19, 2021 @10:06AM (#28918214)
Being able to compile to C, C++, ObjC, and JavaScript natively (and LLVM using https://github.com/arnetheduck/nlvm ), along with an excellent FFI (including to and from Python) means you don't need to rewrite dependencies as you can use them directly. Nim is great at glue code - arguably better/easier than Python.

Along with general language characteristics such as being high level and productive like Python, but with intricate "bare metal" control when you want it, really does make it suitable for writing almost everything.

Re:Nim 1.6 by xigoi on Tuesday October 19, 2021 @06:52PM (#28924741)
Can you show me how to write a frontend web app with C? Or how to make a keyboard driver with Python?