Programming Help

Hi, I present to you a translation of the article "Advice for programming students".

There are many things I wish I had known when I started my journey as a programming student. It's been almost 10 years since then, and unfortunately I can't share my experience and knowledge with my past self, only with my younger colleagues. This post consists of some helpful tips that I wish I had heard when I was 18 years old.

Decide what you need.

You certainly don't need to be familiar with formal logic or categories if you just want to learn how to create something practical (say, an interface) and do just that. There are two basic paths that differ in effort, duration, and outcome.

You can master one area quickly - say in one or two years. You won't be useless, you'll be doing something and making a living. There are enough job opportunities (at least for now) that don't require much flexibility.
You can become a well-established professional who has spent a lot of time and effort on fundamental things. Then you can adapt, switching career paths becomes relatively easy. You can do machine learning, then formal verification, then some low-level programming for trading or move into game dev. It takes time and dedication - I would estimate this process at least 6-8 years.

I strongly favor the second path because it's more versatile, interesting, and brings more in the long run. Technology is constantly changing, so you'll want to switch to new technologies quickly.

Math

Study math because math is useful. I can't stress this enough. When you start, you may think you don't need linear algebra because you don't know about applications. However, for any non-trivial machine learning, you will need it. You need statistics and probability. You'll need logic, combinatorics, set theory, all kinds of discrete mathematics, graph theory, computability theory, formal grammars, lambda calculus, formal semantics, topology, type theories, number theory, groups, rings, fields, categories.

New technologies are constantly emerging. Many of them are based on existing mathematical models. If you know basic mathematics well, you get very nice advantages:

  • Choosing among the newfangled technologies will be an order of magnitude easier.
  • You will understand where you should and should not use new methods.
  • You will understand why the solutions are the way they are. Then you will be able to modify them so that they better fit the context.

For example, my impression is that few people understand why you shouldn't always use the least squares method to estimate how well your linear regression fits the data. This will be required when the errors are normally distributed with an appropriate mean. If they are not, you will blindly apply an inadequate solution without even thinking that part of the model needs adjusting.

Study math to learn how to think mathematically. Writing proofs makes you rigorous about your actions. You will always be thinking about all the possible execution paths your program can take so that you don't introduce errors and security problems. The clarity of thought gained from building proofs is precious. It will also help you write short, concise code.

Learn from the best, use the best tools

Choose your first language. It should be well-designed, that is, have:

  • Consistency.
  • A small core.

Lack of unnecessary complexity (e.g., when learning a "complex" language, there are things you should just know about or constantly remember, they do not bring anything useful to learning).
Little chance of "shooting yourself in the foot."
High-level, because programming is about solving problems and problems, not mastery of any language. Knowing all the little features of your favorite language doesn't mean you're perfect at programming.
 

My advice is to choose one of the following languages:

  • Scheme (there's an excellent classic introductory course, Structure and Interpretation of Computer Programs).
  • Smalltalk
  • Eiffel
  • ML

Do not be fooled by the perceived unpopularity of these languages, in the programming world popularity does not mean quality.

Don't start with Python, please! It is poorly designed, inconsistent and will not teach you rigorous thinking. You don't have to get used to the "well, usually works" mentality. Python has its uses, but not as a first language.

If you get used to shoddy languages and shoddy tools and shoddy software and shoddy solutions, you will inevitably repeat them in your own work. Be critical, ask questions, criticize everything, look for inconsistencies and flaws.

For example, imagine that you are learning a new Go language. Google "Go language sucks" and read why people criticize it. Some of the comments will be minor, but others will really make sense. You'll probably gain new insights from reading the criticisms, evaluating them to determine later if they matter, or if they're just empty words.

Think for yourself.

I have been teaching programming (C and assembler) since 2009 to the students of the ITMO University in St. Petersburg. Many people have problems with programming and never manage to learn it because they do not create code. When they get a task, they try to imitate an existing solution, perhaps taking some fragments from Stack Overflow, customizing it to their liking. Okay, got the solution, what more do you need?

You have to learn how to write code from scratch. The types of skills needed to do this are so different from the skills gained by tampering with existing code!

Programming means making conscious choices. You are in state A (you have access to a number of language functions/libraries and know how to combine them); you want state B (language constructs combined to solve the problem). How do you build a route from A to B? Now this is real programming, problem solving.

When you start writing programs from scratch it gets a little hard, but it's absolutely essential to learn how to build things from scratch. To improve your problem solving skills, it's important to learn algorithms and data structures. Get a good book and solve the olympiad problems online. I recommend Dasgupta's Algorithms for starters, then Cormen's classic book. All of these will open up a whole new world for you, I promise.

An additional part of the software creation process is developing software architecture; you can't learn how to structure your programs properly without creating them from 0 to 100.

Broaden your horizons.

Program every day, do side projects all the time. This is a very simple (and mostly accurate) way for me as a teacher to know that my student is very likely to succeed. One question: what do you program in your spare time?

Your teachers simply don't have enough time to tell you everything. After all, after you get out of university, you have to keep learning on your own until you retire. If you are passionate about what you do, you will learn different types of software for fun, and it will give you much more experience and skills than your less motivated peers.

Ideally you should try everything: write your own compiler, maybe a toy OS, http server, database engine, games, raycasting, create some neural networks, write a simple mobile app, write a program for embedded ..., you can go on. Put all your projects on GitHub and be proud of them: a future employer can take a look at it. Use this portfolio to your advantage.

It is well known that recruiting a good programmer is extremely difficult. Many programmers applying for jobs have trouble writing trivial things like FizzBuzz. If you have existing projects posted on GitHub, the employer will be more confident that you're a good fit.

Challenge yourself with different tools and languages. If someone tells you that all languages are similar, that's either a simplification or lack of experience. Let me explain a little bit.

A computing model is a set consisting of basic operations and ways to glue them together into the order needed to create complex algorithms. Some languages have very similar models of computation, and some are very different.

Programming is much more than the commonly known C / Python / Java / C++ / C# / Go / Javascript, built on the same principles: imperative, structural, a bit with OOP and syntactic sugar to mimic other programming styles. The programming world is HUGE. How about:

  1. Industrial functional programming languages with complex and elaborate type systems (Haskell, Ocaml).
  2. Functional languages with dependent types that allow not only programming but also writing proofs (Coq, Agda, LEAN).
  3. Concatenative languages (Forth).
  4. Logical programming (Prolog, Refal).
  5. Finite automata (regular expressions, Promela).
  6. Highly extensible languages, allowing the implementation of virtually any syntactic constructions, such as Lisp, Forth, Camlp4/5, Rebol.
  7. Subject-oriented languages (JetBrains MPS, XText).

Each new computing model is difficult to understand because it is a new way of thinking. But it is worth the effort and time spent.