upvote
I have heard great things about Nim, you may be very right. It’s just that it’s impossible to ignore the benefits of a mainstream dependency ecosystem. The ecosystem is exactly what made Python and Javascript the giants they are today, despite being somewhat mediocre languages. And the Rust ecosystem is in that same league, without giving up exceptional performance, and without giving up too much ergonomics.

PS: I was very enthusiastic about Cython for a good while and I went deep into it, but I found that it is rather a mess to use in practice. Yes you get C performance within Python, kinda, but you also get all the C footguns, amplified by the complex interactions with Python features.

reply
Yeah. Other ecosystems are undeniably larger than Nim's. I keep hearing about how LLMs are going to nullify that advantage with "not so sloppy" ports of anything to any PLang, but I've yet to see that pattern materialize. "What is a clean interface" is probably a kind of subjective judgement call, but also very clearly depends on PLangs and even PLang cultures. For example, the microdependency culture of Rust/JS/Node have very little to do with the PLang's themselves.

EDIT: With Cython how I mostly kept things organized was the "caller allocation" so common in C where memory was always managed the usual mostly refcounting way of CPython/NumPy, but I had dozens (maybe even 100) little "kernels" I could pass that memory into that could even use Intel/MSFT "intrinsic" asm calls (things like immintrin.h) or even just #include C code which did similar. It didn't seem too bad to me, but Nim always seemed a more complete solution (at the PLang level - not counting ecosys). (And these days there is even NimPy (https://github.com/yglukhov/nimpy) to write low-level speed-up code for Python in Nim.)

reply
There are a lot of nice things about nim, but it's absence of any kind of dynamic dispatch is a pretty serious limitation.
reply
This is misinformation. There is (at least!): `method`, procedurally typed fields (inside case-object variants or not), run-time keyed `Table` with proc values, {.dynlib.}, importc/importcpp things. Beyond that, yes, Nim has rare compile-time superpowers that do lead many of its proponents to use static constructs (totally grant that!). So, you may not see a lot of dynamic dispatch in code bases, but there is little stopping you from using them in your own code.
reply
Ah, yes, I should have been more precise. It doesn't have an equivalent of an interface/trait/protocol with dynamic dispatch.

Yes, you can pass around an object of procedures, but that is awkward, doesn't have any support from the language or stdlib, and from what I can tell isn't a normal thing that is done.

reply
Even back in 2013 there were these ideas: https://forum.nim-lang.org/t/278

I think you & I are really back & forth-ing "the PLang not enforcing/strongly encouraging a very specific way of doing things that a whole ecosystem/community organizes around". Relying instead on self-organization has many pros & cons, to be sure. Lisp suffered much the same "until" Common Lisp (which still leaves many things open). My tag line lately is: delegation affords so much, but trust sure is tricky. Much of the time people seem to discount the often rather large cost of establishing/maintaining trust. (I'm not saying you are - just that it's an easy thing to do. I think it's why there is this is a big megathread on "trusting rust", even though "rust" is a veritable suffix of "trust". Lol.)

reply