Ask HN: Programming Courses for Experienced Coders?
Lately I've been learning Elixir. Many of the popular resources seem beginner-focused, which feels a bit tedious when you've been coding for over a decade. Are there any popular programming books or courses for more experienced coders?
191 comments
[ 3.0 ms ] story [ 220 ms ] threadInformally I just tend to write tight modules that loosely adhere to hexagonal architecture and are easy to unit-test.
I'm at a startup that is hiring, btw (I would be the one to reach out to). Seeking someone that is... probably like you, actually. Interested in Elixir but trying to aim higher as a self-motivated learner.
Old coders who love coding don't have to do so indirectly.
1. https://craftinginterpreters.com/
1. https://interpreterbook.com
2. https://compilerbook.com
For more advanced C/C++ developers I can recommend "The Linux Programming Interface" - (https://man7.org/tlpi/). It is a GREAT compendium for writing code against the POSIX API. I have a (legal) copy of this book on all the computers I have access to.
"The Database Redbook" - (http://www.redbook.io) is a valuable source on database implementations.
"Compilers: Principles, Techniques, and Tools" (Dragon Book) is a great starting point. The book is out of print and but I think it should still hold up for most basic use-cases.
https://shop.jcoglan.com/building-git/
Build a blockchain from scratch in go
https://web3coach.gumroad.com/l/build-a-blockchain-from-scra...
Compiling to assembly from scratch
https://keleshev.com/compiling-to-assembly-from-scratch/
If anyone knows of similar books, don't hesitate to comment below.
It's now on the second edition which I haven't done.
[0] https://codestool.coding-gnome.com/courses/elixir-for-progra...
Edit: Exactly the kind of thing I was looking for
Set it up for local development, then step through calls with a debugger, look at the whole call/request lifecycle, start to tinker with the subsystems..
It's a great way to see the real-world usage of all the core concepts you've been introduced to in the intro/learning courses or tutorials, and be exposed to more advanced patterns.
For Elixir, the obvious choice would be Phoenix if you're on the web app side of things..
https://www.udacity.com/course/design-of-computer-programs--...
CodeCrafters is a bit light on Elixir support at the moment (only 2/8 challenges support it so far). We're planning on expanding Elixir support soon.
Currently, we're a great fit for Rust / Python / Go - we support a variety of challenges for those, and there's lots of example code from other users to review and learn from.
I understand that this might not fit your use-case, but it's worth a try. Just be aware that it tends to hallucinate APIs.
"Simply do not say anything and move on" is something to do instead.
LLMs confer a tremendous productivity boost. You just have to understand their limits and know when it's faster to think through and write the solution yourself.
It finally landed on me that I was using gpt3.5 . Once I moved to gpt4 it got it right the first time.
I feel like telling it that it’s wrong and linking documentation is the same as referring to Wikipedia?
It gives you nice little hints and a different perspective on your api design itself. I'd have a chat with chatgpt and sometimes I'd miss to share specific code and it just assumes or hallucinate on that.
What you've described is the opposite of that.
It's also more fun to have something which can be easily extended than to start from scratch.
If you’re looking to understand what makes Elixir different from the most popular languages and how OTP works, I’d suggest Elixir in Action: https://www.manning.com/books/elixir-in-action-third-edition
If you’re already familiar with that, then take a look at the books from Pragmatic Bookshelf. They have quite a few books that cover different aspects of Elixir development including a recent ML-focused one: https://pragprog.com/categories/elixir-phoenix-and-otp/
I read this book years ago when i was first learning elixir. I was coding for about 8 years at the time, so not new to the game.
I liked it a lot. I don't think i wrote every project in the book, but it helped me wrap my head around OTP and how erland/elixir projects are structured.
Highly recommend it.
And there's it's big brother Predicate Calculus and Program Semantics by Dijkstra and Scholten that more rigorously formalizes the same approach.
Dafny[2] is one approach out of Microsoft Research that attempts to provide automated tooling around some of those concepts.
All of the above are excellent places to start if you're interested in learning how to write better code with the imperative languages that you're actually going to use professionally.
[1] https://www.cs.utexas.edu/users/EWD/
[2] https://dafny.org/
A somewhat more modern approach of related concepts to ewd's work is the work of Richard Bird which teaches you about using equational reasoning to take a correct naive algorithm and systematically optimize it into a correct and fast algorithm. [0] [1]
Regarding Dafny, there's actually a new book out that should be approachable to anyone with programming experience. [2]
[0] https://www.cs.ox.ac.uk/publications/books/functional/
[1] https://www.cs.ox.ac.uk/publications/books/adwh/
[2] https://mitpress.mit.edu/9780262546232/program-proofs/
Equational reasoning is borderline magical, and I look forward to the day when it's as pervasively taught as basic logic.
I have this fantasy in my mind of a language/editor combination that begins with the empty program and only allows legal equational development. Without explicit predication that would just maintain the invariants of the language itself, so no undefined behaviors, but with user supplied predicates would allow a kind of exploratory programming with safety nets. One way to look at it would be explicit symmetry breaking, although I'm not sure that's a good way to describe it to typical working programmers. The idea though is that for a program with the empty specification all code transformations are symmetrical with respect to the spec. And then as the specification is added to certain transformations become symmetry breaking and thus illegal, with said illegality being statically checked. Clearly I'm waving my hands quite a lot here, and I have no clue if it's actually practicable.
I have no affiliation with it I just love the idea and hope to see more like this.
https://www.dabeaz.com/courses.html
Usually I just use that site in addition to the official tutorial when a concept really stumps me.
Here's their article on Elixir[1]
[0]: https://learnxinyminutes.com
[1]: https://learnxinyminutes.com/docs/elixir/
https://github.com/adambard/learnxinyminutes-docs
It's way better than the typical painful language tutorial that is teaching you about how a variable is like a box containing a value... for every new language you want to learn.
For the sake of other people knowledge, if you appreciate this format to learn a language from a book, search for "language reference" books. They are usually succinct and to the point.
There are some positions available though. For example, I recently found Let over Lambda by Doug Hoyte. Excellent book if you are that kind of programmer.
Another problem with advanced materials is that frequently people are even unable to recognise them as advanced or valuable. It is easy to look at and evaluate things you have experience with, it is much more difficult to impossible to do the same with stuff that is beyond your experience (also called The Blub Paradox: https://www.paulgraham.com/avg.html).
Personally, I just read a lot. I try to keep an open mind and even if I don't agree fully with the contents of the book, I try to use the ideas as inspirations for my own thinking. You can read codebases written by other people and learn new ideas. Over time, you gather a library of solutions to problems and knowledge of when to and when not to apply them.
If you do enough of it, you will find useful knowledge in unusual places.
But if anyone is like me and interested in taking a risk on those $80-150 tomes, CRC Press' books have been more hits than misses for me.
But if you are are into graphics programming:
-Peter Shirley's Fundamentals of Computer Graphics is a great comprehensive resource. Despite the name, it serves as a great jumping off point even for experts into a different subdomain if they don't know where to start
- Johnathan Cooper's Game Anim is one of my most recent purachases. A great overview of the animation process, from the views of both the artist and technical engineer. Not just great for concepts but to get an idea of how and where a large studio executes their workkflow in production.
- Most of the GPU series from Wolfgang Engel are worth their weight in gold. The 7 or so GPU Pro series is basically whitepapers on all sorts of (at the time) cutting edge rendering techniques. Then the "GPU Pro 360" books are there if you wanted to focus on a specific subdomain instead of looking across the pro books (e.g. a GPU Pro 360 book focusing on Lighting or Image processing)
Even if you found zero recipes, that does not mean you wasted time. Maybe if you think in terms of results for that particular cookbook investment, but it is pretty arbitrary way to look at it. What if you tried to measure your return for investment on a single page of a cookbook? For half a dozen coobkooks? For a shelf of cookbooks?
If you continue buying and studying cookbooks, you will find some good recipes in some cookbooks and what you need to look for is the total return on the total of investment. I spent a ton of money on cookbooks but my life is much better for it and I have zero regrets even if many of these cookbooks yielded zero results.
So now back to technical books.
Some of these books will yield new knowledge and some may yield very little or even none at all. You may not know before you buy a book whether it will pay for itself, but you know if the whole business of buying books and learning from them is worth it. I chose to buy and read books even if some of them yield little results because I think I am a better person and a better developer for it. I learned a lot of useful stuff even if I completely ignore majority of everything I read and then forget majority of everything I thought valuable.
Hiring people who do not perform seems like a profound waste of resources. Doing projects that fail seems like a profound waste of resources. Learning technology that will not be helpful later in your life seems like a profound waste of resources.
When was the last time you found a cookbook where a significant portion of recipes stayed with you for the rest of your life?
It’s like being able to walk into a bookstore full of cookbooks, and by skimming a few pages here and there, walk out with 3 fantastic cookbooks.
In other words, good programmers have the ability to quickly understand the full problem space (including business concerns) and efficiently navigate the solution space.
But IMO that's a stupid way to view books in general. You would have to contend that ALL books are worth nothing, because you have to expend effort to read it or try to actually make use of the knowledge in it.
So how I define value of a book? From the economics, this would be the opportunity cost which is the next best thing you could do. If you have better use of your time than reading any book then yes, books are worthless to you as long as you can do better things with your time.
For me, I found that reading books brings immense value to me by either directly bringing actionable knowledge or by causing me to think in new ways. Yes, these are my thoughts, but I argue I would not have them if I kept my brain just doing the same thing every day.
I attribute many hundreds of thousands of dollars of my income to ideas in books that I red and some of these books more than others. I am not listing these books here because I also believe that it is not about these books. It is about me getting value from the ideas that I would not know otherwise.
I remember paying crazy amounts for books at university and wouldn't have been surprised to have to pay $200 for a book. As it was I bought mine second hand to save on cost.
When people can expense such items then I also imagine a $200 book selling well when properly targeted and marketed.
What sells even better though are courses, and there are many courses out there aimed at corporates which are in the thousands of dollars so again, $200 doesn't seem crazy at all in comparison.
If this were the case, such a book would be an immediate buy for me. The problem is that you will have to show me that such a book will bring me this value in my culture/country (i.e. not USA) with a very high likelihood - this will be very hard.
I wonder how much this is true in other areas (not counting academic papers).
It's not exactly true in law due to the plethora of giant treatises in any specific subject of law, as far as I know that might be a one-off due to US law putting such an (insane?) emphasis on precedent. Basically need a professional lawyer+historian to compile all the relevant stuff.
But other engineering or science disciples? I have no idea one way or the other.
I’m not sure there’s great content like this for lawyers either even with mandated continuing education requirements. They’re typically a bore and surface level. About the same quality as your average “What’s new in Elixir 1.15” blog post.
As you've pointed out in other engineering disciplines, there are researchers who are pretty deeply immersed in the academic papers and help to move the state of the art forward.
In other cases, there are the societies like ASME, IEEE, ASCE, etc. that put out standards or guidelines. These could either be viewed as documents that you use to plug numbers into formulas or you can try to derive the equations from first principles. Often there are training courses or workshops run by these societies, so that's a place to learn. There are trade publications to learn from as well.
What OP is talking about is essentially learning a new language which is sort of trivial and not advanced. It's sort of a parallel track and he likely wants something that doesn't start at the very beginning. Something called: "Learning elixir for experienced programmers". This kind of thing isn't "advanced". It's more like "convenient". Most programmers spend there entire careers in this zone just learning new languages and new technologies. They are sort of moving horizontally through the field rather then upwards.
True advanced stuff is hard af, and the more advanced you get the less and less relevant it is to your job.
I think, even aside from the incentives, its a matter of interest and time. Earlier in my career, when I was learning at a rapid pace, I also had the time and motivation to write blog posts about what I discovered, as did many of my peers. Its also easier to write about beginner concepts, because they're simpler.
As I've advanced in my career, the things I'm learning and doing are more and more complicated, and/or require much more prerequisite knowledge. Not only do I have less time, there's also a corresponding increase in difficulty in writing concisely and coherently about the more advanced concepts.
About once a week I read a blog post in a field I'm familiar with, and recognize it as something I myself would have written 10 years ago. But I also now see in it the potential problems and pitfalls, and tweaks to make to avoid them. I think to myself "I should write a blog post about that", and sometimes even jot down some notes or a draft, but the topic is just so complicated, and the potential problems so subtle, that it takes a large amount of effort just organizing it, and I get bored/distracted and move on, never finishing it.
Talking to those same peers now, they feel much the same. And even with the experts that do manage to write about expert topics, that's become their full time job. Then after a few years of full-time writing instead of full-time doing, I find when they write about a topic that I've been full-time doing while they were writing, there's gaps in their knowledge or new techniques and tradeoffs they've missed.
I don't know how to solve this problem, except maybe figure out a way to give the knowledgeable experts a sabbatical or something, where they can take a break and write. Good luck getting a startup to agree to that, though.
Of course, I'm sure I don't need to explain the downsides of a talk, Especially one presented by very knowledgable people but not ones who are necessarily expert speakers. But at the same time, that lack of polish may be a light in the darkness that is false platitudes in every other ad.
However, I've never liked writing. First English is not my first language, so I barely managed to write my PhD thesis in that languages, mainly because I had to. But in general I've tried several times to write some extensive piece about something that I am passionate about at the moment, and although in my head the blog post sounds good, once I start writing, I just get lazy and words don't flow.
What has worked for me is mentoring. I am advisor for several startups at different stages. I have weekly 1 hour meetings with their CTOs (sometimes the CEO, depending on the startup). They aske me questions of things they are struggling with, and I give them my POV, ideas and sometimes more questions.
So far that has been very nice. People have appreciated it a lot (I've even been referred as advisor to new founders) and in addition I usually "charge" 0.5-1% equity instead of money, which is a good way to have some stake in projects I like.
What books would you recommend? I find it hard to learn real world patterns and codebases.
Smaller patterns like inheritance, composition, traits, functional monads, async coroutines, RAII, MVVM, dependency injection, and semaphore synchronization, are easy to learn, but seemingly unhelpful in the grander scheme. Nobody seems to completely adhere to the rules. As a result, these small patterns never seem to lead to clean code.
I loved coding as a child and pursued CompSci in college. But having worked a few years in the industry, I really think I do not know how to solve anything. At one point I felt as if everyone is gaslighting me. But if multiple people from different companies say I need to learn, then I should.
Right now I want to read to know what exactly I am missing in my knowledge about how code works in large codebases
(Edit: Thanks for the reply!)
Good. That is very useful state of mind to be in.
Because these things do not produce cleaner code. They are tools to solve problems.
Coders are like photographers. The ones who like talk the most shoot walls head on and then peep at pixels and mostly discuss hardware. The ones who know how to make good photos do not care about who uses what kind of camera. A camera is just a tool to capture light field.
Clean code is what happens in your mind and as a result of your mental process.
Patterns, composition, inheritance tricks, and so on -- these are things you add to your toolbelt to use it when it is needed. You should continue adding tools to your toolbelt to be able to solve wider variety of problems and have more alternative solutions. But on its own, more tools do not mean mastery and do not lead to clean code.
If anything, more tools without knowledge how to use them leads to less readable code. This happened to me for the first half of my career..
What get you to mastery is by building taste for simple code and ability to self reflect on your work. Taste for simple code means you know why code needs to be simple and you know how clean code looks like.
Self reflection is trying to be objective and judgy about your results. When you write the code, you keep refactoring until you like the results. You write a module, then you polish it until there is nothing else to remove and it does exactly what it is supposed to be doing. You do it long enough and you will have experience to start it closer to a clean result. You may never get to be able to write clean code on the first try but you might get better at having much cleaner first approximation.
Ideally, you also take some responsibility longer term for what you produced. You compare your initial ideas with how they fared over time. You learn some things you thought smart weren't so smart at all. You learn what works and what doesn't work in general.
There is one more way and this is mentoring. I do pair programming with people where we design and implement solutions to progress. Lets me get to know the person better and the person gets to observe the process which can be a huge shortcut in the process of learning to write clean code.
Another classics are: - Working effectively with legacy code - Refactoring: Improving the Design of Existing Code
All of these books have a lot of depth to them
It is not at all unfashionable to pay $50k for a master's degree, however.
But, here's how I conceptually think about advancing one's understanding in programming.
First, you can aim for breadth or for depth of knowledge. So, learning another language is, in itself a kind of "advance". However, for depth, you'd usually want to pick a specific sub-discipline in programming and concentrate on that. You will have better luck with choosing theoretical disciplines, because those usually are rooted in math, and so have longer history and more systematic approach. The more "practical" aspects usually follow the arc of having an introductory course (at best) with the next learning stage being an "area of active research" (also, the intro course would typically be bad).
To give you an example: in college I became interested in regular languages. So, I was looking to expand my knowledge on the subject. Out of all things that I could dig up on regular languages two seemed most appealing: approximation of context-free grammars with regular languages and equivalence between generating functions and regular languages. In a short while I realized that I don't have enough of mathematical background to go after the generative functions part, but the approximation part turn out to be fun and interesting. I was able to dig up some papers and even try my hand in doing something with the concept.
You'd have similar success if you went after types in programming languages. There are plenty of publications, and you will have multiple steps ahead of you before you run up the wall of "area of active research". My journey down that path started with Benjamin C. Pierce's Types in Programming Languages.
Another direction you may consider is to try to generalize your knowledge. For example, of programming languages. In this regard, I find the book by Shriram Krishamurthy, Programming Languages: Application and Interpretation to be a good introduction to the theoretical side of crafting and evaluation of programming languages.
There are, also, unfortunately, some areas where a lot of programming work has been done, but very little learning material is available, and, especially nothing deep has been produced. For example, if you want to go down the system programming route... there are books, that's true, but the level of generalization leaves a lot to be desired. It's often boggled in all kinds of "practical advise" and very concrete examples based on Linux Kernel code long ago replaced by something else (or worse yet, but original Unix code etc.)
Or, even worse, if you consider fields like testing. Or even GUI. It's surprisingly common and yet surprisingly without much analysis or structure.
I took 2 courses: "Rafting Trip" and "Write a Compiler". Both were awesome. The Rafting Trip took us through implementing the Raft consensus algorithm from scratch. And the "Write a Compiler" course had us build a small language using LLVM.
Both courses (but especially the Rafting trip one) were definitely for experienced programmers. In the courses I took, people generally had at least 5 years of professional work. And even still, there were a few people that really struggled to stay on pace in the course.
But at the end, most people had a (kinda) working Raft library or compiler!
[1] https://dabeaz.com/
But there were some small group breakouts to discuss the topic and get to know one another. And David would try check in with each person one-on-one every day to answer questions, give tips, and say hi.
So generally, I'd say this is not a high interactivity course like a group project or something. Everyone is working on a separate implementation.
Though, I took the courses online. And, it looks like that's how he's offering them now. But around the time I took the 2 courses, he had just switched to doing that because of COVID. Presumably, the in person courses offered a lot more time to socialize and go out for a drink in the evening.
In particular, I recently prepped/ran a week-long, in-house training session of Dave's Python-Mastery[1] course at my day job. We had a group of 8 with a mix of junior and senior Software Engineers and while the juniors were generally able to follow along, it really benefited the senior SEs most. It covers the whole language in such depth and detail that you really feel like you've explored every nook and cranny by the time you're done.
[1] https://github.com/dabeaz-course/python-mastery/
(I enjoyed teaching the class so much that I've considered offering my services teaching it on a consulting basis to other orgs. If that interests anyone, feel free to reach out to the email in my profile.)
As you say, he is very good at explaining things - it's hard to describe, but it just clicks. Highly recommended.
I was a bit worried about the online aspect, but there is a very good flow actually.
https://www.mirdin.com/
Do have a look at the testimonials. He hits the nail on the head on many ideas I could intuit but didn't have words for.
I don't know of any books or speakers to compare him to. He's a unique bridge between academia and industry. I suppose you could say his teachings are available in the many academic papers he sources, but those papers are dense. His curation and contextualizion gets the ideas in a form I can comprehend and apply at work.