cb321 3 hours ago

This is a decent overview, but misses a few nice things. Interested readers should not assume it is exhaustive (generally something they should not assume..)

E.g., because the feature is so rare (controversial?) it doesn't get mentioned much, but you can also define your own operators in Nim. So, if you miss bitwise `|=` from C-like PLangs, you can just say:

    proc `|=`*[T,U](a: var T, b: U) = a = a or b
Of course, Nim has a built in `set[T]` for managing bit sets in a nicer fashion with traditionally named set theoretic operators like intersection, union, etc. https://github.com/c-blake/procs makes a lot of use of set[enum] to do its dependency analysis of what Linux /proc files to load and what fields to parse, for example (and is generally much faster than C procps alternatives).

This same user-defined operator notation for calls can be used for templates and macros as well which makes a number of customized notations/domain specific languages (DSLs) very easy. And pragma macros make it easy to tag definitions with special compile-time behaviors. And so on.

  • j1elo an hour ago

    That's cool! One I do miss (from nowhere else, I just thought it should exist) sometimes in C is `||=`, and that's sorely missed when bitwise operators do indeed have `|=` (which must not be conflated because it is very different by not implementing short-circuiting to skip right-hand side of operations).

vanderZwan 2 hours ago

> In fact, you could use Nim as a production-ready alternative to the upcoming Carbon language. Nim has fantastic interoperability with C++, supporting templates, constructors, destructors, overloaded operators, etc. However, it does not compile to readable C or C++ code, which is unlike Carbon's goals.

Well, that really depends on what the reason for one's interest in Carbon is, which is slightly hinted at by the last sentence. From what I understand big goal is to be able to do automated migration of large C++ codebases at Google to a saner language. Mond had a nice blogpost musing about it[0]. Nim is not that.

Of course, neither is Carbon yet, and we'll have to wait and see if it reaches that point or if it ends up on killedbygoogle.com. I'm rooting for Carbon though, it's a cool idea.

Anyway, that is a different ambition than looking for a successor language that lets you use existing C++ code without requiring that the latter is changed, which is what Nim is suggested to be good at here.

[0] https://herecomesthemoon.net/2025/02/carbon-is-not-a-languag...

  • zozbot234 2 hours ago

    I'm a bit skeptical about the "fantastic interop" with C++ also. If it was that easy, the Rust folks would have done that already; whereas it seems that they're still looking into it. And Rust is being developed for LLVM, a compiler that's also shared with C++.

    • cb321 2 hours ago

      With `nim cpp` the Nim compiler actually just generates C++ from the Nim source for the backend to compile. So, calling C++ code is just emitting the calls at a C++ source level and so is straightforward. The situation with Rust "sharing" LLVM is very different, as that is not a source-to-source compiler.

      C++ code calling Nim code is also not usually as straightforward. So, "fantastic" here may apply only in one call direction.

barchar 3 hours ago

The coolest thing about nim is that it's macros participate in the type system and overload resolution and can work with both type checked and non type checked code

  • cb321 2 hours ago

    The "dual" of this type-dispatch of template/macros is that the scoping rules also allow you to use a template or a macro to define a bunch of things which are only "in effect" in a sub-scope, like, e.g. that old C hazard of pointer arithmetic - "defined but contained": https://forum.nim-lang.org/t/1188#7366

    In a lot of little ways, Nim is a lot like a statically typed Lisp with a vaguely Python-ish surface syntax, although this really doesn't give enough credit to all the choice one has writing Nim code.

netbioserror an hour ago

I'm the developer of an in-production sensor analysis backend program written in Nim. Our server scripts invoke it on individual or batches of records, so it doesn't continuously run, and we get free parallelism via the shell. I make copious use of Datamancer dataframes. The program is entirely processing logic. I have maybe 3 lines of memory semantic code in 40k lines. I rely on Nim's default behavior, wherein dynamic types such as collections are stack-managed hidden unique pointers treated as value types.

The performance is impressive. I've done some exercises on the side to compare Nim's performance to C++ building large collections along with sequential and random access, and -d:release from Nim puts out results that are neck-and-neck with -O3 for C++. No special memory tricks or anything, just writing very Pythonic, clear code.

Feel free to ask me anything.

  • creata 7 minutes ago

    > The performance is impressive. I've done some exercises on the side to compare Nim's performance to C++ building large collections...

    1. Can we see the code?

    2. What sort of data structures did you test?

    3. What memory management strategies did you use in C++? (It sounds like you used the default reference counting in Nim.)

  • thomasmg 22 minutes ago

    Which compile options do you recommend for best performance, but such that it is still memory-save? (I assume you use memory-save, right?) Currently I use "nim c --opt:speed". Compared to other languages (Go, Rust mostly) the runtime performance (for my use cases) is a bit slower, for some of the cases. Hm, it might be that you disable memory safety, if you compare against C++...

    • netbioserror 17 minutes ago

      I just use -d:release, along with a bunch of other options related to static compilation with musl-libc. I've tried -d:danger before and the reliability of my calculations went completely out the window. I think Datamancer and Arraymancer are dependent upon some of those checks and guarantees. The --opt flag didn't make enough of a difference in my case.

  • bckr 33 minutes ago

    What’s the environment management story like?

    • netbioserror 14 minutes ago

      I try to keep it simple, using Make to build, and so have ran into issues with Nimble. The upcoming Atlas is supposed to fix these issues, but I don't know enough about it yet. But I remember running into conflicting name resolution with Nimble when multiple versions of a package were installed; I believe it was trying to choose betweeen a Nim 1.x package version and a Nim 2.x, which are kept in separate Nimble folders (pkgs and pkgs2).

      I'm probably going to sit down and give Atlas a try soon, and migrate my dependencies.

dundercoder an hour ago

I’ve loved working in nim. I’ve only written some toy projects so far but it’s fast. Anyone find a good ide/language plugin for it?

  • bckr 34 minutes ago

    Does it have an official language server?

benterix 3 hours ago

> WASM is not supported in the standard library.

Would using the C output and using emcc on it solve this problem?

  • cb321 2 hours ago

    Yeppers - https://github.com/treeform/nim_emscripten_tutorial

    FWIW, people have been doing that for about as long as there's even been an emscripten, but the article is pointing out the lack of more tight integration with stdlib/std compilation toolchains. I would say evolving/growing the stdib in general is a pain point. Both the language and compiler are more flexible than most, though. So, this matters less in Nim that it might otherwise.

ledauphin an hour ago

as an aside on Nimony aka Nim 3:

can somebody provide a reference explaining/demonstrating the ergonomics of ORC/ARC and in particular .cyclic? This is with a view toward imagining how developers who have never written anything in a non-garbage-collected language would adapt to Nimony.