Hacker News new | past | comments | ask | show | jobs | submit login
Choosing Nim out of a crowded market for systems programming languages (nim-lang.org)
272 points by generichuman on Nov 25, 2022 | hide | past | favorite | 260 comments



I have done non-trivial things both in Rust and Nim. For big projects Rust seems a little more robust, but for medium and small projects Nim is an order of magnitude faster to develop for. There are still many rough edges, but it's exactly the tradeoffs I would personally pick for my one person small business making tools for artists. So far I have been using Rust and it's alright, but looking very much into Nim to see if I can replace Rust because of the high cognitive load to keep all of the Rust stuff in my head, as I don't really need safety.

Shout out to https://github.com/StefanSalewski/gintro which was super simple to build a simple GUI tool. With Rust I have no idea what to use after trying 5 different libraries.

The downside of Nim seems to be highly unpredictable performance in my experience. With Rust it's much easier to control. This might be a deal-breaker unless I can find some solution to it. Maybe it's just using it more than two weeks and learning the ropes.


> looking very much into Nim to see if I can replace Rust because of the high cognitive load to keep all of the Rust stuff in my head, as I don't really need safety.

Personally I find that Rust has less cognitive load, because so much of what you'd generally worry about in other languages is covered by language features in Rust: static typing, algebraic data types, etc


I'm sometimes a bit confused when people say that Rust has less cognitive load. I assume that's compared to something like C or C++, right?

I've used Rust and (imperative-style) Scala a lot, and I have to say, Scala is way easier since it doesn't have to deal with the borrow checker, but it still has an amazing type system.

Nim is statically typed and has algebraic data types, so I imagine it's also as easy as Scala, easier than Rust.


I think that it has to be?

I like Rust well enough, but thinking about memory management is a reasonably large effort that I generally don't have to make in most languages. Rust, in not having a GC, strictly adds to that load compared to most languages out there. The exceptions are languages like C, C++, and assembler, and there I agree that Rust seems to make things a fair bit easier.

(Though, disclaimer, I never got around to learning modern C++, which I gather is a huge improvement over the style of C++ I do know.)

I'd be willing to accept, though, that Rust's lack of full-blown OO features, and its strict controls on mutation, often makes things easier in large shared codebases. Perhaps not letting people do some particularly wild things that I'm used to seeing in Java and C# at my day job. I'm not in a position to have a worthwhile opinion on that claim, though.


Imagine if someone said "I've used Python and Scala and Python is way easier since I don't have to deal with a type system". That's where people are coming from.

The borrow checker isn't a hindrance, it's an aid. Rust gives me syntax to describe lifetimes and a tool to check that syntax.


Yes, but if you have immutability and a garbage collector (and can afford to use some extra memory overhead), the borrow checker and lifetimes aren't really all that necessary to bother with.


Well, one thing that makes Rust harder is tooling. I don't seem to get around its code completion, at least in VSCode, and the docs, while mostly good, are hard to understand sometimes

I personally don't like that "structures with methods" way of doing things in Rust/Go but maybe that's just about getting accustomed


I agree but I tool functional programming course in college. It was hard! Someone who may not have invested enough in leaning basics of FP, I can totally see why Rust feels like a hard language. During the prototyping phase, I also avoid lifetimes and other esoteric features and often use unhealthy amount of Arc and Rc.

Nothing beats Cargo and company and loves compiler messages. Have used NIM as python replacement, and while language is great and nim batteries are decent, the ecosystem is not there. But who would use nim as python replacement!?


How would functional programming help with Rust? I am fluent in both, and having map and reduce in the Iterator trait does not make Rust anything like a functional language.


IMO Rust is what you'd get if you took a functional lang designer and forced them at gunpoint to create a procedural systems lang. It's not functional, but you can tell it was largely inspired by ideas from the paradigm -- immutable by default, expression-centric to an extent, features like Option<T> and Result<T> available, etc.

It's certainly a language that encourages programming in a functional flavor, even if the lang itself isn't functional.


The things that make rust “functional” are features like a type system that supports sum and product types and functions as typed values that can be passed around. It really is a functional language (in the original ML sense of the word) but with another orthogonal type system bolted on (borrow checker).

It’s missing some features like higher kinded types but it’s functional nonetheless.

I’m interested to hear what your definition of functional is - it’s always interesting because it’s such a vague term, really.


Jeez downvoters - just look at the definition of “functional language”

https://en.m.wikipedia.org/wiki/Functional_programming

And then tell me Rust is _not_ those things.


I recently tried Nim for the first time, and although is simpler, the model with values vs refs was a little more complicated than needed imo, and the 'easy C interactivity' wasn't as simple as with, let's say, Zig, where you'd simply do `@cImport`.

It's still fun though, and I appreciate the minimal visual noise while writing it.


It looks like gintro is a GTK binding - the Rust equivalent would be gtk-rs. https://www.gtk.org/docs/language-bindings/rust/

I'm curious whether you tried gtk-rs and if so what problems did you have?


> With Rust I have no idea what to use after trying 5 different libraries.

Seems like GTK is the pretty clear frontrunner?

https://www.areweguiyet.com/


While GTK is a gui library, it is not a rust gui library. The GTK you link to is simply rust bindings for the GTK library.

The most popular rust gui library at the time of writing seems to be egui with 489k downloads.


> I feel inferior for not being fluent in OCaml

I learned OCaml recently, on my own, for myself. It’s actually a pretty easily language to use and learn, but historically there weren’t EXCELLENT resources for learning it.

There are now excellent resources, predominantly: https://cs3110.github.io/textbook/cover.html

When OCaml 5 settles, its general applicability will be (imho) much larger.

Do I recommend it for everything? No. But you wont hit segfaults like you will in go, and you certainly wont wrastle the compiler like you will rust. Haskell and OCamls lack of fluent programming make them less easy to program in (read: slower iteration), if you get your design right, your final product is just a real treat :chefs_kiss:. Some newer fp langs do have fluent style syntaxes, which are

The ocaml debugging experience stinks, and the lack of builtin (de)serializers for custom/composite types is very obnoxious, to put it kindly. Still, it’s not the obscure thing everyone loves to say about it. Really, its not.

These jokers in this thread “oh rust isnt hard! Ohhh they probably didnt try much.” Respectfully, get outta here. I love rust. Taken the doubly linked list tutorial? How about needed to use anything with Pin? Rust requires a huge surface area of foundational knowledge to be productive, full stop—the author is absolutely within his right to make this very fair claim about rust being onerous, relative to his candidate pool


OCaml is great. One of my favorite languages. I think the only thing hard about it is the fact that it is solidly FP, and that is not a familiar paradigm to many. One of these days I want to check out F# so I can use the whole .NET set of libs as well (the only bad thing about ocaml is the small ecosystem of libs).

> These jokers in this thread “oh rust isnt hard! Ohhh they probably didnt try much.” Respectfully, get outta here. I love rust. Taken the doubly linked list tutorial? How about needed to use anything with Pin? Rust requires a huge surface area of foundational knowledge to be productive, full stop—the author is absolutely within his right to make this very fair claim about rust being onerous, relative to his candidate pool

Rust is not an easy language, but I find it strange that people take the hardest parts and act like it is most of what it is about (I can count on one hand how many times I've had to directly interact with Pin). The things you mention aren't things I spend any time on, and I write Rust nearly 12 hours a day.

P.S. - Is there actually a double linked list tutorial? What an _awful_ way to learn Rust. That is like starting at the very end of what you should be learning and then working forward. No wonder it scared people away.


The doubly linked list thing strikes me as more of an illustration of cultural differences between C programmers an the rest of the world than as a straightforward criticism of Rust.

I've no doubt that doubly linked lists are an awkward hassle to implement in Rust. But the same is true in functional languages, and you never hear people criticizing, e.g., Haskell over this. I have a couple guesses as to why that is, but I'm guessing the main one is that Rust being touted as a C replacement results in people assuming that Rust should be amenable to the same kind of (for lack of a better way to put it) hyper-imperative approach to problem solving that C basically forces upon people.

But I'm also pretty sure that I've never, in my 30 years of programming, used a doubly linked list in anger in a language that wasn't C. (Maybe Pascal?) I have never used Rust in anger, either, but, based on my little bit of dabbling, it seems like yet another language where I would be likely to choose any number of different data structures first. I certainly wouldn't be implementing my own in any case. These days, implementing doubly linked lists from scratch seems to be very nearly the sole province of C programmers and undergraduates.


It's not just doubly linked lists. They're just a basic example of borrow checking not being able to handle a lot of easy patterns that are perfectly safe in other languages.


The easy pattern of graph structures is handled by the easy implementation of adjacency lists, which is how you should have been implementing it in other languages too. The specific incompatibility is with the naïve hand-implementations of these structures; the specific thing Rust does not optimize for is toy code.


You know nothing of what I'm programming. You don't know when, whether, or how my program accesses or deletes data. You don't know what domain I'm in, whether I'm on a team, or what our priorities must be.

And yet, you proclaim that your approach is how I should always do it in any language, in any situation.

It strikes me as particularly convenient, seeing as that's the only approach that the borrow checker can reason about.

To make it more concrete: if we apply your solution everywhere we run into this problem with the borrow checker, it can flatten a lot of our program's (non-temporary) state into basically relational tables. Sometimes that's okay, but for a lot of situations it can be bad for encapsulation, velocity, and modularity.


No need to take it personal. I don't think the "you" OP used referred to you specifically.


I agree with the sibling commenter that the parent poster was likely using the impersonal you. It is true that we don't know anything about you. You haven't volunteered any specifics, so we're kind of forced to guess if we want to try and respond in a productive manner.

To that end, I think that they chose a very good example. Abstractly, doubly linked lists are a special case of undirected graphs. So pointing out that a naive graph implementation is generally sup-optimal, and that usually one can more effectively model them using different data structures that Rust (and functional languages, and databases, and files, etc.) can handle just fine, neatly addresses problems that one might solve using a doubly linked list, as well as a whole host of other cases, in a single stroke.


Fair, but, if so, could we focus on one of those instead?

I'd be especially interested to see an example that's perfectly safe in C or C++, and for which there's no better way of doing the data modeling in Rust. Using the kinds of data patterns that have long been used to avoid circular references in functional programming languages, for example. Because we want to avoid getting too caught up in examples of things that should be hard in Rust because Rust is designed to favor different ways of doing things.

Or, to put it cutely, I'd want to be cautious about doing the equivalent of criticizing a Toyota for having a terrible glide slope.


Perfectly safe at the expense of a garbage collector. You can still do pointer soup and int handle based lists as you can do in any other low-level language with the same caveats. Rust is punching up from the manual memory management, zero-cost abstraction plane and competing with the garbage collected langs. It's still at it's core a tool for writing low level code.


GP was confused about why the doubly linked list case was so important, so I enlightened, it's an example of an entire class of the borrow checker's problems.

Your response isn't really relevant in that context, and instead escalates to a much larger debate, so best I not engage. Appreciate the thought though =)


These patterns are not "easy" at all - for one thing, they're non-compositional and anti-modular. They're exactly the kind of thing `unsafe {}` was intended for - though it would be nice if Rust came with a way of writing proofs of safety for these things, and this is a field of active research.


It's not _really_ a tutorial. But it's one of the best exploration of any language I've read.

https://cglab.ca/~abeinges/blah/too-many-lists/book/README.h...


Ocaml is a (mostly) good to great language with horrible tooling that completely kills any desire I have to work with it.


I recently started using nim for some little side projects and I am having so much fun. Somehow they’ve managed to combine the strengths of high level languages such as python with those of low level, systems languages like C with few (if any) of the drawbacks. It’s pretty amazing to be honest.

Programming in nim feels a lot like programming in a statically typed Python, except that you get small, fast, single file executables out of the box.

Compared to C++ you don’t need to worry about memory allocations too much except when you really want to, and when you do it is much simpler than in C or C++. It is also much easier to control mutability and the type system is much better. Also you can use most of the language at compile time in a much more elegant way than in modern C++.

Another surprising thing is that while the ecosystem is obviously much smaller than on more popular languages, the fact that it has a built-in package manager gives you access to it much more easily than in C++. There are a lot of high quality packages (such as datamancer, arraymancer and ggplotnim) which makes nim very productive in a lot of domains.

That’s not even including advanced things such as nim’s excellent macro system which I personally don’t use (but which enable some of the best nim libraries).

Oh, and I _love_ nim’s uniform function call syntax. Every other language should copy that feature.

I almost forgot to list the drawbacks. The main one of course is that it is not the most popular language (but the ecosystem is big enough that I didn’t find it is a big problem for my use case in practice). Other than that the editing and debugging experience could be improved. There is a decent VS Code plug-in (look for the one made by “saem”) but it is just OK, not great. There is some integration with gdb but it is a bit rough. I usually end up adding logs when I need to debug something.


The author seems to be very knowledgeable about the different aspects of programming. Whether you agree with his opinions or not, this article I think is a great starting point for learning about many interesting topics. Definitely bookmarked for later.


They sound like someone that is attracted to chasing the high of the next technology to learn rather than picking a language like C/C++ that would have worked and given them way more career stability.

Rather than mastering a bunch of programming languages they should have focused on one and built clout as a problem solver that doesn’t see a new shiny tool as a way to label their career. Boring popular language + focusing on building stuff and solving problems are the key to actual career growth.


That assumes a whole lot about their goals. If everyone sticks with C++ we would never have nice things like Zig/Nim/Rust that are advancing the conversation about how we should be doing systems programming tasks with code. C++ is quite influences by a lot of this. Like, let emm hack and learn. Also I think Nim is a very productive language to be hacking in and much easier to get going with than C++.


As they say, let people enjoy things


That take detracts from the amazing work people have done over the decades to research and implement improvements to C and C++. We can innovate without throwing things away, even if it may seem boring to the uninitiated.


People have done (and are still doing) amazing work in Fortran too. Why should we use C or C++ when Fortran was already perfectly fine?


Fortran us better than C and even C++ for its domain, high-performance numerical code. The guaranteed lack if aliasing allows for optimizations not always possible in C code. Built-in handling of stuff like complex numbers and even range types in modern Fortran (that is, supported for last 25-30 years), along support for parallelization, and with robust structured / procedural programming, is just the right tool for some jobs.

BTW if you run fancy modern stuff like numpy, you run quite some Fortran, because it includes, for instance, BLAS.


None of this is true or very important anymore.

For aliasing, in C, there's the restrict keyword, although it isn't used that often. If you take a look at BLIS or even BLAS, restrict isn't used. C++ doesn't have restrict, but that hasn't stopped the development of great numerical linear algebra libraries like Eigen or Armadillo.

C++ has had std::complex for... forever. And C99 has support for complex numbers.

Range types are handy, but not having them typically isn't a show stopper when designing libraries of numerical kernels. They are more useful for high-level prototyping, a la MATLAB. Nevertheless, it's not that hard to emulate the behavior using a well-designed API in C, or operator overloading in C++.

The only parallelism that Fortran has that C or C++ lack is co-array Fortran. I haven't used it myself, so can't speak to how useful it is. Both C and C++ have many options for parallelism: pthreads, OpenMP, MPI, C++'s parallel stuff, and tons of other libraries.

I'm not sure what "robust structured/procedural programming" is. I think Fortran is at a clear disadvantage compared to C and C++, here. The amount of boilerplate needed to define a function in Fortran is pretty painful. Fortran's control flow is a subset of C and C++'s, so any style of structured or procedural programming you would do in Fortran can obviously be done in C and C++.

And of course, numpy (and similar) call out to Fortran, but they call out to loads of C and C++, too!

This isn't to say Fortran is a bad language. I work with people who use it and prefer it. But the reasons you pointed out simply aren't valid. A good reason to use Fortran: you work in a group where Fortran is the language that's used and you want to be able to contribute to what's going on!


Exactly. They are just arbitrarily drawing the line of which language is sensible based upon what was hot when they made their choice.


It doesn't detract from that at all, chief. What a weird thing to say. Particularly in the case of Nim -- it doesn't "throw away" C or C++, it compiles to them!


...decades of research dedicated to handling problems introduced by C and amplified by C++.

Sometimes it makes sense to simply reset things.


Sure. But we can also innovate with throwing things away, which has its own set of advantages.


I have been learning Rust so it is top of mind for me. Rust started with some really tough constraints:

1.) How can we eliminate undefined behavior?

2.) without sacrificing any performance

From there, they built a powerful programming language that has always honored zero cost abstractions and elimination of undefined behavior. This is like a 15 year development and the result is a little hard to understand at first but one of the most innovative things in the realm of systems programming [that people are actually using at scale]. I know Rust borrows a lot and is built on the shoulders of giants and is not a singular invention, but it is slowly winning hearts and minds in places where languages like Ocaml and Haskell never could. You really could not do something like this by saying "Hey, how could we eliminate UB in C++?" Starting anew was the solution :)


> That take detracts from the amazing work people have done over the decades to research and implement improvements to C and C++.

What kind of argument is that?

> We can innovate without throwing things away, even if it may seem boring to the uninitiated.

You can’t innovate without breaking backwards compatibility. C++ is an evolutionary dead end that collapses under its own complexity, deal with it.


Ugh, as a C++ programmer - for the love of god don't choose the language for career stability. Both the language and the ecosystem is horrible. Choose it if you need it work in the domain of your choosing. For me it happens to be the case. If you want to choose a career language go for any of the other TIOBE usual suspects.

I completely agree that if you want to be a career programmer, focus on solving problems for business. But it can be done in any language nowadays.


What's wrong with C++ stability? You think things are looking better in JS/Python world? They both changed tons and the knowledge you accumulate constantly needs to be tweaked and relearned.


I perhaps used words in a confused combination. There are two connotations to stability here - 1. language and ecosystem standardization and 2. having a stable and predictable career. C++ has both a plenty (2. if you find your niche and then you are nigh irreplaceable, but not perhaps at FAANG rates).

Your knowledge never gets old, basically in C++.

The problem with C++ is that it is a horrible language in several ways. I guess the root cause is that it's basically a sugared C preprocessor with an infinite amount of special rules and special cases, that attempts to retain backward compatibility while adding new features. If my domain did not need it I would not write it. But it does, so I do.

My advice not to choose C++ because of career stability meant - "It's a bloody awful thing! Don't choose it if you have options unless you absolutely want to!"


> You think things are looking better in JS/Python world?

Yes.


Let's face it: C++ is pain. Even with all the improvements of the last 15 years.

Choosing something which us not C++ may be a long-term goal by itself.


Have you considered there may be a reason why so many large tech companies are so eager to move away from C++?


Perhaps they care more about exploration and learning rather than career growth and solving business problems.


> Zig is truly compatible with C and will compile C code directly, since its compiler is actually written in C++.

I assume this was intended to say something else?

> Here's the brutal truth: I can't find anyone under the age of 41 in my field to say a single positive thing about D

IIRC the presence of the GC in D was (is?) its Achilles heel. Because the GC is infectious. As soon as your dependency needs it (and IIRC even parts of the standard library did/do), it becomes painful if not impossible for you to avoid it. Had it not had this fatal flaw, D might've fared much better.


> Because the GC is infectious. As soon as your dependency needs it (and IIRC even parts of the standard library did/do), it becomes painful if not impossible for you to avoid it.

Isn't this the same for Nim? The standard library doesn't provide pure functions for parsing strings, it provides functions which generate exceptions. Exceptions use the heap, it's hard to get programs to compile with the garbage collector turned off, so everyone just recommends using ARC.


I don't know Nim, maybe it's the same? If it is I guess that would probably also explain why Nim hasn't replaced C or C++ either.

Though do note that (academic discussions notwithstanding) refcounting is not what people usually mean by GC in these contexts. Having to put up with refcounting is one thing (people already do it manually anyway), but having to put up with a generational or other complex GC is quite something else.


The issue with D is it still feels unpolished. Every time I try it - which is maybe once a year or so - the experience still feels weird and edge casey.

The idea that a GC is somehow a hindrance to language adoption doesn't make any sense to me at all. Doesn't stop people loving Go. But go has slick tooling.


> The idea that a GC is somehow a hindrance to language adoption doesn't make any sense to me at all. Doesn't stop people loving Go.

I meant as a systems programming language. To replace C or C++ or such.


Yeah fair enough.

Though I have to say - are there really that many scenarios in 2022 where a GC is unacceptable? Hard real time systems, sure. Tight loops in a high performance game engine - I can imagine. But... web servers? Graphical apps? Daemons?

I think there is a sweet spot for natively compiled languages, with garbage collectors, but also let you have a tight control of memory layout. There's really not many in this category.


> Though I have to say - are there really that many scenarios in 2022 where a GC is unacceptable?

There are more systems programming jobs (where GC is not usable) today than there was years ago. The percentage of all programming jobs that they make up is smaller, but the absolute number is bigger: https://www.toptal.com/c/after-all-these-years-the-world-is-...

Not saying the original poster is this type of person, but I actually work with a lot of recent bootcamp grads and you be surprised how many think C is totally not used anymore. To many of them, the whole world is written in python and JavaScript.


Anyone who was forced to write Java code on Android at some point suffered extremely painful performance issues due to the Garbage Collector.

I never had any problems with manual memory management, it can be done properly and safely without a GC, so for me the presence of a GC in a programming language is a net loss.


> Though I have to say - are there really that many scenarios in 2022 where a GC is unacceptable?

There are tons of C++ and C programmers who would find the introduction of a GC into their programs to be unacceptable, yes. That's why D keeps losing this battle.


Right, I guess I'm veering off topic and going into 'D in its own merits' rather than 'D as a C/C++ replacement'. Fast python vs convenient C.


I had one experience with Go. It was slow because the GC kept kicking in. So we won’t use Go again in favor of time-tested C++. GC is a major reason we are using C++ over Go. In my mind it’s a half-speed language. I’m also very put off by Rob Pike’s “Look, we replaced C++!” attitude when he somehow doesn’t seem to grok zero-cost abstractions. C++ has plenty of issues, but it doesn’t have GC and it goes further, providing standard allocators: both PMR for convenience and most use cases, and statically, for truly zero runtime cost.


I haven't seen Go's hit larger than 25% in our production.

Usually that means we have to keep average CPU load below 70%. (Since GC cames once in several minutes, it is usually not seen in per-minute averages)

That is ok for us, since Go significantly boosts development compared to stricter language.

It is "marketplace" thing, so we have enough money to spend on additional 50% servers compared to "extremely efficient No-GC" solutions.

It all depends.


Rob pike said they intended to replace c++, that didn't happen to his own accord.


Right. It seems like they set out to replace some misunderstood or outdated view of C++. They’ve clearly had success, but it’s no C++ successor.


It's main thing these days is its compile-time function executing and ‘design by introspection’.


> [..] I decided that I need a safe, fast, and statically typed language that can be compiled and targeted to both mobile and desktop environments, as well as being made available to scripting languages via FFI.

And you eliminated Rust because.. it’s too complicated? It meets these requirements to the letter! Since this is a greenfield effort, would it really be too expensive to invest some time to learn it?

Anyways, I wish OP the best with Nim. I’ve always found it to be an interesting language.


The authors reasoning makes sense to me. Rust is powerful but also complicated and tends to encourage playing "language golf" as often as solving actual problems.

> there isn't a lot of reason to defer to Rust as an obvious choice outside of the usual focus on memory safety that dominates public opinion. As someone who actually hates to code for coding's sake and wants to Get Sh!t Done, Rust is just antithetical to my relationship with computers.

Nim made me enjoy programming again, largely for these reasons. When I was younger I enjoyed mastering languages like C++ or learning complicated generics systems, but now I enjoy just building useful things with minimal fuss. I don't care as much about type soundness of my CTFE, just that I can parse a file at compile time to do something useful. Sure its on my to ensure my files are stable, but thats just part of programming.

> I don't want to have to think about the language, and that's all Rust wants you to think about. I see a lot of people attracted to Rust where there is no shortage of funding and developer focus tends to be competitive, often leaning towards academic purity over solving pressing customer facing problems. These aren't luxuries I have and, to be frank, is not the profile of developer that one should hire for in an early stage startup. Nim gets out of the way, and stays out of the way.

This is an interesting take.


> tends to encourage playing "language golf" as often as solving actual problems.

Is this your perception, or are you actually seeing this being encouraged by the Rust community?

> This is an interesting take.

I personally don’t agree with OP’s take on Rust at all, but I respect their decision to use whatever language works best.


Not GP.

In my experience, “language golf” is very popular in Rust, Scala and Haskell communities.


“language golf” will sour me to a language/community very quickly. I especially despise implicits, as they make source code utterly unreadable without the help of tools.


> would it really be too expensive to invest some time to learn it?

I guess it depends on who you are. I find the complexity of Rust, and the community's cultural acceptance of said complexity, oozes out into every library to make every new thing you try to do seem like another incredibly hard slog.

I had one try at Rust a couple of years ago, and gave up. I had another one in the first half of this year, this time intending it for a (personal/hobby) cli app. But again, just found it dispiriting. I wasn't baulking at a single tutorial. I read all the Rust book (and worked through about half of it in detail). I read Jim Blandy's book. Lots of tutorials etc. I went through all of Rustlings. And wrote the first phase of my cli app (it's trivial but fairly robust and I use it daily). I still found it damned hard to get anything done in Rust.

I haven't quite given up (mainly out of stubbornness and having some time on my hands), and plan to take up the 2nd phase of my one Rust app. But anyone who finds Rust to be tractable by just 'investing some time to learn it' is living in a different world from mine.


Thanks for sharing your experience.

OP in particular seems like someone who is familiar with a variety of languages, hence my comment. In addition, given that their requirements lined up with what Rust is good at, the time investment would be worth it.

When it comes to learning Rust in general, I think the difficulty and amount of time required depends on one’s background and overall learning style. If you are the type of person who wants to fully understand why things are the way they are before moving on, the process may likely slow down further. I think Rust is the kind of language where accepting things as they are at first will help you learn quicker. You can always circle back to dig in later.

For me personally, it took a couple of tries to “get” Rust. It definitely wasn’t straightforward to learn, but it wasn’t insanely complex either. Again, I think background and learning style contribute here.

Best of luck on your learning journey!


Your response seemed to fall into a category common amongst Rust enthusiasts, which is to assume anyone resistant to the lure is ipso facto lazy or misguided. Your own question was a hint at laziness. I have no idea how much effort the writer put into evaluating Rust. I doubt you do either.

I don't know why some of us find Rust difficult. Perhaps it just is, or isn't, or is for some people and not for others, or perhaps we are just thick. My suspicion is that there are more people who do than seem apparent, because they tend to get shut down by the very decorous implications of laziness or stupidity that are so characteristic of the Rust community.


Nowhere did I say or even imply that people are “lazy or misguided” for not learning Rust.


Well I didn't see another way to gloss your question:

> would it really be too expensive to invest some time to learn it?

I'm entirely happy to take your word that I've misinterpreted the question. Back-and-forth in comments about intended meaning is rarely useful. So my apologies.

But the general attitude in the Rust community (of which I have no idea whether or not you're a part) absolutely is "Rust is not hard, and if you find it so, that's a measure of your dysfunction, not a description of the language".


The context for that question is important: OP had a set of requirements and Rust seemed to meet them. I’d personally consider investing time to learn technology X if I found out it met my requirements. This is not a Rust-specific thing.

I agree that Rust is not simple to learn. There is a definite learning curve involved, especially at the start. I hope your experience with the community and the language improves going forward.


> given that their requirements lined up with what Rust is good at

I would say the opposite.

OP stress on the C/C++ interoperability. In rust, you need to either

(1) wrap the API in something Rust-like / Borrowchecker-friendly - which need lots of planning ; or

(2) Do it with lots of unsafe code - which make the memory safety lots more complicated to reason about

For memory safety, you can get it from any GC language without extra mental load.


(1) is a one-time investment and allows you to take advantage of compiler guarantees. (2) is what every other language does for FFI anyways. In Rust, you could have a lightweight wrapper around the C API, but you would lose out on some benefits.

OP said performance was critical, so why would they use a GC language?


I am curious about the safety, though.

This minimal example causes a segfault:

    type Foo = ref object
        a: int

    var foo: Foo = nil
    echo foo.a
which wouldn't be simply possible to type in safe Rust.


Reference and pointer types (annotated with `ref` and `ptr` respectively) are nillable. The compiler can provide null safety guarantees by annotating types with `not nil`: https://nim-lang.github.io/Nim/manual_experimental.html#not-.... So then your example would look like the following, and fail to compile.

    type
      Foo = ref object
      Bar = Foo not nil
    
    var bar: Bar = nil # error: type mismatch
    echo bar.a
Discussion about not nil by default is here: https://github.com/nim-lang/Nim/issues/6638


Hi, article author, here. Down in one of your other replies, you state:

> The context for that question is important: OP had a set of requirements and Rust seemed to meet them.

The context as I presented it is perhaps unfairly narrow, and I've glossed over some of the non-technical requirements that constrain my choices. Time-to-market and funding levels are hyper critical - these are hard limits that have less riding on me-as-IC being the sole determinant of a positive outcome, and more on being able to hire the first team members should I meet my funding goals in 2023. Here in the EU, hiring rust devs is ultra-competitive, expensive, and open positions tend to sit unfilled for longer periods of time. There is a mercenary like attitude among experienced crypto developers that makes it difficult to recruit for projects. A developer who is good with rust and knows crypto well doesn't need you for a job - they're probably already looking for funding or considering a co-founder position with a biz person that's already snared a wealthy benefactor for advisory and seed funding. This makes building a founding team (vs a team of co-founders) very difficult in the space.

On the flip side, I can teach a good JVM / golang / python / NodeJS developer how to iterate in nim a lot faster than bringing them up to speed as a proficient rust developer.

My top considerations were among "productive" compiled languages: go, crystal, swift, even investigating mruby. These languages have considerably less cognitive surface-area in banging out pedestrian and proprietary IP code in a 7:1 ratio (not scientific, obvs). First, you need to quickly produce MVP and v1.0 products. Secondly, the follow-on to that is being able to support fast iteration to launch and prune features. This latter aspect is much more important than the zero-to-MVP phase, since the clock isn't really running until you're actively marketing a project and it's gaining (or losing) users. Rust is just not a good choice for the entire code base. It is, however, a great-to-good choice for low-level dependencies. Given it's flexibility, I think Nim can be both. We'll see.

There are two documents that haunt my thoughts over the course of decades being in tech startups. One of them is Paul Graham's "Beating the Averages". The other is Akin's Laws of Spacecraft Design.

One of Paul's reasons for using Lisp at Viaweb was, paraphrasing here for brevity, that choosing the defaults of your competitors is going to yield an average result, which will put you out of business. In my industry vertical, I do think that Golang is more that default than is rust. The evidence seems to point toward Go based teams being better at burning through VC (tongue firmly in cheek ;-) ), and that Rust is superior at embedding working technology whose code-paths touch every customer, every day.

My sincere hope is that Nim hits the sweet spot in the middle while eeking out some of the competitive advantages that Graham talks about. As the idiom goes, you takes your money, and you makes your bets.

http://www.paulgraham.com/avg.html

As for Akin, the full list has some doozies but the one that really sticks out to me in the context of startups is this:

40. (McBryan's Law) You can't make it better until you make it work.

https://spacecraft.ssl.umd.edu/akins_laws.html

cheers


> Rust: I'm not afraid to admit it - Rust is just too complicated for use as an aging and cranky solo developer.

...

> As someone who actually hates to code for coding's sake and wants to Get Sh!t Done, Rust is just antithetical to my relationship with computers. I don't want to have to think about the language, and that's all Rust wants you to think about.

My guess: the author hasn't even tried it other than a cursory glance. I don't feel at all the way the author does about Rust. I do somewhat about Haskell I admit, although I like it just fine, but Rust is very much a "get it done" language, not something for academics. The only exception to this is the borrow checker, which isn't near the impediment most people think it is, but it does take a little practice. I learned it at 45 without issue, just a little bit of time. At this point, I code Rust as fast as any other language (probably faster when including debugging time - I almost never have to debug my Rust code).


I have written around 30k+ lines of rust by now, and I have to agree with OP. I have encountered many situations where perfectly reasonable, zero copy, memory management that would be completely normal, fast and safe in C, it basically impossible to replicate in Rust (or at least I am not clever enough to figure it out). Are there other ways to structure the data that work in Rust? Yes, of course. Do I like them compared to the C one? No, not at all. Do I think that the additional memory safety that comes from Rust is worth it? In some use cases, yes


I have written about 50K LoC of Rust, so fairly similar. I will agree that I have had occasional "lost days" with some very complex spots of code that would not have been a problem in a GC language. That said, I feel like I've made up for that at least 1.5-2x by my productivity and lack of bugs in other sections.

That said, I can understand how it may not be for everyone. I love it, but there are some data structures you just have to code differently, and until you spend time thinking about how to do that, it would seem like wasted time you wouldn't get back.

My personality may also be a fit: I'm very much a measure twice, cut once kind of person. I tend write my algorithms in pseudo code and sketch my data structures on paper before I touch the keyboard, so even in my "get it done" language I don't immediately just start coding always.


Seeing some of the hassles with creating basic stuff like a linked list is part of the reason I have yet to use it seriously. I think I will eventually, but I certainly won't act like it doesn't come with a cost or that it always pays off.


If you were clever enough to write it safely in C I can guarantee you'd be clever enough to write it in Rust.


Oh boy, that is so not true. Anything where the boundaries of the lifetimes are easily determined at runtime but unknown at compile time is extremely easy to model safely in C, and a nightmare in Rust. At least if you want the same level of performance and a similar modeling of the data


> Anything where the boundaries of the lifetimes are easily determined at runtime but unknown at compile time is extremely easy to model safely in C,

I don't even know how to respond to this seriously. I guess just imagine me pointing to every blatant instance of this not being true.


With all due respect to Michael Palin, "this isn't an argument ... it's just contradiction."

Perhaps, for the benefit of those of us observing if nothing else, it might be beneficial to identify some concrete examples to discuss before proceeding.


I dislike when a discussion turns into "I have to teach you the basics now". I'm just not willing to engage in that most of the time with strangers on the internet because they usually don't want to be taught, they want to be right.

Explaining that you can express complex dynamic lifetimes in Rust using 'unsafe' and module-level safety is a waste of my time because it's empirically true.


But you are engaging with strangers on the internet. You're just not doing it in a way that's particularly edifying. Indirectly insulting me and others doesn't help your case on that front.

Let me turn it back on you. By refusing to educate people on what you think they got wrong, you come across looking like just what you're worried about: someone who just wants to be right.

If your goal is to defend Rust, I would suggest you either teach for yourself, or share links to others teaching the thing you want to communicate but don't want to type out, or, if neither of those, then to simply keep your peace and let someone else do the responding. Speaking for myself as an on-and-off Rust learner, I've got to say that the single biggest frustration I've experienced with learning the language is wading through all the low effort gainsaying in order to find the nuggets of digestible, practical advice about how to effectively use the language for non-toy problems. It's not that I can't do so, per se. It's just that it's really hard, and perhaps even counterproductive, to work up the motivation to wade through all the snark and invective when my original purpose was to try and unwind at the end of the day.


I made an accurate statement. Anyone can take it or leave it.

If you want help learning the language I'd suggest the Discord or subreddit, people will be happy to assist.


In my experience, the vast majority of examples where that fails is because of two reasons: project evolution that doesn't spend time re-evaluting memory managemnt together with the new requirements on the data, or inexperienced C coders. So that goes to my last point in my original post, yes as an industry there are use cases where rust is better because of the provably safe memory management (let's forget unsafe for the moment). But as a language you _can_ safely model those situations in C esily. The problem is that the solution is not robust to change. If you don't agree with that it will be me who doesn't know how to take what you say seriously


Um, lifetimes are not a made up concept of rust to be in your way. It helps you understand issues that would be real and undetected in your C app.

Your C app would work by happy accident and you would not notice until later when data is corrupted in another part of your program. This is the rest of us wanted to leave C/C++.


Rust lifetimes are just the lifetimes of the memory, exactly the same as C. The only difference is you simply need to (sometimes) tell Rust where the memory for a reference comes from explicitly, where as in C you don't (but in C if you get it wrong your program will segfault, unlike Rust, or worse it might not...sometimes).


> Rust lifetimes are just the lifetimes of the memory, exactly the same as C.

Rust lifetimes are only the lifetimes of the memory that are provable by the type system. There are many valid lifetimes that are not provable. For example lifetimes that change at runtime, and self referencing lifetimes, or cyclic lifetimes. Newer versions of the borrow checker enable it to prove more lifetimes correct, but it will never be able to express all valid lifetimes of the actual memory.

This means some patterns the are completely valid cannot be expressed in safe Rust due to the limitations of the type system, but can be expressed in C.


And you can use unsafe.


Well yes, lifetimes also exist in C, but it is only in Rust that they are compiler checked


> I have encountered many situations where perfectly reasonable, zero copy, memory management that would be completely normal, fast and safe in C

So you think. It doesn't matter how smart you think you are, statistically speaking you're not smarter than a compiler.


I think you are overestimating the expressive power of lifetime annotations in rust, and how smart the borrow checker is


Anything you can express in C, you can in Rust. When it comes to pointer tricks you might have to use unsafe, but that is part of the language.


If only 50% of the community didn't think it was their job to scream at complete strangers for using that part of the language.


Agreed (unfortunately). There is too much of an obsession in avoiding unsafe at all costs in my opinion. When you consider all C/C++ is effectively written in an unsafe block then it seems a bit ludicrous to assume you would never ever use unsafe in tight, performant code.


Can we please not do this?

It's fine to give a different viewpoint, but it's surprisingly common that whenever someone says anything bad about Rust, a Rust user comes in to say that they just haven't used it enough.

It's like saying "If you don't like my favorite movie, you just haven't watched it enough."


It's not even the right category of criticism. The author talks about 'mathematical purity' which is something Rust sneers at. Spend just a little while with Rust and you can see that when the language is getting in your way, the driving direction it is pushing you in is towards code that will be maintainable. Which is still not about getting shit done, and is still a valid axis to prefer Go's rapid development cycle on, but if you cannot name the distinction then it is hard to believe you have spent enough time with the language to properly observe it.


I kinda agree, it's weird to me how people make a big deal about the borrow checker as if it's an evil spirit gatekeeping your code.

And if you wanna go fast instead of writing maintainable code you surely can with stuff like unwrap(), clone(), Copy.

In a way I think most people expect to pick up Rust more easily because they have expertise in other languages and are surprised when Rust feels like learning to code again, basically turning some ingrained assumptions upside down.

It really is not the kind of language where you can glaze over the introduction chapter and churn a TODO app in the same afternoon in my opinion.


>And if you wanna go fast instead of writing maintainable code you surely can with stuff like unwrap(), clone(), Copy.

That's a good approach to learning the language, but it breaks down as soon as async comes into the picture. It's basically impossible to be fluent writing async rust without a very healthy understanding of complex types, how the borrow checker works passing things across closures, etc.


> It's like saying "If you don't like my favorite movie, you just haven't watched it enough."

It took you average movie time to learn whole entirety of language? Wow!

And without sarcasm, yes, sometimes it is the case.


Most of the bugs Rust catches are memory related bugs and some data races in concurrent code. In any GC language the first is solved and there are concurrency frameworks available that prevent similar data race issues. TFA's author is comparing against Nim, a GC language. And in my experience of 10k LOC of Rust it's the same as the author's.

Also does every criticism of Rust have to have a prominent rebuttal? TFA buried it in the appendix and the article is about a lot more languages than Rust, but here we are talking about Rust again. We all have our favorites, we don't have to stick out for them everywhere. Some people don't like Rust and that's okay.


Seems like Rust is hitting peak popularity right now so there are tons of people out there feeling slightly insecure about their new language and needing to defend it every time someone picks a competitor.


> Also does every criticism of Rust have to have a prominent rebuttal?

Ha, sorry - I just really love Rust and want others to at least try it. I passed on it for _years_ because I thought like the OP (I used to code in Scala - I personally find THAT takes cognitive load to remember all the features. Rust feels small to me in comparison). Rust made me LOVE to code again and I just think there must be others out there who would feel the same if they just tried it.

> Some people don't like Rust and that's okay.

Agreed, I'm sure it isn't for everyone.


Maybe you should try a language where people get a lot of work done in the day to day ? E.g: Python, Go...

It seems crazy to me someone who code in Scala, now loves Rust. Brains are really something else :)


I've written extensively in about 10 languages including the two you mentioned.

The current project I'm writing is migrating from Python to Rust. Python is not appropriate for large projects IMO and this one I wrote and am now porting to Rust is no exception. I do love Python for things up to 1000 lines or so, but after that you really need to test every single line, which is just a PITA. Mypy and now others help, but the typing isn't strong enough (although I've heard good things about some newer static typing addons).

I have a love/hate relationship with Go, but after I found Rust I'll never touch it again. It simply isn't expressive enough which leads to code that is overly verbose. The lack of a decent enum, repeating nil pointer mistake, verbose and error prone error handling, the constant copy/paste (now semi fixed with generics). I do love that it strives to be a simple language, but strangely the Rust tooling is much easier to use, so I'm not convinced it hits the mark. I do love how fast it compiles, and that is the one thing I hate about Rust.


Hm. Ok. Tell it to my previous company running 12 million LoC of Python.

It was easier to make changes there than in the 500k loc c++ system I maintained later.

Language has nothing to do with success of large projects, it’s everything around it. The culture of the company, the cicd systems, the release system, the build system, packaging, documentation , rollback, dependencies.

And for large projects, you’re rolling a lot of those yourself.


> Hm. Ok. Tell it to my previous company running 12 million LoC of Python.

Just because it can be done, doesn't mean it should be done. Just my opinion.

> It was easier to make changes there than in the 500k loc c++ system I maintained later.

I don't consider C++ a good language in any way, shape, or form. Now had you claimed the same about OCaml, Kotlin, etc. I would have a harder time believing it.

> Language has nothing to do with success of large projects,

Of course it does, but they do not exist in isolation either - it is just one component. There are many factors that would play in.

> it’s everything around it. The culture of the company, the cicd systems, the release system, the build system, packaging, documentation , rollback, dependencies.

My point about python is that it literally _requires_ you to make up for language deficiencies (aka dynamic typing + unchecked exceptions) by testing insane amounts to even make it possible. The things that work against you at large scale, work for you at tiny scale (aka scripts).


Heheh company with 14 million LoC barely had tests :)

I don’t know what kind of companies you worked on, but let me tell you that the code that runs the world comes from an era before tests, and some of it is too complicated to even be tested.

Test it in production is the only way for a lot of it. Then you need observability and easy ways of rolling back. That’s about it. Regardless of the language.

Read the latest google book — code architects at google I think it’s called ? Has a couple of great chapters on testing at scale and how unittests are useless


Your argument vs OP that tried rust, is that they should try rust until they agree with you?


Im currently writing a multiplayer game client (personal project) in nim +SDL2 which is comes with bindings for. Now and then I hit some obtuse compiler error messages, and the compilation times aren't the best. But honestly I'm glad I chose it over c++, which has been my default choice in the past. I wanted to try something new and I'm glad I stumbled across it at the right time


Would have liked to see an opinion on the large number of memory management techniques for Nim [1]. Seven types(!) ranging from GC's to manual. Surely this makes reasoning of performance very hard. Where do you focus - your program or the memory management options. Perhaps in practice everyone has settled on one of them(?)

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


The default for the upcoming Nim 2.0 will be ORC. Its the default already on the dev branch since the Nim compiler was switched to use it. See Araq's talk from NimConf: https://youtu.be/aDi50K_Id_k?list=PLxLdEZg8DRwSQQaK0UVRd1Dae...


I'm curious about this too. If Nim managed to design a system that gives you more flexibility without adding more complexity, that would be pretty stellar.


I'm choosing between learning Nim or Rust. Nim frankly looks like the nicer of the two, but also less marketable and with smaller community.

Suck to say but it's true.


I honestly don't think your options should be between Nim and Rust. Nim has a very small community, and almost nobody is hiring for Nim experience. Going through Nim's forum, I think most developers tend to work on Nim projects alone.

If marketability is your priority, learn the popular languages like java, c, c++, golang etc. Even people hiring Rust developers usually have some leeway to hire someone who can learn Rust on the job.

The decision to learn a programming language comes down to three options:

- Popularity

- You are paid to learn

- You are passionate about it, and you don't expect to collaborate with anyone.

Number 3 is the reason why I am learning Nim.


I think you are jumping to conclusions about my choices. Why do you explain to me how to decide when you don't know my objectives and constraints?

My main language is Python, to that I'd like to add a compiled, native code, fast-ish, statically typed language with good Python interop. That takes away JVM and .net languages and leaves, roughly, C++, Rust, Nim, maybe Go. I take Go off because I don't like it. I also can't stand modern C++. What does it leave me with?


> Why do you explain to me how to decide when you don't know my objectives and constraints?

You asked a question. You didn't provide any context. I took the initiative to answer the question based on the mere statement of "Nim vs Rust".

My intial feedback still holds true. Does your job require you to learn anything specific or do you want to learn anything just because?

> I take Go off because I don't like it. I also can't stand modern C++.

You are giving your personal opinion and without context. Why do you not like Go.... never mind. It is the weekend, try Nim and Rust both, see what you like.


Nim is also easier to learn - if you know Python and any conventional statically typed language, it's a walk in the park. I was producing fast, working code in a couple of hours.

Learn Rust for your job, Nim for your side projects.


Something I long assumed about Rust before really getting started is that it is /slower/ to develop with. And at first that is definitely true because it introduces some pretty big, powerful, and constraining things. When you learn to work with these things and have taken your lumps discussing your code with `rustc` it is a lot of fun.

1.) Moves / borrowing / memory model 2.) Adopting a more functional style [to support 1.)]

My observation is that a lot of people /really/ want Rust to be imperative and treat it very imperatively they fight the borrow checker way more than if they adopt the idiomatic norms of Rust. There are some edge case data structures that can be a little painful and require some specialized knowledge, but once you are into Rust I don't even think it is unpleasant for side projects and general purpose hacking, but to get there it demands a higher level of mastery than most languages, but when you get there it can feel extremely productive.


Rust's sphere of necessary domain knowledge is higher than average. That's not a downside relative to the goal it has in mind, but it is a trade-off. When you're an indie developer working on a side project, there's a strong impulse to let go of a lot of the specific quality controls and customizations that you can use in a team setting where you're paid to know how to operate the inner workings, and instead look for something that is "prosumer" and lets you hack out a solution.

It's kind of the difference between "I want to make a camera" and "I want to mod a camera". Making means controlling the design from the beginning, and Rust is one of the best available tools for that. But modding is more like what you do when you want to bodge together some pieces of I/O and data processing. Apps dealing with audio and graphics in any fine-grained sense tend to want the latter: they aren't actually dealing with resource management issues that often, especially not in the "weekend hack" stage, they just need low latency device access and a fast-enough inner loop. And those requirements imposed a massive, non-obvious barrier to entry on stuff with a substantial VM runtime: writing bindings, remapping ABI semantics, etc. You had to learn a lot of concepts, possibly more than are needed for writing useful Rust code, to overcome that. Rust demands just that you use certain kinds of documented idioms to get through a typical coding problem, while fighting with compilers and linkers to create bindings is a no-mans-land of debugging the meaning of each error message, silent failure or crash, requiring you to know two languages, the build system, the binary formats, and the OS you're targeting simultaneously.

For a long time, C++, for all its faults, was the prosumer's tool of choice for coding near to the metal while still leveraging existing tech, because it was what the toolchains actually supported directly, which let you get ypur weekend hack working piecemeal, while using something else introduced unacceptable levels of overhead.

But I think there are now justifications to use Rust in some cases and Zig or Nim in others. I've kicked the tires on all three, and can vouch for Nim feeling productive in the sense of being both relatively C-friendly as a build environment(lots of features for high-permissiveness hacking) and also occupying a "default to high-level methods" mindset. D could have gotten there in an alternate reality, I think, but it was trying really hard to be big-systems code instead of hacker's glue, which has saddled it with an awkward design story. The things D wanted to do well, Rust now mostly occupies.


I like all of this thinking. I don't deal a lot with ABI and integrating Rust into things, just another programmer that has been writing a Go (and Python) over the last few years and gradually becoming disaffected with its constraints and design, though Go is still a great language to get things done with and much safer than say Python or other dynamic languages. I will say this, though, as an older programmer, even when scratching an itch, it is often worth Doing It The Right Way. It feels freeing to rush ahead, know you are making technical debt, but get a thing to seemingly work.

If you or anyone else ever has to maintain it that technical debt almost always comes calling and it can often be unpleasant. For personal projects, oh well, you move on, maybe you can throw it out. For even small professional projects you are now in the "Find Out" phase of technical debt. So I am just in this mindset of writing meaningful things and saving experiments for truly throw away code, which still has its place. I am gonna go ahead with Rust as my next 5+ year language, a role Go and Python filled. I think my litmus for Python vs. Rust is if it will take me more than a day (estimate) to write, I am going to suck it up and use Rust.


Found this myself. Learning curve is steep. Still not there yet but once you get into it I can really see how more productive I am vs other languages.

Other languages just require a lot more trial and error to get them to do what you want. Rust, if it compiles, generally does what you expected.

It's not just type safety and the borrow checking either, it's the idioms, std lib, and other language design choices that lead on to improved devex in the wider ecosystem as a result.

I understand you can get the same features out of modern C++ now days but it's not just the features, it's everything that comes with it.


I had a similar experience. I took a very small project from Python and turned it into Nim: it was about six times as fast to run and took roughly the same amount of code in both. I have plans to learn more but this article is actually a little more fuel for my fire as I think one of my next explorations would be transferring and running code on other systems. If portability is as easy I could see this being used for some work tools I am building. We will almost surely never replace the current language all the major code is written in, but for small self-contained tools it would be great.


I'm learning Rust now, I can say Nim is much harder. Maybe the language itself is simpler, but the documentation is just not very good. Very unpolished and amateurish. I actually forked out fifty quid for Araq's "Mastering Nim" book; it is atrocious. Spelling and grammatical errors on every page. The very first code example did not compile.

I also regularly run into utterly infuriating bugs while trying to accomplish what I thought would be simple things. Don't expect to be able to get anything useful done using iterators. They're zero-cost only if you don't value your own time.

On the other hand, all of Rust's docs are a joy and I haven't run into many technical problems so far.


Yeah, I wrote an equivalent service in Java and Nim, and I just couldn't get Nim to perform as well as Java, and it wasn't even easy to write. Random segfaults, depending on memory manager used, random libraries requiring different memory managers, ORC being talked about a lot despite causing random segfaults, and so on.

I really want to love Nim.


Author's take on Java is really funny.

"..the JVM's largesse isn't aging particularly well. It will die with my generation's retirement."

I call this fundamental blindness considering the JVM is improving dramatically year after year - now even supports lightweight concurrency like Go in 2022.

Java will still be alive and kicking when no one alive even remembers Nim.


Good points. People also seem to forget that the JVM's introspection and monitoring capabilities are second to none.


Not only Java, but major JVM languages as well (Clojure, Kotlin, Scala).


Did we read the same book? I find Mastering Nim a pretty excellent reference. (And you have to install the pixels library :-P)

The online documentation, certainly, could be better. I sometimes find standard library documentation lacking in examples, and compiler documentation is currently undergoing a massive refactoring effort on a couple of fronts. But the manual (https://nim-lang.github.io/Nim/manual.html) isn't half bad.


>(And you have to install the pixels library :-P)

I knew someone would say this: it doesn't tell you that, does it? It's supposed to be an introductory reference work, so surely "how to install the 3rd party package required by our hello world example" should be included?

And anyway, even after I installed pixels the code still didn't run right.

I honestly found it insulting that such an expensive book would have such obvious oversights. It's like nobody proofread it at all.


can you post a picture of the page ? I'm curious now


Actually I just double checked and it turns out I misremembered; it does tell you how to install the library. But it didn't work properly when I tried to run it, I just got a blank window. A few people in the Nim discord had had the same problem and nobody could figure it out.

I don't want to take a picture because I already wrote in the book and I don't want people to see my handwriting. But here is some verbatim text from that single page:

>In this chapter we will show the basics of Nim language

needs a "the" before Nim

>(types, for loops, if and case statements, procedures, etc.) while using basic graphic primitives to create shapes

needs a comma after the close parenthesis

>The premise is that the `putPixel` proc exists and we can use it, ...

"proc" is a nonstandard technical term that has not been defined properly yet

>All we need to know is: that proc takes the x and y coordinate of a point ...

colon should not be there, and it needs a "the" before "proc"

In and of themselves these are fairly minor problems, but the whole book is like this. All are forgivable in say, a blog post, but this is a book I paid good money for. It's shoddy work, evincing a lack of care. Not to mention, the print quality is poor.


Ok thanks


I have the book, and it's an excellent resource for the language. I might be a little biased because I am a long time Nim user but definitely so are you.


Does Nim have any large groups sponsoring? Part of the appeal of Rust is that it will be around in 20 years due to so many groups adopting it and maturing its governance.

I enjoyed learning Nim syntax through exercism.io (not affiliated, just really enjoy it as a tool), but I'll be honest that I have no clue if it will become an ungoverned mess or thrive.



Ah, so its definitely a passion project with only about $21k in direct funding per month as of last update (2019).

Hey @G/Xooglers, Linux Foundation, etc., consider supporting Nim!


> Nim is also easier to learn - if you know Python and any conventional statically typed language, it's a walk in the park. I

I kept hearing the comparisons to Python so I thought it'd be interesting to pick up but the syntax and naming was so counter to Python that that expectation made me immediately bounce off of it.


I tend to be a C with objects (compiled with a C++ compiler) type of person because I think things like the base string, memory blob, etc types in C should have the ability to have bounds checking built in at compile time if the programmer chooses. Simply fixing the few things "wrong" with C I tend to think gets you 95% of the way to a heavier weight environment like java/etc.

So, I can't help but feel that all these languages are trying to solve that last couple percent, and paying a huge price in perf or programmer productivity to do it, at the cost of basically close to 0% bugs actually being reduced. Particularly when compared with C++ and Ada when used in a rigorous development environment.

Nim seems like the kind of thing (a veneer over C) I would want, along with an easy of interfacing to the rest of a C based project, but I always just tend to end up reaching for C with classes, when I need to get something done yesterday, and it needs to fit in a few K, or push the metal to the limit. Largely because I trust I won't get myself in a corner with it.

(PS: I too tried rust and tossed it as not ready, and not really solving the right problem. I don't tend to have memory concurrency bugs in either C or C++ because I don't try to be clever, instead defaulting to simple ownership models wrapped in C++ classes, or fully containing locking/etc in a single function that does all the work of both locking and unlocking the data structure in question and reading/updating it through a single entry/exit).


> So, I can't help but feel that all these languages are trying to solve that last couple percent, and paying a huge price in perf or programmer productivity to do it

I'm the first to admit that Rust has a steep learning curve. But now that I'm proficient in it, and as a long time C++ programmer, Rust is easily 2x more productive for me, and WAY more enjoyable. For large/complex codebases, the gap is even bigger IMO. But yeah, it takes a lot to get over that initial hump. It really helps to have a mentor for the first couple months.


> So, I can't help but feel that all these languages are trying to solve that last couple percent, and paying a huge price in perf or programmer productivity to do it, at the cost of basically close to 0% bugs actually being reduced

What about those “heavy” languages like Java, etc? Why don’t you use those then? I really don’t think that it has been true for the last 20 years to claim that they have a huge perf cost. And you really can’t go down the “safe” path in Java, even race conditions are well defined after all.


Importantly it's a decision made as a solo developer at a tiny company. Otherwise it's not like there are any Nim jobs out there, or any serious mindshare/momentum, or significant investment from big companies.


> Rust: I'm not afraid to admit it - Rust is just too complicated for use as an aging and cranky solo developer.

I'm nearly 51 and currently learning Rust.

The first 10 hours of it were horribly slow, but it isn't as steep of a learning curve as Optimal Control Theory.


I'm close in age to you but that was one part of the article that resonate w me.

I'm often writing little scripts for my computer or things that a dozen people will use, if I'm lucky. If the program 'crashes' it barely matters.

It feels like, in Rust, I have to carefully choose my data type and use the applicable methods (not always intuitive), whereas in Nim or Go, I can basically just slap something together and then have an error condition which is like 'if you die, just print that you died and quit.' And that pretty much meets my needs. The extra safety isn't actually protecting anything valuable, in my case.


I mean "unwrap()" and "panic!() are right there for "blow up and don't care", if you're really just doing throwaway scripting that should be enough.

And the "?" operator is way more ergonomic for throwing actual errors up a level than all the boilerplate in Go.

The pattern matching with `match` `if let` and `let else` are pretty easy to use to unwrap Result and Option enums.

And then the "anyhow" or "thiserror" crates make it all more ergonomic.

The end result is something is much more readable than all the error handling in Go, while still being at least as safe if not more safe.

Plus you wind up playing with Monads without needing to know what the hell an endofunctor is.

And there's no null/nil, while Options have to be explicit and if you squint (because of the presbyopia) they look kinda like the nillable stuff in C# 8.0


Kind of an ironic reply - naming 10 Rust features and libraries vs. an `if` check in Go to argue that Rust has simpler ergonomics for throw-away code.


My response covered the gamut from throw away code up to error handling in professionally written code, with a diversion through "null" handling.

To reiterate, for throw away code (or tests) unwrap() and panic!() will work just fine.


> code up to error handling in professionally written code

Lol, if you knew how much python code runs the world without even checking for exceptions, or with a try/except/pass ... and the world keeps on spinning.

"professionally written code" made me chuckle


Yeah I'm done with the trolls here.


I never understood the pearl clutching going on when people hear that Rust has different constructs for handling errors and control flow and if/else stuff is kinda an antipattern.

Same kind of people that would hold dear GOTO statements in my opinion.


Well the responses here are just a little bit more conviction that I'm on the right path with Rust.


Not sure if you're being sarcastic or serious


Learning curve is straight up for many with the borrow checker, but once you are over that hump, and it comes pretty quick for most, Rust is no harder than any other language.


Easier than C or C++ for sure. But I definitely wouldn't say that Rust as easy as a GC'd language like Java or Go.

They have strictly less constraints to deal with, they can let you use the simplest pattern for the situation, and (in my experience) they have less superfluous refactoring sessions due to the overly conservative nature of the borrow checker. I like how Matt Welsh put it in https://mdwdotla.medium.com/using-rust-at-a-startup-a-cautio...:

> What really bites is when you need to change the type signature of a load-bearing interface and find yourself spending hours changing every place where the type is used only to see if your initial stab at something is feasible. And then redoing all of that work when you realize you need to change it again.

Perhaps you're instead speaking of a specific situation or kind of program where the borrow checker happens to be no harder than any other language?


In my experience, it depends heavily on the kind of thing you're writing. I could write some small programs in it, no problem: a rather complex, text-based calculator was easy and elegant to write with function arguments, a game server monitor, some tools for a cryptography course, an FFT analyzer that reads from WAV or AIFF, etc. Then I tried to port my rather efficient Earley parser (https://en.wikipedia.org/wiki/Earley_parser) from C. Constructing the item set efficiently wasn't that hard, but constructing the forest (set of syntactic trees) was. In C, it was basically free by using some pointer sharing, but I couldn't get that done in Rust. Perhaps there's some clever trick I couldn't think of, but I couldn't get it anywhere near C's speed. And since the ultimate goal of that parser includes further memory shenanigans (unification of results yielded by the rules), I dropped the project.

At my job, I'm writing in Go. I fairly sure I could easily port the C code to that. It would probably run a bit slower, but the algorithm and data structures would be readable, and extendable.

So: it depends.


I really can’t understand where this idea that rust is ‘hard’ comes from. Everything that it formalizes is something that you should already be conscious of. If not, well… you have a different, bigger problem.


That's true only in comparison to languages with manual memory management. Higher level languages spare you the burden of being conscious about these things, which means Rust is naturally going to be more difficult to work with than, oh, I dunno, Ocaml.

From the other direction, coming from low-level languages: the other problem is that Rust's type system isn't powerful enough to express certain things that you, a competent C programmer, might be fully conscious of...and so you end up needing to fight the type system to get it understand something you're already aware of. To use a classic example, you can understand exactly how the lifetimes work in a doubly linked list but still find it more painful to write in Rust than in C.


Memory things, sure. There is the whole concurrency/parallelism thing, though.


Pony is a great example of fearless concurrency without the borrow checker's difficulties.


It's a shame how seldom this language comes up in discussions, I toyed around with a few years back and it was wonderful even back then.

Happy to see that it's getting frequent commits, would love to see it become more popular.


Can you explain to us what's the bigger problem we should be addressing according to your opinion sir?


You’re creating lots and lots of bugs that will come back to haunt to at runtime (midnight on a Friday if the universe has its way).


You're assuming everyone is coming to Rust from C. People who are learning Rust from a garbage-collected language will absolutely feel that Rust is harder than what they're used to, and not because they were writing bug-ridden code in Java or whatever.


Single ownership often introduces bugs of its own. In Java, I never need to create an Err if the thing my ID is "pointing" to isn't around anymore in whatever hash map the borrow checker made me store it in.

It's good in some cases, bad in others.


> In Java, I never need to create an Err if the thing my ID is "pointing" to isn't around anymore in whatever hash map the borrow checker made me store it in.

What’s the problem here in Rust?


It's not an 'idea'. Many people find it hard (I do). You might not understand why this is the case, but that they (we) do is an empirical fact.


Not really. Plenty of languages are garbage collected so you don't need to consider the intricacies of memory management. That was one of the biggest issues I found when I first started writing Rust.


That absolute claim is simply not true. That's like saying that people need to avoid shared mutability in every program, which simply doesn't make sense for a lot of programs, especially if you have a garbage collector already.

It's only a useful tool that has some nice qualities in some settings. It's not some underlying truth of the cosmos, it's just a situationally useful way to do things.


> Pony has probably the best type system in any language existing today, giving even Haskell a run for its money.

In what sense?


What’s the LSP and linter/formatter story these days? Last time I tried it the lsp was miles behind what I am used to from TypeScript land in vscode. I have gotten sooo used to all the auto completion, helpful error tooltips and auto imports and formatting on save that it felt tedious not to have that in a similar capacity. Maybe I was just doing things wrong and it’s been a while. In general I am super intrigued by nim coming from python originally. I wish I could use it professionally on a project just to spend more time with it


Its ok. A developer was recently hired to work on it full time though!


On it or with it?


On it, to improve the lsp tooling.


It's alright when it doesn't crash. But it frequently crashes. Tooling is definitely a weakness of Nim (although it's improving).

More specifically: right now auto completion is excellent, implicit type annotations are excellent, error tooltips on save work, broader rename/refactor support is limited/nonexistent, formatting on save is fine, auto imports don't exist (and probably shouldn't given that it's typical to use unqualified namespaces).


Aside, curious what this bit of the post refers to:

> Pros for Swift are focus on secure programming outside of just obsessing over memory safety like Rust.

I've never used Swift at all but would enjoy learning what it brings to the "secure programming" table that I might be missing from the summary at https://www.swift.org/about/#safety

Another aside, the author gets some points for looking at Pony.


I can’t speak for the author, but I’ve had a similar feeling. Where (safe) Rust’s core principle is memory safety at all costs, I feel that Swift takes a more nuanced approach, prioritizing making good programming patterns easier while still being memory safe (though perhaps not as expressive as Rust).

Swift also is much more principled when it come to certain things like exceptions. Whereas Rust (if I remember correctly) allows arbitrary panic-ing and catching of panics, Swift forces you to acknowledge a possible panic at function call sites using “try”. Without “try” control flow can’t suddenly end.

Admittedly, I haven’t used Rust significantly in a couple years, but I wrote this a few years back and some of the points still have merit: https://gist.github.com/GeorgeLyon/c7b07923f7a800674bc9745ae...


> Whereas Rust (if I remember correctly) allows arbitrary panic-ing and catching of panics

While it is possible to "catch" a panic in Rust, this is not an error-handling strategy, it is a correctness fallback. The intent is that, if you're writing a Rust library that exposes a C ABI, you halt the panic at the boundary of your library, because there is no standardized cross-language unwinding scheme and so unwinding across an FFI boundary would be UB. It's not there for error handling (and it can't be, not only because the API is deliberately designed to discourage it, but also because Rust programs can be compiled in a mode where panics abort instead of unwind).

> Swift forces you to acknowledge a possible panic at function call sites using “try”. Without “try” control flow can’t suddenly end.

This is a bit inaccurate. You can absolutely do things like divide by zero in a Swift function that isn't marked as `try`, which will crash the program. This is the same behavior that is expected of panics in Rust.


> while still being memory safe (though perhaps not as expressive as Rust).

Rust's memory safety protects against data races. AFAIK, Swift does not.

> Swift also is much more principled when it come to certain things like exceptions. Whereas Rust (if I remember correctly) allows arbitrary panic-ing and catching of panics, Swift forces you to acknowledge a possible panic at function call sites using “try”. Without “try” control flow can’t suddenly end.

Generally in Rust, a panic means the program has entered a state that is unexpected by the programmer. One example is an unexpected index out of bounds error.

For cases where an error is an expected program state, like a web request or input validation, it's recommended to use `Option` or `Result` instead. Rust will force you to handle the error case.

Yes, any function can panic, and any caller can catch panics, but panics are not the primary "exception" analogue in Rust. Panics are only for fatal errors.

I don't know anything about Swift, but from a quick search I see something called "Fatal Errors", which I assume act a similar way.

Now to address the points in your gist.

> lauded the Borrow Checker for discouraging people from using the borrow checker! This results in less performant code much of the time.

The borrow checker is much improved with non-lexical lifetimes which makes it far easier to deal with.

> The escape hatch of macros and build-time source generation has allowed Rust to sweep some of its usability issues under the rug (Just use a macro!). Swift strives to support all of the use cases developer have in the language itself

I have no idea how you could, for instance, implement something like `serde` without macros or reflection without building it into the language. Other common uses, like `lazy_static`, have been replaced with better APIs that don't use macros at all. Building these things into the language or standard library without enough experimentation beforehand can be problematic, as `lazy_static` shows.

Rust's development is more open than Swift. It doesn't have the luxury of a single owner that can dictate THE WAY to do things, because it must support use cases from web servers to embedded MCUs. Macros and other forms of build-time execution provide that flexibility.

> Coarse Imports

Personally, I think Rust's module system and imports area the best I've ever used. As I said, I've never used Swift. Are all of the standard library functions in a single namespace?

I imagine that this makes implementing things like refactoring much easier.

> First party IDE > > Say what you want about Xcode

Xcode is MacOS exclusive.

> With the current state of RLS, developers often forsake modern IDE features even though reliable code completion, refactoring tools and diagnostics greatly benefit developers.

RLS is now deprecated, and rust-analyzer is fantastic.

> Out-of-the-box debugging experience

I haven't ever tried interactive debugging with Rust, so I can't comment.

> One of the more powerful uses of a type system is to have functions perform different processing based on the type of its arguments.

I think one of the fundamental difference of today is that this should be handled by traits, not by standalone functions.

> In Rust, this is achived via the From and Into mechanic. The first unfortunate consequence of this is that you often have to create a new type and trait pair per argument you want to be polymorphic.

I don't think this is a common pattern at all. Generally you'd just implement the trait for each type and put the different behaviors in the trait impl, rather than in the function using an enum.

> you can effectively only ever have one generic implementation of your custom into Into… for a trait, since otherwise the type checker complains there can at some point in the future be a collison.

This is only true for types outside your crate.

> In Rust, you cannot create trait objects out of certain types of traits. Often, you could use trait objects for this type of thing, but I haven't figured out a way to do this with more complex constraints. For instance:

    trait Bar {}
    trait Baz {}
    trait Foo {
        // This is invalid
        fn foo(t: &(Bar + Baz)) -> ();
    }
I think what you're looking for is:

    trait Foo: Bar + Baz {
        fn foo(&self);
    }
This will work as long as Bar and Baz are object-safe.

> Making it generic disallows using Foo as a trait object:

    trait Foo {
        fn foo<T: Bar + Baz>(t: T) -> ();
    }
    // This is invalid
    fn do_work(f: &Foo) -> () { … }
You can make the trait generic instead of the function:

    trait Foo<T: Bar + Baz> {
        fn foo(&self, t: T);
    }
> Multiple if let cases

They are a work in progress, available in nightly: https://github.com/rust-lang/rust/issues/53667

But they do require an extra level of parens in some cases, though I think that's insignificant.

> Guard Statements

Rust has these now as "let ... else" statements.

    let Pattern(binding) = thing else { ... };
> Explicit try

This was covered above: use Result or Option instead. Panics are not exceptions.

And as for unwrap, yeah you just have to know that it will panic. It's just a thing you have to know about the language, like `try`.

> Rethrows

Transpose is stable now. But generally for that case I'd do this instead:

    let y = Some(1).ok_or(Error)?.and_then(|i| {
        if i > 3 {
            Err(Error)
        } else {
            Ok(i + 1)
        }
    })?;
> Ternary Operator

I prefer the lack of a ternary, since, as you show, an if can do the same thing.

> String Interpolation

You can include variable names inline now. And they're not C-style at all.

> Named arguments

Personally, I've never felt the lack. Especially with the inline hints from rust-analyzer.

> Default arguments

I actually prefer how Rust does not have function overloading. This includes default arguments and optional arguments.

> Function-level polymorphism

And the above also applies to this.

> This is also useful for operators (in Swift, + is a polymorphic function)

This is implemented with traits in Rust.

> Alternatively, you could use use:

    use MyDescriptiveEnum as E;
    match e {
        E::Foo => …,
        E::Bar => …,
    }
You can do a glob import instead

    use MyDescriptiveEnum::*;
    match e {
        Foo => …,
        Bar => …,
    }
> Raw types for enumerations

Rust enums have this for primitive numeric types, but others do not.

> Rust's enum and struct initializers all use different syntax. In Swift, there is a single syntax

Sure, they both use parens, but they are still different syntaxes.

> Trailing Closures

I don't like this. Seems like a special case for little to no reason.

> Default Closure Arguments

Same as the above.

> Extensions, Type Inference for Associated Types

I agree these could be useful improvements.


> OCaml, Haskell, F#, and other weirdos: I personally can't do it. I tend to not like functional programming languages. I want to, but my brain lacks the plasticity to relearn everything.

Why would you find OCaml hard to learn if you know Nim? Isn't Nim a functional programming language as well?

Also, how is Nim for writing real-time games that run via JavaScript where you want to avoid garbage collection pauses?


Nim is not really functional. Like most modern languages, you could probably pull of a functional style with it, but it's mutable, imperative, etc.


OCaml supports mutability well. Basically, you can write OCaml as if you are writing Nim.


Same way you avoid them directly in JS. I don’t think Nim claims it’s easy to do.


> I think the D folks fell into the same trap as Rust in trying to support every esoteric programming fetish stemming from toy-project and side-hustle demands among People Who Code.

Chef‘s kiss.


My issue is that Nim has some awkward problems with static linking:

https://github.com/nim-lang/Nim/issues/15220


Nim desperately needs a real web framework (batteries included) and a proper ORM and it will take off like wildfire. Python on steroids.


Has anyone tried prologue? https://github.com/planety/prologue


Yup, but it's more similar to "express" in Node than to a full framework like Django. I have plans to build a library on top of prologue for the ORM and database interaction and other cool features of Django that prologue currently lacks.


There is this attempt at a batteries included web framework: https://github.com/jfilby/nexus


I wonder why people haven't implemented it yet. Seems like a good project for me.


I think you’re very confused about the purpose of a systems programming language.


Not at all, and I've actually _used_ Nim for a few years now.

If Nim does not get a general purpose, batteries included web framework it will never reach escape velocity and will be left in obscurity despite all of the incredibly difficult and marvelous work Araq and the team has done.

I want them to succeed. I love the language!


Nah, parent commentator and me both think Nim could be really large. The definition of "systems programming language" is defined by arbitrary lines.


Web apps are applications and are the opposite of systems software. Systems software would be the web server itself, or something that runs beneath the application layer.

Yes definitions are sometimes nebulous but that doesn’t mean words should lose all meaning and we should stop trying. Systems programming is a useful label for the boot stack, kernel, protocol implementations etc. which support the application layer.


The "systems" label only means those languages can do a few more low-level things, nothing more. There's no reason not to use it for other things as well.


I know this is hammered to death on HN, but you could definitely argue memory safety is a reason not to use systems languages for anything else.

Granted though it means what you meant by "it". I read that as "a systems programming language", but if you specifically meant Nim then I think it can enable a GC.


people just say it's a systems language, it doesnt have to be only this.


Nim still need a lot of time to mature, there are totally ridiculous decision of things that core things have done like style insensitivity and half a decade old serious bugs that Nim team ignore to fix cause Nim adoption to low. 5 years ago it was on rival to rust but now rust had sky rocketed and Nim community is having a lot of in fighting going.


The best language to learn and use right now for systems programming is C/C++. It is by far the most marketable skill with 99.999999% of all low level systems written in C or C++. Large scale systems used by companies that pay top salaries for developers (Google/Meta) are written in C++. There is more material out there for learning and mastering these languages than any other language save maybe Python or JavaScript.

If you are not an expert at C or C++ and being paid to learn Rust or Nim, you’re actively harming your career by not mastering the languages that people want today. If learning hot new fads brings you joy, then perhaps the intrinsic value outweighs the real world loss, but it’s the hard to swallow truth.


C++ codebases are not at all pleasant to maintain. I'm willing to accept a smaller job market in exchange for a much more enjoyable day to day existence.


Not everyone is interested in maximizing their income. A lot of us here got into programming because we really do just like to code.

For us, it's worth sacrificing $x thousand per year to write code in a fun language that makes us happy. Your condescension toward that decision says more about your priorities than it does about ours.


Most people prefer coding newer systems over legacy systems in old dialects of C and C++. So that skews things more heavily in favour of rust.


I agree, but what people prefer vs what companies do are very different.

Companies rarely pay for totally rewrites. Nim compiles to C and offers safety that can work on top of codebases without a re-write.


> Large scale systems used by companies that pay top salaries for developers (Google/Meta) are written in C++.

And you of course have some stats that prove C/C++ pays better at FAANG than more pleasant languages?

> There is more material out there for learning and mastering these languages

Really? C++? Maybe I’m looking at the wrong places, but outside of huge Stroustrup books, and a couple of gems like Effective C++, there’s not much high quality content out there.


The Rust community is however, an excellent community to be part of.

And it's future proof. Everyone knows Rust is the future.

I'd say, for most college students, Rust would be the one you'd advise today.


> The Rust community is however, an excellent community to be part of.

I honestly haven't found this to be the case. There is a constant denial that some people might find Rust difficult (with a very strong implication that if they do, it's because of inferiority on their part), and extreme thin-skinnedness towards even the possibility that Rust might not be for everyone. Indeed, a bluff assertion that it is for everyone is part of its official tagline. The community keeps up a surface politeness, but it always looks to me that it achieves this by keeping a tight lid on dissent (or appearance thereof).


I've experienced this as well. Any disagreement always comes down to "you just haven't used it enough". I let myself take that gaslighting for years before I decided to just not go to the Rust servers any more.

And then when you question any of the classic Rust axioms (such as safety or speed being only desirable rather than an absolute commandment) a lot of them tend to get rather hostile. It's not a pleasant crowd if you don't think 100% like they do.


Sorry to hear that. I certainly don't think Rust is ideal for every use case. And it is definitely hard to learn. I think people get a bit too zealous promoting it, simply because it has solved a lot of painful problems that many of us have battled with for decades in C++/C land.


I have bad experience interacting with members of the rust community. Biggest issue is that they don't keep their opinions to themselves and frankly make everyone misserable with their "join us now, you must" mentality.


I have mixed experiences.

The evangelism on HN and reddit can be stifling. Particularly the overemphasis on "safety".

The community on discord was very helpful though, when I was struggling.

I feel like the community is large enough that you can find a lot of more normal people using it, and just avoid the zealots.


Yeah, the way I sometimes describe this is that Rust social media can be pretty toxic, but the actual Rust community is generally very friendly and supportive. The problem is that a lot of people confuse the two.


I should definitely say, if I'm talking about the "community," I mean real people not anonymous Twitter accounts.


I don't think safety or correctness can be over-emphasized.


I'd say it definitely can, 99% of tasks in programming can be done with a garbage compiler after all.

Different conversation though.


I don't know it's the future. I was writing C and C++ when everyone was yelling that Go would replace them. I am still writing a lot of C and C++ while people yell that Rust will replace it. Chances are when Zig/Nim/Pony becomes the new hotness, I will still be writing a lot of C and C++.

Beyond Rust, Apple has swift, Google is working on "Carbon," and there's a ton of active work on improving the safety of C++. The future is exciting, but there is a lot more than just Rust in it.


College students learning mostly Rust -- that would be a blessing. We would get rid of the typical "every noun is a class" type of thinking that students tend to have going through a Javaducation. We would get them to see the correspondence with structs, procedures and traits and we would get them more often to reach for the simpler solution that way.


"I started out coding in the mid-90s and refocused my career on Bitcoin and crypto in 2016 after leaving a very large software company in Seattle."

You're embarrassed to have worked at Microsoft but not on crypto pyramid schemes?


Hmm.. wonder why Pascal isn't on the list


I professionaly used Delphi in the past for some specific Windows system administration tasks and I still use free pascal as a successor.


Because it’s 2022 not 1982?

There hasn’t been a new Pascal standard in 34 years.


Not sure about the current state of ISO Pascal, at least there's no ISO D or Rust, either. D and Rust are defined by the official implementations.

On the other side, Delphi is still being enhanced and FPC tries to be compatible with it, so there are not stuck in 1982.


I do C#, Go, Python, Node, Ruby, etc., but Free Pascal with Lazarus is my #1 choice for any cross-platform desktop app that needs a decent GUI without using Electron.

It's free, fast (enough), and exceptionally easy. If you need a supported system then even Delphi is back to being (not totally un)reasonably priced once you consider that they only charge when you begin earning from it. Their threshold is very low, but by the time you reach it you've tested your idea and got sales.

As for Pascal standards, I'm not entirely sure why there would need to be a recent one. Standards bodies have their place, but their activity is pretty much never something I ever give a thought to when deciding on software tooling.


I think Pascal implementations are practically dominated by Delphi and FPC these days (FPC has Delphi compatibility mode).

On the other side, there are more players in C/C++ club: GCC, Clang, MSVC, Pelles C, LCC Win32, AMD C++, Intel C++, etc. Having a standard is certainly useful.


Standards can be overrated, sure, but some things like Unicode support really need to be done rihht


It will be interesting to look again once Nim reaches 2.0. And Crystal still requires lots of work on compiler and Windows Support. I just wish it had more resources. Along with Zig. All three of them need more time to mature.


Nim does not have a native ssl and regex lib in the standard library like golang or python. These libraries are taken for granted nowadays.


It doesn't? https://nim-lang.org/docs/re.html and https://nim-lang.org/docs/net.html are part of nim's standard library. Are they missing something you expect?


They are dependent on pcre and openssl respectively unlike Golang which is native.


Well, sure Golang, but to be fair they are not native pure Python in Python's stdlib either...

This is more broadly relevant since part of the appeal of Nim is its easy C/C++ interoperability (by generating to these and so only requiring some declaration).


This comparison looks more like a discourse than anything else IMHO.


biggest con of Nim - no one uses it, so you will probably hit a toolchain/compiler error which will be very frustrating

too similar to Go to not go with the 100x community size Go brings with it


Hey I do, and report bugs which eventually are all getting fixed. Besides me (who's that guy anyway) there are a lot more experienced programmers who have built amazing things with Nim. Arraymancer, a deep learning library comes to mind and fidget which is an UI library, it's remarkable because all it's dependencies were written from scratch in Nim. Not to forget the Ethereum client nimbus and all the other companies using Nim in production. Perhaps give it a shot?


It's far more enjoyable than Go. I use Go at work, Nim at home. A smaller community, of course without Google's backing, but it is growing.


If I recall Nim doesn't even allow tabs. Programming languages should not be overly opinionated in formatting, especially when it requires extra bytes to use spaces.


> Programming languages should not be overly opinionated in formatting

I think gofmt, python black, etc have demonstrated that it's usually better to have a single standard then it is to fight endlessly about these details.


They have demonstrated that some people have interest in controlling formatting.

It would be a stretch to say they demonstrated that it’s better to enforce a standard.

Black, itself, changed rules many times within a 1-year period to the point our own CI would fail on existing code that previously passed.


> CI would fail on existing code that previously passed.

You problem isn’t that black changed formatting rules, your problem is that you didn’t pin CI dependencies. This isn’t a unique problem to black, any other tool used in CI pipelines can cause things to break if you don’t pin them.


Indeed. Something wihout security impact will use pointless resources when you update. Do it rarely (or never if possible).


It's funny you say that, because Go and Python are two of my least favorite languages, partially for reasons of formatting.


I disagree entirely. Ideally there should be one valid way to format your code, and robust tools to make that formatting happen automatically.

Allowing alternatives yields zero benefit and causes pointless debates and diffs.


The benefit is, what if I don't like four spaces as indentation? What if I like two? Why do other get to force their aesthetic preferences on me when there already exists the tab character, whose apparent width is configurable?


> causes pointless debates

yes, having languages establish an immutable standard for tabs vs spaces has clearly ended all debate over them.


But it actually kind of has ended this nonsense in the go community, and to a lesser extent in the rust community.


If it helps, you can configure your text editor of choice to auto-swap tabs for spaces. However, I share your displeasure for the gesture.


Do the extra bytes matter?


Programming languages shouldn't even consider whitespace (except perhaps new lines) syntactically important at all, so the whole discussion is silly. Once you've decided whitespace is important you might as well make emoji part of the syntax.


I disagree: if we make languages have NWS (Non-optional WhiteSpace) then we can easily disambiguate between:

  let traversed-distance := yard-length;
And:

  let traversed-distance := yard - length;
Which is valuable as kebab-case is best case.


Why not? Making identation part of the syntax allows more for less?


You cannot cut and paste freely when indentation matter


Yes ok, but this is not very limiting and doesn't make this approach a ridiculous and failed one to start with, as the OP originally suggested and those languages which do it disprove already?


Because indentation-based languages have very limited formatting they can do. They can't do any indentation formatting.




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

Search: