Learning new programming languages with limited time: Rust, golang, or otherwise?
I want to learn a new language that I can use for personal projects. But I want to pick the right one for me, given the fact that learning it will be a time investment and I don't have a ton of time for "fun" stuff these days.
I've spent a decent amount of time tinkering around with Rust and my experience has been decent so far, if I'm trying to filter it through the lens of the current Rust craze. It just seems that the code has a somewhat... ugly(?)... aesthetic to it? I'm not willing to cast it aside yet and I think the "ugliness" just comes from me not really recognizing the syntax very well.
I started looking at golang and was immediately interested in the marketing message of it being "a better C". Aside from Hello World, I haven't done anything else with it.
Some random notes/points about my experience and what I'm looking for:
- I am very accomplished with PHP, quite accomplished with C, somewhat accomplished with C++ and Python. Of those, I find Python to be too "free and easy", PHP (Symfony specifically) and C++ to be so OOP-oriented that I just end up writing a bunch of boilerplate, and C is just... C (I'd rather pull out a tooth than have to work with C strings).
- Aside from the obvious pains of C, I think it's the most fun of the bunch. I don't know why I think this, because again, I absolutely hate C strings.
- I appreciate the package management and ecosystem of Rust, from what I've seen. C-with-Cargo would be awesome.
- The older I get, the more I appreciate strong typing.
- I like a language that allows me to systematically and logically organize my code into various modules, directories, etc. This is where PHP/Symfony shines in that there's a place for everything, as opposed to a bunch of .c and .h files all dumped into a folder.
- Ideally, I'd like something that can compile into a binary that doesn't require JVM, etc.
I'm open to suggestions outside of Rust and Go... those are just the ones I've been seeing mentioned the most over the past decade.
Rust is like if python and C had a baby who grew up to be a genius. I have nothing bad to say about the language except having to wrap everything in Ok(). It has the most informative error messages I have ever seen.
I have not used go, so no comment there.
Rust has a very high barrier to entry, which IMO accidentally ends up being a strong filter for more motivated and smarter programmers. Understanding how to appease the borrow checker takes a while.
I will caution that I’ve heard many terrible things about async/await Rust code. That's not a big issue as you can use threads/channels instead to write more go-like code.
The error handling in the language and compiler are both great. There’s a bit of ecosystem divide on how to unify error types across libraries. There’s no inheritance so you can’t get help from the existence of a root Exception class. It’s a solvable problem but the stdlib only provides the container, Err/Ok. This means there are competing 3rd party solutions for anything beyond that like getting the “message” from an arbitrary error, attaching related errors, or just allocating stack space that could belong to one of your errors, or one of many different library’s errors.
But besides that aspect after using Rust’s unions and the ? operator you’ll be glad to see exceptions removed. Why did we ever have a completely separate control flow pattern for errors?
I’ve been considering learning Rust, and I keep hearing this. I’m curious as to why people think that - did Rust just kinda rush an implementation of it? Would love to hear what anyone might have to say about that.
It did not feel rushed. It took years. Recently I've heard that one major issue is that Rust's equivalent of a destructor (a
Drop
implementation) can not execute async code. But that means you need to manually insert those types of tear-down functions into your code just before structs managing async resources would be dropped.Syntactically they did have a major win by making
await
a postfix operator.It's funny, I've been observing Rust casually for years and vaguely wanting to learn it, although I haven't had time or reason yet. So I remember all of that back and forth about async and am keeping up with the work on the Polonius update for the borrow checker, but I don't see these day-to-day pain points.
Given what I know about the language, it definitely makes sense that that would be an issue. Thank you for sharing! Maybe I'll finally go give Rust a try one of these days and see for myself.
I'm in the progress of learning Rust and the free Rust book (it's usually called "the Rust book") is so awesome. It's definitely meant for (somewhat) experienced programmers. Brown university has an experiment going that tries to make it even better with quizzes, some more text and some tools visualising borrows etc. Very enjoyable.
https://rust-book.cs.brown.edu/
That's part of what was driving me so crazy, and I'm sure it's because I wasn't using Results properly. I vaguely remember being forced to handle an Sqlite exception and having to Google around until I could find the proper way to handle it. I didn't think the Rust book was very helpful in that particular section.
If could find a good primer on the RIGHT way to handle errors, I'm sure that would go a long way for me.
Yeah I find that good rust resources are hard to come by. There are a couple of O'Reily books about it that might be worth checking out.
Here is also a vid that was useful to me: https://www.youtube.com/watch?v=s5S2Ed5T-dc
If a message "A better C" interests you, you should check out Zig. It aims to be a modern take on C that also plays very well with existing C libraries.
I haven't used it myself. When I was checking it out it was still a immature and people warned me back then that it would be very hard to learn it of you don't already know C, which I don't. I plan to return to it someday though.
Zig also makes for a good C compiler, it's amazing how much better it was for cross compiling stuff compared to ACTUAL C compilers...
I've been learning it the last few weeks and I do like it. The comptime metaprogramming and safety checks are very nice.
It does not attempt to be a safe language in the same way Rust does, but it does try to make it easier to write safe programs. Sophisticated compile-time metaprogramming and checks. There is a builtin testing framework with memory leak detection. In debug modes in detects use-after-free and double-free with very helpful error messages (eg memory was allocated here, freed here, and freed a second time here).
Generally I like this better than my experience with Rust. If I have some construction I know is safe I can just write it without fighting a borrow checker, and the language gives me tools to help verify its safety.
Something else that's very nice - the language is very small, and very consistent. It's been very easy to get started, in stark contrast to my experience with Rust.
Tooling isn't amazing but it's getting there. ZLS master branch has some recent improvements. There's a general theme that for a good experience you need to be on Zig master, but then your standard library is in flux which is tricky to deal with. Most changes lately deal with the build system and package manager. The language is not mature in the same way as C/C++ or even, but to a lesser extent, Rust.
I've played with both Rust and Go, and while I bounced off Rust after giving it maybe a month or two (I just could not figure out how to represent certain structures in a way that would appease the borrow checker), I was almost immediately able to be productive in Go and was able to port a CHIP-8 emulator I wrote while I was learning it.
Go is definitely very boilerplate-heavy in the form of its error handling, lots of
peppering the code, but I don't personally mind it much. It's opinionated, and its opinions often align with mine. Go also heavily encourages organizing your code, without prescribing a strict way to do it. I often hear people say to split out code into functions and modules as they develop organically, there's no default template/framework for it. You're encouraged to create a place for everything, but what that place is is up to you to decide.
I hate the complexity and syntax of rust. It's ugly and cumbersome. But, it's an awesome language for speed and anything systems level.
Anything outside of systems level, and I think it's just too much with far too much boilerplate.
I would suggest Julia, Go, or if you really want to get experimental: Mojo. It has the ability to run any python module or package, but with a multiple 1000x speedup. It's new, but built by some of the best programming language designers out there. Mojo is also compiled.
Elixir if you want something very different but really cool. But that runs on the ErlangVM and doesn't exactly compile down in the same way as most languages.
I want to give a +1 for Erlang/Elixir, despite having very little experience with it so far. The story itself of how the language came to be is compelling, and it speaks to the capacity of the language to do its thing really well - "write once, run forever"
Do you think Mojo would have applications outside of AI, which seems to be what it's mostly advertised for, and preferably in web dev?
Python is my first and main language but I really want something strongly typed and performant now. I was set on giving Go a serious go but if Mojo has the potential to be used in meaningful capacity outside of AI as well, I'd love to embrace a strongly typed and crazy performant Python!
They are trying to commercialize Mojo before open-sourcing it iiuc. That makes it an absolute no-go for me.
They have promised to eventually open-source the compiler, but who uses closed-source programming languages in {{current_year}}?
Edit: Yes I know about Mathematica. The mathematicians can do whatever they want I suppose.
Edit 2: Happy to be corrected if I'm wrong about any of this.
Sadly, I feel like I'm kind of in the same boat. I want to learn something new, but can't decide where to focus my efforts. My list consists of the following, in no particular order:
Out of curiosity, have you heard of or hold any opinions about V?
I’m finding Deno (TypeScript) to be pretty fun. TypeScript’s types are advanced enough that you can go too far and get complicated error messages, but there are libraries like Zod that do some pretty advanced things with it. JavaScript has inconsistent performance depending on how well the JIT works, but it’s faster than the Python interpreter and plenty fast enough for what I’m doing.
I like Go, but at times it’s more low-level than I care for. I’d rather work with lists than slices and arrays, even though it’s not as efficient.
Another advantage is that the API’s that make it into browsers (and are also in Deno) are usually pretty easy to use.
I think if you know how to write good C++ and understand RAII you'll pick up Rust's borrow checker and lifetimes pretty fast.
Of course if you can write good C++ you might find wrestling with the borrow checker tiresome anyways... ;)
You could try Julia :
++ Somewhat different paradigm with multiple dispatch, something new to learn compared to other language
++ Package/environment manager (you can organize your code into packages and even have a local package registry)
++ Interactivity (REPL is super good)
++ Fun and easy (to some extend)
-- Limited compilation capabilities at the moment
-- Lack of libraries outside of scientific computing
I absolutely adore Julia. I tend to prototype all my code in Javascript (even systems modules!) before moving it to Rust or Elixir (or more recently MOJO).
But, Julia writes with ease like JS, and is incredibly powerful, fast, and so nice. The REPL is one of the best I've used.
Seriously, check out Julia.
Dart satisfies all of your requirements. As a plus, you could dabble in writing apps with Flutter.
I don’t have any recommendations to offer, but wanted to say I know exactly what you mean about Rust looking “ugly”. As someone who’s usually writing Swift or Kotlin, to analogize with cars Rust feels like a big boxy truck with visible bolts and rivets whereas Swift and similar feel more like sporty coupes designed with flowing lines. It reminds me of C++ that’s trying to maximize use of bells and whistles with the friction I feel when trying to scan/read it.
This all likely improves once one has read/written a sufficient amount but from an outsider’s perspective it feels like a bit of a bear.
I do mostly web application development, which usually kicks off asynchronous transactions in a microservices-based architecture, so Go was the obvious choice for us. There are some things that annoy me about it, like variable capitalization determining public or private scope, but it's efficient and has a lot built into the base language. I don't think that the public module community is very strong. There are a ton of widely used but abandoned projects out there.
I've wanted to learn Rust, but it seems like it's not the best choice for web applications. Not that it's incapable, that's just not it's forte.