Learning Rust with Large Language Models: a Project for 2024

January 2, 2024 :: 6 min read

Bespoke tutoring is one of the promises of large language models. Let's see if they can help me learn Rust.

This article is part of a miniseries:

  1. You’re reading it.
  2. Learning Rust with Large Language Models (Part I): an Outdated Manual Written by a Newbie.
  3. Coming later!

There’s a GitHub repo associated with this project.

Rust is a fairly low-level, fast systems programming language. It’s primarily known for its emphasis on memory safety. I tried learning it about five years ago but I didn’t have time to properly commit to it then. So I shortly dropped it.

Nowadays, large language models (LLMs) are all the rage. In my last post, we discussed how LLMs need some killer applications that would prove that there’s more to them than just hype. Bespoke tutoring and coding assistance are among the most promising ones; and definitely marketed as such. So I decided to revisit Rust.. but with a spin. I’m going to learn Rust but using an LLM as my main source of information.

When I say an LLM, I just mean ChatGPT (free or the paid variant). In my experience, it’s still the best among the big models.

Note that last time, I said that machine learning-powered coding assistance tools (e.g. Copilot) are an interesting space. However, for this project, I’m not going to use them. I don’t want to be offered ready-made solutions to problems that I’m working on; I’d rather have this conversational question->answer workflow which is more akin to studying. It makes it so I ask the model for help when I need it, instead of being always on in my editor.

Buckle up.

Fifteen years of code

I’ve been writing code for various purposes for almost fifteen years now. While I have, strong yet totally objective, opinions about all languages that I’ve used, I’m going to spare you this time. Still, to explain why Rust is the most logical choice for this experiment, we need to take a short trip down the memory lane.

Prior to my undergrad, I did a bunch of UI customisation and scripting for Windows; notably, in Rainmeter. I wouldn’t really call it programming but nevertheless, it was my first foray into such things.

My bachelor’s was quite heavy on C/C++. So I used those exclusively for about two years. You could say that I have formal education in C/C++ since all I knew about them was from my classes. Bar occasional debugging of GNU/Linux tools or machine learning libraries, I haven’t used either much after my undergrad though.

In the second half of my undergrad, I got interested in big data and picked up Scala. I self-studied it from various YouTube tutorials, and Coursera courses. Consecutively, it got me my first big boy software job. I’d say I spent about three-ish years with Scala. However, my journey with it ended in 2017/18 when I started working in research. Even though I occasionally needed to write some ETL pipelines in Spark, its Python API became good enough for me to drop Scala entirely.

I started using Python in 2016, when I got involved with machine learning. It’s been my primary $DAY_JOB language since then. Although it never clicked with me, I’ve been using it for most of my personal projects too.

I’ve been writing some Javascript/Typescript here and there with a sprinkle of NodeJS. Mostly for this very website, to debug random page errors, and to interact with some visualisation libraries like D3.js.

And a bunch of other stuff that wasn’t impactful enough to deserve a mention.

Fancy matplotlib documentation

I spend a lot of time working on the security/privacy of LLMs. But admittedly, I haven’t used them all that much to write any code. Not because I haven’t tried but rather due to the mediocre experience.

I use ChatGPT once in a while to help me explore some exotic part of matplotlib instead of browsing through the documentation. The caveat is that I do know exactly what to expect. I’m not sure if at the end of the day it was a net positive experience either. For every handy tip, there were equally many hallucinated functions and options that didn’t exist.

Occasionally, I use it to write some shell scripts. For the life of me, I can never remember the syntax. On top of that, getting relevant results from Google search is getting increasingly difficult day by day. If the second search engine query fails to give me a solution, I might try ChatGPT.

Worth pointing out that both in the case of matplotlib and shell scripting, I resort to ChatGPT once a week at most.

In Autumn 2023 I migrated this website from VueJS to SvelteKit. Sadly, ChatGPT wasn’t helpful at all. It mostly gave me hallucinated APIs and outdated examples. To be fair, that doesn’t surprise me much. Svelte is a fairly new framework compared to e.g. React. So there aren’t many resources online. As a result, there isn’t much training data for a language model.

I’m also entirely aware of the overall bimodal sentiment towards programming with LLMs. On one hand, total replacement of your software engineers (which I mocked in my last post). On the other, something akin to my matplotlib experience — if you know what you’re doing and what you need, the LLM will help you with the fluff. Alas.

A crab
Rust is a powerful systems programming language with a high skill floor. (C)Rustaceans are its semi-official mascots, and the nickname for its community members. Picture source.

Why Rust?

There’re two other main contenders: Go and Swift. What I’m looking for is a systems programming language that I can use for my own tinkering first, and escape the Python hell. Second, it’d be great if it had some use for my professional needs.

Swift is something that I’d like to learn the most. The language vibes well with me. Solid design, the right level of abstraction, chef’s kiss. Unfortunately, it’s difficult to use outside of Apple platforms. Cross-platform Swift and server-side Swift are amazing initiatives that aim to broaden Swift’s adoption. But they aren’t there just yet. This makes it unwieldy both for tinkering and my work. I hope that in the couple of years, I can revisit it. Simultaneously, if I ever need to bust out a MacOS/iOS app, I don’t think I’ll have any trouble doing that.

Go would be my first choice if tinkering was the only criterion. It has a fantastic community around CLI/TUI tools. By design, it’s a great backend language, and it’s the default choice for projects that require more performance than JS/TS offer, and aren’t bound by the corporate chains of C# or Java. Admittedly, I had trouble choosing between Go and Rust. At the end of the day, it comes down to the fact that I don’t need Go for work. Anything that I would use Go for at work today, I can do in Python or TS just fine; not great but fine, and that’s enough for my research-PoC-MVP needs.

Rust has a high tinker score in my book. Lower than Go but high enough. Also, many people (e.g. ThePrimeagen) have been selling it as a great choice for tools with well-defined IO, such a CLI tools. I buy that. Similarly to Swift, I also like its vibe. I look e.g. at the collections API, or the error handling, sweet pattern matching, excellent iterators. My brain gives its nod of approval. I guess it’s a remnant of my Scala times. Then, there are use cases for work. My biggest pet peeve with using Python is that it’s slow. While most machine learning libraries are just Python wrappers around optimised C/C++ code, I also need to write non-computational workloads that must be fast, e.g. parsers. Python certainly doesn’t deliver.

Utility aside, there’s some actual difficulty to learning Rust. Dealing with the borrow checker and lifetimes are common pain points. What I’m trying to say is that I can learn Go and Swift easily without any major hurdles. So if there’s a programming language where I could use some assistance, that would be Rust.

How

Over the years, I’ve figured out what works for me when it comes to learning new tech — a lot of messing around, following some examples, and just diving deep into a simple, albeit concrete, project(s). So I’ve laid out a three-step plan for this Rust experiment.

Part I: basics and messing around. Discovering the syntax and fundamentals. Hello worlds, file reading, collections. Just random stuff. Think of all the drilling or sawing when you get a new tool — if you know, you know.

Part II: Advent of Code till I get tired. Advent of Code is an Advent calendar of short programming challenges. Every day, you get a new algorithmic problem to solve, based around some common theme. While many people do it to hone their existing skills, I think it’s a great way to familiarise yourself with a new language. It forces you to explore the standard library and commonly used tools.

At some point, I will spend more time figuring out how to solve the challenges instead of learning Rust. That will be the time to drop Advent of Code and move on to other stuff.

Part III: actually useful stuff. This is the part where I get to do the things that I wanted to use Rust for in the first place:

  1. Explore some async and threading options for handling web and database calls;
  2. Write a simple CLI/TUI tool;
  3. Figure out how to use PyO3 s.t. I can write efficient Rust and call it from Python.

This list might grow over the following months. Even if it does, it’s unlikely that there will be a standalone part IV. Which means that I’ll wrap up at that point. I’m expecting the finale to land some time in Q3 2024. Maybe Q2 if it isn’t working out at all, and I decide to call it quits early.

What’s next?

To absolutely no one’s surprise, I’ve already started this journey. But I’m not going to spoil anything just yet.

Crucially, I want your input. Do you think Rust was a good choice for this? Do you think my plan/list is missing something crucial? Message me on social media, or send me an email.

You can expect the first update around the end of January. Stay tuned!

More posts.