---
title: "My Advice for Programming and ML"
source: "https://x.com/jsuarez/article/1943692968013025457"
author:
  - "Joseph Suarez (@jsuarez)"
published: 2025-07-11
created: 2026-05-14
description: "This article is a prequel to my opinionated reinforcement learning guide. It exists because people have asked me for it repeatedly. Start he..."
tags:
  - "clippings"
type: clipping
area: clippings
status: completed
topic:
  - Machine Learning
  - Career
rating: 5
date: 2026-05-14
updated: 2026-05-14
---
![Image](https://pbs.twimg.com/media/Gvlh3rmXYAA-6nv?format=jpg&name=large)

This article is a prequel to my opinionated reinforcement learning guide. It exists because people have asked me for it repeatedly. Start here if you a) do not know how to program b) don't know ML or c) started reading the main article and were confused (see a/b).

## How to Learn to Program

Having a PhD in AI does not mean you know how to code. Having access to an LLM also does not mean you know how to code. Thinking that either of these do is probably a negative signal in general. Being a good programmer is harder than being good at AI, and every good programmer who has started doing RL with us has done very well. Most of programming is very simple. Simple does not mean easy. The thing that makes programming hard is that it is often terribly taught in a way that trains you to over-complicate everything. Unlearning this takes either years of failure and pain or a particularly open mind that your entire outlook on how to program could be stupid and wrong. If you are brand new to programming, you have an advantage here. If you are not new but are reading this anyways, I invite you to make this decision now.

Programming is the act of writing down instructions that operate on data. The list of instructions is relatively short: you can create variables by assigning data to addresses in memory, evaluate conditions on variables, loop over conditions to run the same set of instructions many times, and group instructions together into functions. You can learn the tools of the trade within a few hours, but applying them effectively is the pursuit of a lifetime. Skill in programming is not logarithmic. A bad programmer creates problems. A good programmer solves problems. A great programmer can change the world with nothing more than a laptop. Enough philosophy. Here are my top 10 suggestions:

**Learn by doing.** Start with something that will take you a few hours. Build up to something that will take you a few days. Simple games are great because you get quick, visual feedback for most problems. I'd suggest using raylib for rendering. It's light-weight, available in nearly every language, and the library itself is a great example of well-designed software.

**Start with Python.** A lot of experienced devs hate Python. I sometimes hate Python too. You should start with Python anyways because it will let you get started faster than almost anything else. Most AI projects you encounter will have at least the top layer written in it. But don't spend too long in Python. The design of a language pushes you towards a specific way of thinking about problems. Avoid heavy external packages, inheritance, decorators, and generally anything else that takes you away from learning to express logic in terms of assignments, conditions, iteration, and functions. Write a couple basic games, applications, or tools and move on. Use uv for package management.

**Learn C Early.** C is a wonderfully simple language for writing high-performance software. The only reason I don't suggest learning C first is that it requires you to learn a bit more about how computers and operating systems work, which is too much all at once when you're new. A short list of concepts that you should understand: types, type casts, structs, (single-pass) compilation, linking, memory allocation, stack vs. heap, pointers. Avoid C++ for now. It's C with a ton of extra stuff bolted on that you mostly don't need.

**Avoid Abstraction.** Always aim to solve the problem at hand in the simplest way possible. Do not introduce complexity for the sake of generality unless you know for sure that the eventuality you are planning for will actually arise. And even then, it is often better to beat that horse when it arrives. C is great for this because it takes away most of those tempting, self-defeating tools like inheritance and heavy third-party libraries.

**Use Git.** This one is so basic that I almost forgot to include it. Make new projects on GitHub by default and commit frequently. This is the best way to avoid losing work. It also gives you a version history for when you inevitably break something that used to work. ~All open source projects are run through GitHub.

**Use a Debugger.** A debugger allows you to run your code line by line and inspect the values of local variables. It is dramatically faster and more flexible than littering your code with print statements and allows you to jump around quickly. Pdb for Python or gdb for C will suffice. Use an address sanitizer for C. This will give you readable error messages and is so important that I would not suggest C without one.

**Learn Basic Unix Tooling.** Get comfortable with the command line asap. You don't need to be fancy here. Basic commands like ls, pwd, cat, head, mv, cp, cd, mkdir, top, etc. You will only need the ~10 most common tools ~90% of the time. Ideally use native Linux if you can. MacOS is okay. Windows is not - use WSL if you do not want to dual boot. I'd suggest a basic Ubuntu install. Do not go ham customizing everything. Get comfortable with your distro's package manager, which is probably going to be apt. Not snap.

**Don't Get Nerd Sniped.** Programmers love inventing clever ways to do things worse and waste your time. Especially when you're new, avoid: object oriented and functional programming (they're both dogmas), test-driven development (writing a few tests is fine), language and distro hopping, industry "best practices" (there are plenty of terrible FAANG engineers), Python's type hint system, make/cmake in C, fancy config parsers like Hydra, GitHub submodules and fancy CI, modern web development frameworks like React (learning basic HTML + CSS is a good idea), ricing, the latest new programming trend on X, and everything else I rant about on my dev livestreams.

**Don't Grind LeetCode to Learn.** It can be a necessary evil for job interviews, but solving tricky problems with clever algorithms really isn't a good representation of programming as a whole. You should absolutely learn basic data structures and algorithms, but mastering 10 flavors of dynamic programming isn't going to be as useful outside of interviews as building more projects. I haven't taken a programming interview in years, but I'm certain 18 year old me would do better than 28 year old me. 28 year old me is better in every other way.

**Don't Worry too Much About IDEs.** It really doesn't matter that much. I use NeoVim with a grand total of two plugins. It's light-weight and stays out of my way. Yes, I have used plenty of IDEs. No, it doesn't matter. VSCode is fine, just run stuff through the terminal instead of project configurations and buttons. This will break the illusion that the IDE is a magical required tool. Do not use an AI-first editor. Once you have learned the basics on your own, a code complete tool like copilot or SuperMaven is fine. But use it to save typing and documentation lookups, not thinking.

## How to Learn ML

Becoming an effective researcher is actually easier than becoming a good programmer. Most researchers are very bad programmers. Good programmers have a much easier time becoming good researchers than bad programmers. I became a good researcher before I became a good programmer. I wish I had put more time into becoming a good programmer first.

Unlike in general programming, the resources available for ML are actually pretty good. Stanford's CS231n lectures are available for free online. Watch the ones by Andrej Karpathy or Justin Johnson. Also, actually do the problem sets. This is mandatory. Look, I do not like most courses. This one is good. It is designed to teach you things without being particularly challenging. You need to know what a partial derivative is, what a matrix is, and that's about it. Don't worry if you haven't seen a derivative applied to a matrix expression before. It's the same as applying it to a single variable except that sometimes you transpose the matrix. It's really not any harder than that.

Once you have completed CS231n, you will understand how autograd works (because you built one) and be comfortable with PyTorch (because you'll have used it to to build other things). Congratulations, you're out of useful course material. The next step is to start reading academic papers on ArXiv. Interested in a specific area of AI? Search around for a list of the most important papers and read them. This will be overwhelming at first, but it will get easier over time. I've provided you a list for reinforcement learning in the main article above. My best general advice all revolves around understanding limitations of the scientific process. I've been very intentional with my wording. Reread these three paragraphs periodically until you see for yourself where they came from.

**Understand how Science is Done.** You can't understand papers without understanding the circumstances under which they are written. Most conferences enforce an 8-9 page limit. Since most ArXiv papers are also either published or were intended for publication, you'll notice that they are also 8-9 pages. Why not shorter even for simple ideas? Because that is both an upper and lower limit. Writing a 6-page paper will normally get you rejected. Why do so many papers have excessively formalized math even when it's not relevant or helpful? Because reviewers like to see formulas (also some researchers just like writing them). Why is the paper missing X obvious ablation or control experiment? Because the overworked grad student who wrote it ran out of time and GPUs (mostly GPUs). Why aren't there more papers in X area? Reviewers don't like those. Oh, also, plenty of papers are just wrong, so when two papers appear to have directly contradictory results, that's because they probably are!

**Don't Trust Prestige.** You should care about my opinion based on what I've provably built. I use my academic credentials because unfortunately that's what a lot of people look at. So I'm perfectly positioned to tell you not to trust papers from X conference or Y university by default. It's a weak signal at best, and I've been burned replicating bogus results from people who should absolutely know better. While less common, people do sometimes straight up lie to get their work published. More often, it's a combination of noisy experiments and wishful thinking induced by 6 months of long hours at the lab. The best indicator that a work is correct is open-source code with multiple independent replications and usage in follow-up work. But this still isn't a perfect signal, and I've been burned here too. Replicating the results of papers is a great way to learn, but know that this can take months. But you should absolutely implement some of the more basic papers when learning a new area!

**Look for Errors.** Assume publications are wrong by default and find the skeletons in the closet. Are the experiments poorly controlled? Are the baselines too weak? Is the reasoning provided the only plausible explanation for the results? Work to decouple the content of the paper from its usually over-complicated presentation. To the extent that the paper is correct, how does it fit in with surrounding works? Building intuition is a combination of validating claims and pattern matching. You can think of this as estimating the probability that a specific direction or method is worth your time. The greatest opportunities arise when all the papers in a specific area are making the same error. This usually happens when the premise of a topic or the standard evaluations are fundamentally flawed. Great researchers can pierce the veil of collective myopia to strike out in new directions.