Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Nim 1.6 (nim-lang.org)
300 points by WithinReason on Oct 19, 2021 | hide | past | favorite | 178 comments


I learned Nim last year by rewriting some of the core Arduino functionality in C, and then wrapping them in Nim. (I also wanted to better learn C and better understand how Arduino's internals work, thus the convoluted approach)

A few observations:

* The community was very helpful and responsive. I identified a bug in compiling Nim to bare metal C, and it was fixed in 24 hours.

* The C/Nim bindings were a breeze to use, even for a relatively novice C programmer like myself.

* The language is fairly sparse, in a good way. It feels a bit like Go in that regard, but with better metaprogramming support.

* I personally like meaningful, Python-style whitespace, but I could see how that could be a turnoff. But I'd hope people can look beyond that and give the language a try.

* I could _actually_ use Nim to write code for an Arduino Uno, so the project was a success. The firmware sizes weren't that bad, either, which was my biggest concern. Nim's memory management is very flexible, and the ARC system seemed to work great without the need for GC. [1]

[1] https://nim-lang.org/blog/2020/10/15/introduction-to-arc-orc...


I have decided that meaningful whitespace is an anachronism.

20 years ago, I liked it a lot.

Today, after the invention and normalization of opinionated autoformatters, it means that the autoformatter can't figure out for me how my code should be indented. Which means that, assuming I am using an autoformatter, it creates one more thing that I have to do manually, because the editor can't accurately do it for me. And, since the whitespace is significant, it ends up being one more potential source of bugs.

I also don't love love love that (at least with the keys I know well) significant whitespace is more awkward to edit with vanilla vim than curly braces and parens are.


Some counterpoints:

Your auto formatter can’t figure out where you missed braces either.

Missing brackets in languages where they are optional for single statements (C) has been a source of serious bugs.

Also, in Vim, indenting/dedenting a block is just highlighting the lines and using > or <.


> Missing brackets in languages where they are optional for single statements (C) has been a source of serious bugs.

This is why, in languages where they are optional, a good autoformatter will automatically insert them. If you've got it set to run every time you save the file or run tests, it's likely to do so long before you have a chance to produce the next Heartbleed.

It's not perfect, of course, but it's as good a protection against this sort of thing as I've ever seen.

> Also, in Vim, indenting/dedenting a block is just highlighting the lines and using > or <.

But, excluding plugins (which aren't available/consistent across all the editors where I use a vim editing mode), I don't know of a quick vim command that lets me quickly select, delete, replace, yank, or change the full contents of a scope in a whitespace-sensitive language. Or quickly jump to the beginning or end of the current scope. Stuff like that. Versus, with curly brace languages, vanilla vim gives me an experience that approaches the ease of paredit.


> I don't know of a quick vim command that lets me quickly select, delete, replace, yank, or change the full contents of a scope in a whitespace-sensitive language.

I'm sure there are better ways, but you could v9G$ to select from the current line to the end of line nine. Or v9j select the next nine lines, v9k previous nine, etc.


But compare the ergonomics of:

  1. yi{
To:

  1. Find line number of start of scope.
  2. Decide on easiest way to get there, and either:
     - kk
     - 5k
     - 37G
  3. Find the end of the scope. 
  4. Decide how to grab it. Then:
     - y9G$
     - y3j
     - V, jjj, y

I hope maybe I've made my case that it's more awkward, right? That is not to say that I don't know how to do it. It's just that, in the one case, I can do the job in one thoughtless action that lives so deeply in my muscle memory that I barely even consciously remember what the actual keystrokes involved are. By contrast, in the other, it takes several steps, some of which are likely to be small pauses to decide how to do the next step.


You're both just making the case that you shouldn't use vim to write code.

More modern editors (e.g. VS Code) and modern IDE's (e.g. IDEA, CLion, Visual Studio) make either indenting absolutely trivial.


I think you may have misunderstood?

My main editor is IDEA, followed by vscode and emacs. But all three are set to vim mode. Vim itself has actually never been my primary editor; I generally only use it when I'm sshed into servers.

The thing that vim mode gets me is twofold: It (mostly) unifies the editing interface among all of those editors, and it allows me to edit code more quickly.

The thing I was talking about above is not indenting - my autoformatter does that for me. The thing I was talking about is (a sort of hacky version of) syntactically aware editing that allows me to quickly do large-scale operations without having to explicitly fiddle with the cursor.


I think that by installing vim on all your editors, you are missing out on a lot of productivity.

You are basically giving precedence to text edition over code edition. When you use an IDE, you are editing code, not text, and that IDE's key bindings are optimized for that purpose.

I suggest you take the time to learn native key bindings to whatever tool you picked and see where that gets you, you'll be surprised after a few weeks.


You took the words right out of my mouth. I'm in the exact same boat. I use more than one editor but I always install the vim plugin. It provides an instant speed boost to using that editor efficiently and quickly. We don't switch editors _that_ often, but at the same time, remember trying to remember keyboard shortcuts for TextMate, then Sublime Text, the VSCode, then IDEA, etc.? With the vim plugins, editing text is now the same across all editors.


I'd you're using Neovim, you can also make use of Tree-Sitter to navigate across the parsed syntax tree. There are many plugins to do that, e.g.

https://github.com/nvim-treesitter/nvim-treesitter-textobjec...

or

https://github.com/David-Kunz/treesitter-unit

(The latter is created by me)


Or you could use Neovim with Treesitter for selections that use the language grammars.

https://github.com/nvim-treesitter/nvim-treesitter#increment...


Unless you are a beginner, the "decide on easiest way to get there" shouldn't exist. It should be muscle memory.


> Your auto formatter can’t figure out where you missed braces either.

Correct, but I will notice the braces are wrong when the auto-formatter indents things differently than I expect.


And I'll notice the indentation is wrong when the indentation is different than I expect.


>Your auto formatter can’t figure out where you missed braces either.

I mean, it kinda does? You get a result that's wrongly indented if you miss a brace.


well yeah, then what? where would the missing brace be? you can't really tell since now the formatter clobbered your indentation, unless you remember, of course


When this happens to me with `cargo fmt` I don’t need to remember, I can just revert the formatting changes using undo in Emacs.


Practically speaking, it’s almost impossible to miss braces. If you’re copying and pasting, you can place your cursor anywhere inside the desired pair of braces, paste, and the autoformatter will figure it out.

Ideally an autoformatter would also add braces around a one-line if statement as well.


it is very possible... I often paste parts of some code into a lambda and missing a brace here and there.


A botched merge conflict resolution can repeat a block statement just fine, it will have the same effect. And repeating a statement inside a block isn't necessarily better.


How does significant whitespace save you from bugs?

    if expr:
        doA()
        doB()
Is doB at the correct level?

Having text that's invisible change the flow of your program is crazy IMO.


The bugs being referred to are from optional brackets in C:

    void foo() {
        ...
        if (expr)
            doA();
            doB();
        ...
    }
which is unambiguous to the compiler, but could (and I expect would, especially when glancing through a lot of code) cause misinterpretation by a human reader. We can more easily hallucinate the brackets than the indentation.

I disagree with the idea that indentation spaces are invisible; rather they are much more visible than a pair of brackets. This actually becomes a problem when you embed/indent too much and 70% of the line is spaces. It's all you see!


Yes, but pretty much every coding standard I've seen mandates the use of braces always. You do it without even thinking. Your example wouldn't pass code review.


I don't care that much in my own side projects but when working with others and resolving merge conflicts your example is my nightmare. It's so much easier to have brackets denote scope as you don't have to get the indentation right when actually resolving merge conflicts. It's easy to fix it up afterwards by automatic indentation in the editor.

Significant white space is a mistake IMHO :-)


    if (expr) {
        doA()
        doB()
    }
Is doB at the correct level? It's the same thing.


> Today, after the invention and normalization of opinionated autoformatters, it means that the autoformatter can't figure out for me how my code should be indented

This is precisely why I prefer significant space: it forces you to write tidy code. Sloppily written code that depends on the autoformatter to be properly indented makes me suspect the logic could be sloppily written too.

Besides, any humble plain text editor understands autoindenting, so there's no sensible reason to not indent properly.


Definitely some subjectivity to this question, but I'm the opposite: to me the curly braces are the anachronism, a relic of a time when the programmer had to do lots of extra stuff to help the language parser/compiler.

For awhile it was awkward because it was up to the programmer to keep the redundant block delimiters in sync - the braces (for the computer) and the whitespace (for the human). The fact that modern editors and IDEs for those languages now do the housekeeping on behalf of the human is great, but it seems odd that it's needed at all, and it always feels especially cumbersome when returning to those languages that still require it if I've been away for awhile.


I don't personally run into either of these issues at all working with Elm code (significant whitespace language) in vim.

Having your indentation wrong is basically the same as ending your parens in the wrong place isn't it? Not sure an autoformatter can fix it if you throw a close bracket in before you should?

For formatting, elm-format is opinionated (I don't love the 4 space indentation though) and pretty much everyone uses it. No issues with indentation that I can recall. Not sure if nim has it's own formatter (I haven't played w/ nim in a few years), but I believe python does?

The biggest win of significant whitespace to me is readability. Subjective of course, but I just find it easier to read and less noisy than C / JS syntax. Probably about the same effort to write. I also like bracket soup lisp languages though (w/ rainbow parens) so maybe I'm just weird. /shrug


If I don't add a brace, I'll get an immediate error that something doesn't add up.

If I mess up indentation, the program will carry on as if nothing had happened.


This is not really true in practice. It is the same thing as accidentally moving a line across a brace in a brace-delimited language.

The incorrectly-indented line will generally blow up at runtime or fail to compile, because it's in the wrong scope.


If you misplace a brace (which is the true equivalent of messing up indentation), the program will also carry on.


I get what you say, and agree with you that autoformatter+braces are a cool thing. Problem with that is a lot of people don't use any formatter: not an autoformatter, not a format guide. They just "know" what is best, which usually end up in horrifying (R in my field) code. Sometimes they even feel _smart_ when chaining call after call after call to pull off some kind of one-liner with the help of braces, pipes and semicolons, and then twit the monstrosity with great pride.

Python, and others, had the wisdom to put a corset on those people with whitespace and indentation.


Oh it definitely can run on those devices! I wrote my own keyboard firmware from scratch in Nim, and the firmware sizes are vanishingly small compared to even simple "hello world" level stuff in Arduino. I did a talk on it for NimConf2021: https://www.youtube.com/watch?v=dcHEhO4J29U


This is great!

I've wondered if Nim could be the foundation for a sort of "next-generation" Arduino. It's easy to learn, compiles to small binaries, and can wrap a ton of existing C code.

My experiments taught me wrapping Arduino from scratch, while possible, might not be ideal. There's some cruft in that code base, and the abstractions could use some updating.


Yes, yes Nim could be. Actually I’ve been working on that idea for a while now. I’ve been working on getting an Embedded Nim project going on GitHub. Come stop by! Also some discussions on Nim forum: https://forum.nim-lang.org/t/7731#49050

PS I’m wrapping Zephyr as a basis, but working on better Nim abstractions on top.


There is definitely room for this, it just needs somebody passionate enough to write a nice Arduino/embedded framework and document/promote it well.


I wrote my first Nim app recently (an agent for reporting server data) and I must say, I like the language. It was a quick and painless learning experience. As of now my binary is about 400KB and uses about 1.3MB in memory consumption.

Indeed – as others have reported – Nim feels very much like Python, while the superfast compilation time means I can test code changes quickly during the development cycle.

For reference, I mostly write web apps in Elixir, but I needed another language in my toolbox that is statically compiled and lightweight.

I looked at Rust, Nim and Crystal. I ended up choosing Nim, because Rust is too complex for my taste, and Crystal’s syntax resembles Elixir (they both drew inspiration from Ruby) and it would be confusing when switching between the two languages.

Ultimately, they’re all cool, modern languages, so pick whatever fits your brain and helps you reach your objectives easier, while engaging in this social (or solitary) activity called programming.


> Ultimately, they’re all cool, modern languages, so pick whatever fits your brain and helps you reach your objectives easier, while engaging in this social (or solitary) activity called programming.

Extremely, extremely true!


Have you tried Nimler? It’s pretty nice! I haven’t used it for a year or so.


Well, I wanted to try Nimler (as an alternative to Rustler) but I couldn’t get it to compile on my Mac. Something about some missing symbols if I remember correctly.

I’ll have to investigate deeper when I have the time, as it seems quite appealing to be able to rewrite the slower Elixir parts in Nim.


Odd, but hopefully fixed. The ability to add "noexceptions" annotation to ensure you handle any possible exceptions and avoid killing beam is awesome.


> 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".


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.


> 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


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).


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...


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


Actually, the bare minimum is a well supported and centralised numeric library providing arrays, matrix and the base tools


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.


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


> don't want to recompute it each time you change something

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


Wow, what a great invention I have been missing! You made my day! :-)


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.


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.


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 :)


Also one of Ethereum's proof-of-stake clients is written in Nim: https://nimbus.team/docs/index.html



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!


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).


Thanks for the links, I’ll check those out.


When using Nim for "scripting" it is recommended to use TCC for rapid compilation. It is genuinely fast.


* Backend: For something Jinja/Twig-like: https://github.com/enthus1ast/nimja


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...


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.


> 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.



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.


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.


Nice! That definitely sounds enticing.


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


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.


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.


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).


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.


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.


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/...


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/


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.


If you ignore the whitespace sensitivity, Nim's syntax is actually more similar to Pascal than to Python.


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.


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...


> 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.


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.


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.


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.


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.


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.


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


> 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


I heard PL/I was the original language for “everything”. It’s not a new concept :)


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.


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?


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.


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.


Can you show me how to write a frontend web app with C? Or how to make a keyboard driver with Python?


Nim has been such a fun language to use. I make a money-earning desktop application (Electron for the GUI and Nim for the core logic) and companion web service (fully Nim). It has been a pleasure using Nim to make these and other things.

Congrats, Nim team!


I would love to see this, what's the product?



The full changelog is here: https://github.com/nim-lang/Nim/blob/version-1-6/changelogs/...

For those who wonder what the 15 extra modules are, here's a quick summary:

Algorithms:

  - enumutils: generate case statements from enums, and utils for holey enums.
  - setutils: adds functionality for the built in `set` type.
  - packedsets: replacement for `intsets` that allows distinct types.
Operating system:

  - tasks: basic primitives for creating parallel programs.
  - sysrand: create cryptographically secure random numbers.
  - tempfiles: create temporary files and directories.
  - vmutils: enable/disable VM tracing in user code.
Javascript:

  - jsbigints: arbitrary precision integers.
  - jsfetch: wrapper for the JS Fetch API.
  - jsformdata: FormData wrapper for the JS target.
  - jsheaders: Headers wrapper for the JS target.
Metaprogramming:

  - genasts: alternative to `quote` for metaprogramming with explicit binding.
Misc:

  - socketstreams: wraps sockets as streams.
  - importutils: allows access to private fields from another module.
  - strbasics: high performance string operations.
You can check out the modules themselves at the stdlib page: https://nim-lang.org/docs/lib.html

There's also loads of quality of life improvements across the board to existing standard library modules and general backend, e.g.:

  - float to string is 10x faster,
  - JSON serialisation is 20x faster,
  - better compiler messages,
  - memory management performance (e.g., ORC is 10% faster)
  - `static[T]` improvements,
  - improve `enum` type conversions and allow `enum` overloading,
  - new design `concepts` that compile faster,
  - build system and cross compilation improvements,
  - unicode operator symbols,
  - VM improvements such as working with `addr` at compile time.


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

Whoa, this really surprised me!


Doesn't that depend on the size of the compiler? Nim can surely be faster than all of them, but that particular figure can't mean anything.


The Nim compiler is pretty big.


So what? You are not comparing the same thing.


Of course not. But what else would you want to compare?


Lines of code per second for compiling the compiler. Or a standardized set of programs like language benchmark game. Not to say that they are not susceptible to problems, but they have much more information than the compiler compilation speed.


To all those wondering about IDE support , the actively maintained VSCode extension is :

https://github.com/saem/vscode-nim

The default extension suggested by VSCode which have over 43k downloads in un-maintained for Eons and it won't work.

Here is the link : https://marketplace.visualstudio.com/items?itemName=nimsaem....

This extension works properly , go-to definations too.

Nim need contributors on VSCode and other extensions part , and the language server which is in active development :

https://github.com/PMunch/nimlsp

@dom96 can you pin this somewhere on the forum or website ?


How to run those benchmarks?

At that Nim release page:

https://nim-lang.org/blog/2021/10/19/version-160-released.ht...

Is link to this benchmark:

https://web-frameworks-benchmark.netlify.app/result

Where nim is 2nd with 200k req/s, but it is using httpbeast:

https://github.com/dom96/httpbeast

That says it would be more useful to use jester:

https://github.com/dom96/jester

Jester has 150k req/s.

But, when looking at these:

https://www.techempower.com/benchmarks/

drogon, actix etc has about 600k req/s .

Also redbean has about 600k req/s, when I tested:

https://redbean.dev/

I tested like this:

git clone https://github.com/wg/wrk.git

cd wrk

make

./wrk -H 'Accept-Encoding: gzip' -t 12 -c 120 http://127.0.0.1:8080/

When I tested https://caddyserver.com v2, it did show about 800k req/s.

It would be very helpful to know how those benchmarks are actually done, so that I could compare what is actually fastest in real world, and not just use some for benchmark tested winning non-realistic code.


You definitely cannot compare a benchmark result you got on your machine vs. one in (what I believe is) a CI environment.


The source code for the benchmarks is here: https://github.com/the-benchmarker/web-frameworks And the httpbeast code is here: https://github.com/the-benchmarker/web-frameworks/tree/maste... TechEmpower and TheBenchmarker are 2 different benchmarks and I'm not sure how they compare.

Besides that benchmarks rarely benchmark realistic code and the Nim blog doesn't mention being the fastest out there, but it mentions "native performance" which I feel like is a fair claim.


>Nim made its first entry in TIOBE index in 2017 at position 129, last year it entered the top-100, and for 2 months the top-50 (link). We hope this release will reinforce this trend, building on Nim’s core strengths:

I wonder if it has chances to ever enter top 20.


It does, with the right libraries. I started a product last year in Go. If I had done so this year, it would have been with Nim. It's a really interesting language.


why use tiobe when it is so clearly a bad metric? Pypl or the ieee index are much more reliable.


well, because Nim is neither in Pypl [1] nor in ieee index [2] yet... :)

[1]: https://pypl.github.io/PYPL.html

[2]: https://spectrum.ieee.org/top-programming-languages/


Not sure why you say these are much better when all these surveys pretty much give you the same result, if you look at these rankings in terms of brackets.

Basically, they pretty much all agree which languages are the top 3, top 5, top 10, etc...


Tiobe ranks based on search results rather than visits, so languages can be ranked highly due to old computer generated docs that no one has ever read. Furthermore, tiobe only searches "x programming" which biases towards some languages and against others (Go and Julia come to mind as ones that are refereed to as Golang and Julialang frequently). Also, although the general results TIOBE gives look roughly accurate there are some entries that are wrong enough that you should question the validity of the ranking as a whole. For example, TIOBE ranks "Classic Visual Basic" as the 11th most popular language and claims that it has climbed 8 ranks in 2020. Given that the language hasn't been supported since 2008, and I have never heard of anyone using it for anything, that is rather surprising. Similarly, Tiobe appears to believe that Visual Basic is more popular than Javascipt which is frankly not credible (for refferrence, PYPL and IEEE place it at a much more believable 18th and 22nd).


I don’t know much about Nim, does it have a mandatory gc, like go? How good is Nim’s gc?

Those who have written some Go and Nim, home does the code look like vs go?


Nim is the most readable language I've ever seen. I've dabbled with Go, but Nim is almost like pseudocodes+types. Highly recommend you take a look and try it out! You can use libraries like https://github.com/planety/prologue or https://github.com/treeform/pixie to create something quickly and fun(compile times are faaasst!).

And Nim does not have a mandatory GC, you can go as low-level as you want, but in case you don't want that you can choose from several great GC's(a capable soft real-time GC and Boehm for example). Or you could combine the best of both worlds and take a look at the shiny fancy ARC/ORC deterministic memory management: https://nim-lang.org/blog/2020/10/15/introduction-to-arc-orc...


Looks like you know a bit of Nim. Apart from ecosystem and IDE what are the some of the disadvantages of Nim compared to Go?


* Goroutines are probably a lot more easier to use. Work is being done to make Nim even better in that area: https://github.com/nim-works/cps but don't expect it soonish.

* I feel like Go has less 'edge cases', but the Nim compiler is steadily getting more stable, especially consider it's not backed up by a major company!

* Metaprogramming is really powerful, but not beginner friendly. The documentation says use macros when necessary, but personally I don't think that really happens in practice.

The advantages by far outweigh the disadvantages, especially if you are looking for a clean Go alternative(except maaaaaaybeee web application).

EDIT: my own wishlist, but they aren't relevant compared to Go:

* Better sum types * Builtin pattern matching


I have not done a lot of Go, but I'm pretty sure Nim's concurrency story isn't up there with go, at least not yet.

Nim has other advantages, including great Interop with C or C++ as it compiles to these languages and allows low level, unsafe features like raw pointers when needed.


I have written a bit of both, recently re-wrote a command runner for a side-project https://gitlab.com/jarv/cmdchallenge in Nim and found it very pleasant and much less verbose, which was a nice change from GoLang while keeping type safety. A good example is parsing JSON https://nim-by-example.github.io/json/ as you can do a lot with fewer lines of code. I think the main disadvantage of Nim is that there is less out there in the ecosystem, libraries, and it's more likely you will run into quirks and bugs in the standard library.


I really like the look of Nim but every time I dig into it I find a really strange syntax decision. For example:

> The json module provides the %* operator which is used to create JSON objects

I'm curious what the benefits are here of an operator over some more readable syntax. I have a dislike of languages where ascii noise seems to be favoured over readable english tokens.


This is interesting, especially for a language like Nim that favours familiarity with Python.

Even Rust dropped most of its strange operators/sigils early on in the experimentation phase, because they confused people and Rust doesn't step back from confusing people lightly, haha.


Probably because Rust already has too many ascii symbols! ;) I still get brain mush remapping Rust's & from C's &.

But yah Nim's % is a bit strange at first, but becomes fairly handy in practice when dealing with lots a small bits of JSON. There's the % "to json" operator that mimics the $ "to string" operator for a single value. Then %* was added to handle multiple json items (I read it like apply % to all items). So it has a decent symmetry. Other than % and $ ascii operators are pretty rare in Nim code. Even bitops use or, and, shl, shr, etc over ascii operators.


This way you can write json literals in the code, and it will look just like regular json. For serialization and deserialization stdlib uses `to/load/store` proc names.

  import std/json

  echo %*{
    "key1": "value",
    "key2": 12,
  }


Could have just used a "JSON" keyword instead. Symbolic names are needlessly obscure and unfriendly. Hard to infer meaning, hard to pronounce, hard to search online, etc.


As if "json" is any more searchable. Operators have a meaning that you learn quickly when learning the language. You wouldn't do math with "multiply" instead of "*", so why would you want that in a programming language?


Multiply already has a symbol, and JSON already has a name. Making up a symbol %* to mean JSON is like making up a name Flurb to mean *. Sticking with what already exists seems much simpler.


Because with a keyword the meaning is much more explicit, and I consider that to be more valuable. And I think "*" is a bad example because pretty much everyone who programs already knows it's multiplication.


It might not be the best example, but the point stands. Succinct notation is important. "JSON" instead of "%*" might not be the greatest of examples but still.


Because there's no point in saving three characters (although I'd rather have it be "literal_json" or "inline_json") just to have people memorize what yet another symbol means in a highly specialized context when you could just read the word and be perfectly certain what the code means without looking it up the first time.

Even after the first time symbols have a non-trivial cognitive cost for a lot of people, if not most, all while providing near zero benefit unless your app is pretty much nothing but a bunch of inline json expansions.


Of course it is. It's descriptive and searchable.

Because * / - + is the common ground that essentially everyone is familiar with. And that's about as much math notation as makes sense in general purpose programming languages.

There is only one math but many programming languages. Multiplication is universal and fundamental. Creating JSON objects in nim is the opposite of that.


> Of course it is. It's descriptive and searchable.

If I entered "nim json" into google I'd get thousands of results for the language and json in general, and no way to narrow it down to meaning the operator "JON". That's not really what searchable means.


> no way to narrow it down to meaning the operator

My google insider tells me you can add the word "operator" to your query to do that. Or any other similar word like "keyword" that anyone else thought to call it on stack overflow.


Checkout the newer std/jsonutils: https://nim-lang.github.io/Nim/jsonutils.html

let a = (1.5'f32, (b: "b2", a: "a2"), 'x', @[Foo(t: true, z1: -3), nil])

let j = a.toJson

assert j.jsonTo(typeof(a)).toJson == j


Yeah, I tend to agree with you here especially after a take a break from writing Nim I need to re-learn a lot because it is impossible to hold it in my head for very long.


That's really good point. Also, I don't think it's the only weird operator they introduce in the stdlib without any good reason.


The json module is old and probably wouldn't be designed this way today.


That %* is really strange. Also in the example there is no notion of errors? Nim is exception based?


yes, invalid JSON would raise an exception.


As a python dev, nim was much easier to get into than Go, Rust, or even Zig.

If you squint, it looks like a toddler Python with strong typing, compilation and a few different API, espacially for managing finalisation.


I may be splitting hairs here but Python is actually a strongly typed language. It would be better to say nim has static typing: https://wiki.python.org/moin/Why%20is%20Python%20a%20dynamic...


Check out this Nim talk. Addresses some of your questions.

https://www.youtube.com/watch?v=d2VRuZo2pdA


Thanks I’ll check it out.


Once you're done with that one you can go on with more advanced subjects here: https://www.youtube.com/watch?v=cISmv0IGoQQ

From around 1:00 pointers are being discussed.


Cute but disappointing.


Nim has multiple memory management strategies and you can pick any. A few types of garbage collectors, reference counting and manual memory management.[1]

Nim is less verbose than Go and more expressive.

[1] https://nim-lang.org/docs/gc.html


Nim can be mark/sweep collected but also has a collector called ORC that's reference counting plus a version of the Recyler algorithm for cycle collection.

ORC turns out to be rather nice to use: https://nim-lang.org/blog/2020/12/08/introducing-orc.html


What's the state on:

- web frameworks / servers ? (ie. is there something like Sanic that is actively maintained ?) I imagine it's too early for a consensus.

- database drivers ? (postgresql is important here. I can live without an ORM)


There is plenty of web frameworks and servers, each with differing maintenance levels. You can for example check out Jester[1] and HttpBeast[2] (shameless plug, I wrote these :)).

1 - https://github.com/dom96/jester

1 - https://github.com/dom96/httpbeast


Thanks !

I see jesper's Request has its body as a string. How would you manage (very) large request body ?


In the ORM field, Norm[1] is an actively maintained package that supports SQLite and Postgres (shameless plug). It's framework agnostic, I've used it with Jester and Prologue (it had nothing to do with Prolog btw).

Among frameworks, Prologue is the most actively developed and feature rich.

[1] https://norm.nim.town


Why use an ORM when you can just not turn everything into objects?


Maybe a year and a half ago I put myself towards learning Nim. My learning project was a basic REST API backend written using the standard library.

I found the lack of IDE support very painful. On top of that, I ran into places where the documentation was out of date or just incorrect. After a few weeks of painful, slow going, I turned my attention to GO instead and haven't looked back.


i think that is over 2-3 years ago , Since nim 1.x documentation is fine , and vscode plugins are out. It your time to look back now , a lot more stable and complete.


Cool, I'll give it another shot.


I see 2 targets that Nim could attack well with a bit of focus - Python and Swift.

Both have their strengths, but you always pick off people at the edges. Performance would do well against Python, and multi-platform against Swift.

This will be an interesting space to watch. If a beautifulsoup equivalent existed, I would put some serious time into it and reduce my Python time (but that’s just my need).


Instead of beautifulsoup you're honestly better off just running an instance of Firefox/Chrome and scraping data that way. You can do fairly easily these days and I have a library that allows you to do so in Nim: https://github.com/dom96/webdriver


I use it to parse crappy (non-standard) RSS feeds offline for an internal app I use. chrome-scraping would just be more of a pain (although I've done it before).


Have you tried htmlparser? Its fairly tolerant of "wild" html. It could use some tweaks to match the html5 spec that defines a lot more tags that don't require end tags. Also the library isnt to bad to grok and tweak yourself.

There's also Nimquery that looks nice, though I haven't used it yet. Still looks to replace a lot of beautifulsoup.


No, but I use feedparser in the same script.

Basically I'm scraping SEC data, but the script has been around for awhile untouched, so there are probably better solutions today.


One thing I think would be interesting - get listed on Computer Benchmarks Game.


It would be interesting, yes, but the maintainers of that have explicitly refused to add Nim (and other "new" languages).


Think of it as an opportunity for you to publish the measurements you make!

https://benchmarksgame-team.pages.debian.net/benchmarksgame/...


Ah - I wasn't aware of that. That sucks.



For anyone put off by nim's copious use of camelCase and PascalCase, I recently learned that nim treats identifiers as the same if after removing all underscores the identifiers compare equal case-insensitively (except for the first character which is case sensitive). This means you can completely ignore NEP 1 (just like you can ignore PEP 8) and write your code with snake_case identifiers and Upper_snake_case types including any calls to external code.

This means that for people like me who find camelCase horribly ugly and refuse to casually use any language which uses it in its standard libraries or syntax (I'm looking at you haskell and zig) you can write code in a more aesthetically pleasing way while everyone else around you can continue using the horrific camelCase names (even when referring to your snake_case code).

Also, I highly recommend switching to at least 3 space indents so that unlike regex your code stops being write-only.


I started looking at Nim a few months ago, but I didn't like the feature where it ignores underscores and capitalization. It seems to me that this would make grepping harder on larger projects.

I suppose a linter or style-guidelines-and-not-making-mistakes invalidate this issue. For anyone that has used Nim, has this been a problem in practice?


Within a specific project, you pick an approach and stick to it, just like you should do for any given convention within a project.

The idea is to make it easier for projects using different conventions to be built on top of each other without making things harder to read - and in practice it actually works really well at that.

On the upside, people freaking out over the style insensitivity makes for a nice change from people freaking out over nim caring about whitespace, so at least we get some variety in our aesthetic worrying from people who've not had time to try the language yet :D


Ha, I wouldn't have thought to criticize the spacing, but I did see one person complain as I explored old Nim discussions. Nim being strict on tabs is something I see as a good feature for the same reason the style flexibility made me instinctively flinch back. I've experienced mixed tabs and spaces in Python code and I do not like it; the flexibility leads to inconsistency.


Tabs vs. spaces hides though.

Inconsistent naming is visible in diffs in any language, style flexibility or not :)


No, never. Actually the most problem I've ever had with this feature is seemingly unending discussions that come up in almost every single HN discussion ever, like https://news.ycombinator.com/item?id=28651040

> would make grepping harder on larger projects

There is a built-in tool `nimgrep`, but honestly I never even need for that - `rg` worked perfectly fine each time I had to do something like that.


I've been using Nim for hobby programming for a few years now. I'm maintaining the Norm package, it's an ORM for SQLite and Postgres. Not a huge project but not a hello world either.

Style insensitivity has never caused a single problem for me. Honestly, this is the most unimportant language feature, I don't get why it causes such fuss every time Nim is mentioned.


It has never caused a problem for me. I didn't even know it was a "feature" until I'd used Nim for a year. In theory it seems like a terrible idea. In practice, it has never caused any problems.


Nim needs that one killer framework and it's off to the races. A Rails or a Phoenix, batteries/ORM included for Nim. Imagine running a very scalable, productive project on peanuts hardware with very fast performance. Killer.


Are there any capable IDEs for Nim?

I'm thinking something along the lines of what GoLand is for Go, or Rider is for C# - a fully-featured IntelliJ kind of IDE.

I'd be much more inclined to kick Nim's tyres if there is a good IDE.


I believe the best experience ATM is with VSCode and the nim plugin. It's not perfect, but th community is aware and there is work underway to improve tooling: https://github.com/nim-lang/RFCs/issues/300




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

Search: