I think it's a good place to start with memory management issues because you have to deal with it but good practice is enforced. C/C++ is the obvious alternative for that level of programming, but it's less constrained, which is better in some ways but bad in others. If you're wanting to learn Rust eventually, you might as well start there.
If you're wanting to not start with the low-level memory management stuff, and want an introduction to programming per se, there's lots of options.
One thing to think about is OCaml. It's a nice language, similar to Rust in some regards, and in fact Rust was originally written at least partially in OCaml, and for awhile was kind of discussed as a derivative of OCaml in some places. You'll get a mixed imperative-functional kind of introduction without going to quite as low of a level.
Another approach is to to just learn a language. In that case I'd probably recommend Python (probably Python 3) or javascript, because there will be a ton of resources and the skills will directly transfer. If you're looking for something that's maybe more niche but "clean" you could try Julia or Nim. Julia's very numerics focused and is getting used in that area, but doesn't get used out of that, at least so far. Nim is very very niche but a good language, similar to Python but faster and cleaner and some ways. Another thing to think about is Scala, which might transfer to Rust in some ways better than the others (except OCaml).
Honestly, though, I might just start with Rust. It will be heavy going at first, but I think learning the memory stuff is very very useful later. It depends, though. I think you have lots of good options. What's most important is to just dive into something that's interesting to you and start creating stuff, regardless of how small it is. A lot of concepts will transfer across languages.
Programming languages will feel a bit foreign since there are different paradigms involved, but you have a solid perspective to start with.
Since you know bash, you know the environment your programs will run in. Start by learning simple IO with stdin, stdout, and stderr. The rest is basically just different methods to organize your code.
I don't mean to diminish what I'm sure is your extremely proficient grasp of bash; rather I mean to diminish the way you presented it. If you're an expert, you know it without being told.
Then try a statically compiled language like F#, C#, OCaml, or Kotlin, depending on what kind of platform you like.
Then try a lower level language like C, Ada or Rust.
There are of course completely different paths you could also take, like tossing Prolog or Haskell in there somewhere, but the above path will cover the basics of what's most widely used in industry, ie. functional, imperative and OO paradigms, curly brace syntax vs indentation based syntax, the common control flow abstractions, statement oriented vs expression oriented languages, and statically and dynamically typed languages.
C++ is an archaeological dig of a language, which has about 4 major strata. It can be an entirely different language project to project, depending on how you use it. However, I suspect that a particular C++ style using smart pointers and RAII can be a good preparation for Rust. This is especially true if you can contrast that C++ style with some other woolier style of C programming.
If you want to be very knowledgeable, 1) write a compiler that produces machine code and 2) do some concurrency.
What's most important is to just dive into something that's interesting to you and start creating stuff, regardless of how small it is. A lot of concepts will transfer across languages.
The best advice by far.
This should be the canonical way to describe it. Brilliant.
This is THE reason that I don't recommend C++ as a stepping stone language. If you need it use it, no hate, but it can make using online resources a mishmash of guesswork until you grok the history of the strata.
In my experience, particular theory as in CS papers isn't needed for learning Rust. Understanding the runtime stack, RAII from C++ and malloc/free from C helps, but if you haven't already programmed in C and C++, it doesn't make sense to learn them in order to learn Rust. Any introductionary lecture on how the runtime stack works combined with the abstact idea of pointers to heap should be enough (no need to know how heap allocation works in detail).
Given how often it seems to be used to perpetuate dubious claims about Esperanto's almost-magical benefits, I'll need to find some time to completely rewrite that Wikipedia article. For now I'll just link to a review of one of the studies I wrote up a while ago: https://news.ycombinator.com/item?id=14848019
I was able to find the article "What About a Simple Language? Analyzing the Difficulties in Learning to Program" by Mannila, et al., which found that first time programmers found it easier to write bug-free programs in Python than Java and subsequently had a lot less trouble with the details of Java after learning Python, as they did not have to use the mental bandwidth to learn the most basic concepts of programming while also learning static typing and the incantations required to use Java.
However, after getting to the point of feeling “I can do this programming thing”, I don't think Python provides any specific help for learning Rust more efficiently than learning a given thing in Rust directly.
General problem solving, the vernacular and methodology of programming (what's a variable, a function, control structures, how is a program run, what are expressions and statements, etc.), and finally the actual language itself.
The first two are universal across languages, but the third is very different depending on what you pick. A language like Python makes that part much simpler than a language like Rust. There's fewer hoops to jump through, less to keep track of, and you can dive in applying your newfound knowledge of the first two topics.
(Rust doesn't even have linear types, btw)
You can learn all that from Rust, but it is possible you will have a better understanding of the design decisions if you have first experienced writing a C program and having it crash due to some memory management issue.
Thank you.
I would say start straight with Rust. Maybe you will find that it is not what you wanted/expected, and decide that another language will work better for you.
If you do like it and think it’s what you were looking for, you can always go back and read theory, other languages.
Despite its hype, Rust is no silver bullet(lots of unsafe calls in all libraries, mem leaks are still possible, etc..), so give it a go first and see if it’s indeed your cup of tea.
Go ahead and start learning all of the languages you are interested in. At the same time.
There isn't that much information to remember. Each language has simple grammar and only a dozen or two words.
The subtle differences between languages give context to each other.
If knowing something is going to help you with Rust, then it will help you even more in parallel when you've gained some entry-level experience with Rust.
[1] https://doc.rust-lang.org/book/second-edition/index.html
The primary reason to learn it first is to focus on manual memory management. You could also just delve into C, but I still recommend just beginning with rust and skipping the cruft.
It's an archaeological dig of a language, representing something like 4 major strata. Archaeological digs have pits. The way to learn C++ is to limit scope and learn a particular style of C++.
What's your application for high performance?
FYI, I still do utilize heap allocated objects via STL & framework objects, I just leave all heap memory management to wheels I don't invent in house.
I'm not aware of a Rust from First Principles book or whether Rust is based on an underlying denotational or formal semantics.
However a good bet is mathematics. And you'd be best served by the typed lambda calculus, predicate calculus, and type theory. If there's one thing I've lamented it was missing out on learning early on in my career it was how to structure computer programs as mathematical objects. I've spent much of my life using the wrong metaphors.
My 2 cents: start shallow. The hard part of learning the right stuff from a language is picking a project that let's you run into those aha moments. I like to cut my teeth on a basic Sudoku solver and maybe a small web service for the younger languages. I picked two languages that are relatively simple to pick up, let you get to the meat quickly, and are popular and familiar.
If you don't get pointers yet, learn C. Something with arrays of arrays can be good here.
If you want a taste of some functional idioms without feeling drowned by them, learn Python. Use list comprehensions and filter and reduce a lot to warm up with them.
You can get exposed to a lot of paradigms in Python without committing to anything. Classes/oop, first class functions etc.
C++ is harder than those two because the learning resources are less consistent. Too many idioms have changed over and the last decade.
I think jumping straight into rust after that won't be quite so intimidating. Rust itself has a lot of new things to think about but some are unique enough that there's no good warmup language.
I don't think you need an undergraduate degree to understand the un-typed lambda calculus. You can build an intuition for it with syntactic substitution at first. For such a big idea it's really quite simple in practice. That makes it quite beautiful.
Moving to the typed lambda calculus is the next step and builds upon the prior knowledge.
The reason I think it's useful is that it allows you to reason about abstractions -- even complicated ones -- in a manner that reduces the cognitive burden on us. It's also not tied to any single programming language: they can all be modeled with mathematics. Proofs are programs and programs are proofs.
I do agree that a hefty does of practical application helps to solidify theoretical understanding. I see them as informing one another.
If one needs cyclic data structures in Rust, the existing theory of functional data structures is a great model for how to solve such problems. Persistent and reference-count-friendly data structures are brothers from different mothers. Haskell enforces pure functionality. Then one can relax and use Rust, and its arcane features will actually come as a relief.
- working in ASM forces you to really learn the memory model, even moreso than C
- LC3 is a lot simpler than any real assembly so you'll learn it faster
- LC3 was made for students of programming and has documentation that assumes you're not too familiar with CS already
I don't recall which part of the course best covered ideas around scopes and their contents that will come up when you start thinking about memory in rust.. but it definitely wouldn't hurt to do all 3 languages.
If you just want low level acces to hardware it might be easier and more useful to learn C/C++. Easier concepts to grasp, more readable syntax and 1000x more avaible resources to learn or libraries to use.
Don't worry about the borrow checker, liberally apply .clone() every time it complains. Don't try and golf your initial designs. Lots of vec, .clone() and structs that own their contents.
Unfortunate name though.
I'm personally not a fan of the bang! operator for macros, and the ' lifetime symbol choice. Might seem minor but they just leap out at me for some reason as irritating syntax choices.
Pun unintended?
Rust is like Bitcoin, everybody talk about it, but no one really use it.