The Physics, Math and other STEM majors in our classes have a unique set of backgrounds, interests and relationships to the technologies and theories we study. For programming, there is a particular theoretical mindset that meshes well with emerging trends in Computer Science. It deserves a special note we cannot address in our normally mixed classrooms.
The path to programming fluency is different for each person, but there are common paths. The path for math-oriented minds is especially topical. We see a number of once esoteric CS Theory topics like Type Theory and Category Theory become increasingly common in the leading edge of both industry and academic practices. The demands for more complex, performant, reliable and manageable computational systems require a more rigorous approach to software engineering well beyond traditional mainstream software methodologies like OOP Enterprise Java.
Here are my opinions, observations, and recommendations for our math students to efficiently and enjoyably learn programming while avoiding stagnation. This list is optimized for the existing courses presently offered at Kenyon rather than my ideal greenfield recommendations (although the two are not too different):
- Learn a common numerical programming language like R, Mathematica, Stata, etc. which will serve as the easiest gateway into a programming mindset for mathematically- inclined individuals. These are great languages with extensive libraries to construct and visualize statistical models but are often self-limiting when it comes to learning the art of programming.
- Learn a low-level language like C/C++ with a focus on understanding how underlying hardware affects performance, design decisions, data structures, etc. Without a good grasp of underlying realities of hardware, memory, network and other implementation details, your prospects for growth and learning beyond a beginning or even intermediate local maximum are foreclosed. More interesting, demanding and mission-critical applications generally require such knowledge (at least at a supervisory level). These include fields both within academia as well as various fields with similar requirements like FinTech, HealthTech and Silicon Valley startups.
- Learn a general language like Python but go beyond learning the simple 20% that can do 80% of what you’d ever think you’d need by carefully reading the authoritative documentation of the core. Then explore APIs of popular libraries and examples of excellent libraries like Flask.
- Learn a programming language grounded in mathematics like Haskell, which reads like poetry in its elegance and cruft-free expression. Erlang/Elixir is a gentler, programmer-centric way to indirectly learn some of the same underlying concepts shared among functional programming approaches. Intuiting the intimate mappings between: Logic <=> Maths <=> Programming will increasingly be demanded of high-end programmers.
- Special Note: Data Analytics/ML/AI. To a first approximation, this subfield only requires entry level maths, stats, and frameworks like TensorFlow, Keras, and PyTorch. While more math/stat and Python or C/C++ is definitely helpful, the tools are rapidly evolving to be increasingly easy-to-use and automated. The challenge for easy-entree technologies like web dev, data analytics, and ML/AI is acquiring mastery through experience in order to stand out from the crowd. Or, have a non-CS domain of expertise like PolySci, Literature or Art where one can add unique value-add insights.
- Study the many lessons you can learn from a newer, well-designed language like Julia for numerical programming or Rust/Go for Systems Programming. These languages were architected from scratch to explicitly address the shortcoming of their predecessors and embody the wisdom of the brightest minds over many decades. There are many valuable lessons to be learned by diff’ing implementations of common problems between a legacy and new language (e.g. Networking code in C/C++ vs Rust/Go)
- Study popular architectures and practices from a diverse set of fields like React/MobX (Web), ROS (Robotics), Kafka (Messaging) and Apache Spark (High-throughput stream processing) to appreciate both the general commonalities and distinctive particularities of successful software architectures. Seeing how React centralizes and coordinates complex states within a web framework not originally designed to handle such, or how Kafka implements a distributed streaming messaging system, is very helpful. Even if you never directly use them, such tried and tested frameworks will enhance your conceptual vocabulary and provide insights for better designs in whatever language you do use.
- Learn languages that shift your perspective and open your mind to new and better ways to think about programming like Type Driven Development with Idris.
More realistically, do a bit of survey research and settle on 2-3 of the above to focus on during undergrad with an awareness of the larger picture. Like writing, you have to code to learn coding. Thus, the best approach requires:
- A well thought-out plan (like this)
- A disciplined schedule
- Well curated books/courses and knowledgeable mentors
- Repetition (e.g. 100 Days of Code)
- Non-trivial Passion Projects or Topics you are eager to master (AI or Econometrics or Computational Biology). Alternatively, find a concrete, specific and measurable solution to a contemporary issue–for example, how to reduce global warming through more accurate modeling of energy and waste flows
- Find as large a community of sharp, enthusiastic and focused individuals to connect to and network with.
To make things concrete and tractable, my first two recommendations would be to learn Python beyond whatever level you are at now and then learn a complimentary language like Haskell that provides a more formal and rigorous foundation to computational thinking. These two languages are virtually non-overlapping in many important regards and can very efficiently provide you quick insight into (a) efficient, practical and real-world programming across a wide range of domains/applications and (b) a minimalist, rigorous and well-regarded vehicle to discipline your mind in the methods computational thinking.
Here are my summer Python recommendations. And here are two specific books I’m recommending to learn Haskell this summer. I’ve seen presentations by at least one of the authors and he appears to be an excellent instructor. These are more math-oriented than some more popular introductions to Haskell written for programmers, so choose whichever suits your style.
- Programming in Haskell, 2nd ed., Graham Hutton
- The Haskell Road to Logic, Maths and Programming, 2nd ed., Kees Doets & Jan van Eijck
- With many more free resources on the Intertubes
Disclaimer: I am by no means an expert in all these programming languages, but I have cycled through most of these to some degree or other. I am fascinated by the different paradigms of encoding thought, mathematical models and structuring thought. Over the decades, my curiosity has increasingly trended towards the mathematical, abstract and what I see as the only solution to complex problems and all the challenges that they bring. I’ve tried to deliberately winnow my course content and the recommendations above to what I see as a strategic response to the long-term trends I expect to unfold over the next 20+ years.