Summary
Many developers enter the market from backgrounds that don’t involve a computer science degree, which can lead to blind spots of how to approach certain types of problems. Gary Bernhardt produces screen casts and articles that aim to teach these principles with code to make them approachable and easy to understand. In this episode Gary discusses his views on the state of software education, both in academia and bootcamps, the theoretical concepts that he finds most useful in his work, and some thoughts on how to build better software.
Preface
- Hello and welcome to Podcast.__init__, the podcast about Python and the people who make it great.
- When you’re ready to launch your next app you’ll need somewhere to deploy it, so check out Linode. With private networking, shared block storage, node balancers, and a 200Gbit network, all controlled by a brand new API you’ve got everything you need to scale up. Go to podcastinit.com/linode to get a $20 credit and launch a new server in under a minute.
- Finding a bug in production is never a fun experience, especially when your users find it first. Airbrake error monitoring ensures that you will always be the first to know so you can deploy a fix before anyone is impacted. With open source agents for Python 2 and 3 it’s easy to get started, and the automatic aggregations, contextual information, and deployment tracking ensure that you don’t waste time pinpointing what went wrong. Go to podcastinit.com/airbrake today to sign up and get your first 30 days free, and 50% off 3 months of the Startup plan.
- To get worry-free releases download GoCD, the open source continous delivery server built by Thoughworks. You can use their pipeline modeling and value stream map to build, control and monitor every step from commit to deployment in one place. And with their new Kubernetes integration it’s even easier to deploy and scale your build agents. Go to podcastinit.com/gocd to learn more about their professional support services and enterprise add-ons.
- Visit the site to subscribe to the show, sign up for the newsletter, and read the show notes. And if you have any questions, comments, or suggestions I would love to hear them. You can reach me on Twitter at @Podcast__init__ or email hosts@podcastinit.com)
- Your host as usual is Tobias Macey and today I’m interviewing Gary Bernhardt about teaching and learning Python in the current software landscape
Interview
- Introductions
- How did you get introduced to Python?
- As someone who makes a living from teaching aspects of programming what is your view on the state of software education?
- What are some of the ways that we as an industry can improve the experience of new developers?
- What are we doing right?
- You spend a lot of time exploring some of the fundamental aspects of programming and computation. What are some of the lessons that you have learned which transcend software languages?
- Utility of graphs in understanding software
- Mechanical sympathy
- What are the benefits of ‘from scratch’ tutorials that explore the steps involved in building simple versions of complex topics such as compilers or web frameworks?
Keep In Touch
- @garybernhardt on Twitter
- garybernhardt on GitHub
Picks
- Tobias
- Gary
Links
- Wat
- Birth and Death of Javascript
- Destroy All Software
- Deconstruct
- Data Structures
- Computer Science
- Compilers
- Programming Bootcamps
- Graph Theory
- Julia Evans
- @b0rk on Twitter
- Allen Downey
- Jupyter Notebook
- Halting Problem
- Idris
- Visual Basic 3.0
- Set Theory
- ML Family of Languages
- SML, a simple dialect of ML
- SML/NJ, a compiler for SML
- OCamL, a more modern dialect of ML
- F#, an even newer dialect of ML
- Clojure, a modern Lisp-like language
- Lua Grammar (scroll to the very bottom for the full grammar)
- John Carmack
- Twitter Thread Explaining Episode Context
The intro and outro music is from Requiem for a Fish The Freak Fandango Orchestra / CC BY-SA
Hello, and welcome to podcast dot in it, the podcast about Python and the people who make it great. When you're ready to launch your next app, you'll need somewhere to deploy it, so check out Linode. With private networking, shared block storage, node balancers, and a 200 gigabit network, all controlled by a brand new API, you've got everything you need to scale. Go to podcast anet.com/linode to get a $20 credit and launch a new server in under a minute. Finding a bug in production is never a fun experience, especially when your users find it first. Air Brake error monitoring ensures that you'll always be the first to know so you can deploy a fix before anyone is impacted.
With open source agents for Python 23, it's easy to get started, and the automatic aggregations, contextual information, and deployment tracking ensure that you don't waste time pinpointing what went wrong. Go to podcast in it.com/airbreak today to sign up and get your 1st 30 days free and 50% off 3 months of the start up plan. To get worry free releases, download Go CD, the open source continuous delivery server built by Thoughtworks. You can use their pipeline modeling and value stream app to build, control, and monitor every step from commit to deployment in 1 place. And with our new Kubernetes integration, it's even easier to deploy and scale your build agents.
Go to podcastthenit.com /gocd to learn more about their professional support services and enterprise add ons. And visit the site at podcast in it.com to subscribe to the show. Sign up for the newsletter and read the show notes. Your host as usual is Tobias Macy. And today I'm interviewing Gary Bernhardt about teaching and learning Python in the current software landscape. So, Gary, could you start by introducing yourself?
[00:01:47] Unknown:
Sure. I'm Gary. The thing I you're most likely to recognize me for is, a little lightning talk called WAT that has been very popular. Or The Birth and Death of JavaScript is a full length talk I did that was very popular. The main thing that I do is I run a company called Destroy All Software that publishes, screencasts, so videos where you see my screen demonstrating programming stuff. And, my goal there is always to sort of demystify the parts of programming that a lot of programmers find scary or off putting or they don't wanna dig into it because, I don't know, because it's scary. So I also run a conference called Deconstruct here in Seattle, but that's a little bit less related to the direct act of programming, which is kind of why we're here.
[00:02:31] Unknown:
So yeah. That's me in a nutshell. And I know that you spent time working in a lot of different languages, but 1 of the ones that you have been involved with for a long time is Python. So do you remember how you first got introduced to the language?
[00:02:44] Unknown:
I absolutely do. It was a very notable event. So the basic thing that happened is that I used Python to DDoS electrical engineers with QA reports, which is a sort of weird statement. So, so, in 2000 4, I was in college, and I was doing, a co op, which is sort of like a very long internship. It was 7 months long. And it was a company that built test and measurement devices, so things like, a rackmount box that will measure temperature through thermocouples or a a different rackmount box that will measure strain on materials, so the flexing of the material. And that would be used for example to, you you put a a plain wing in a, wind tunnel and you cover it with strain gauges, hundreds of strain gauges, and then you just subject it to extremely high winds, and you record a 1000 or 10000 sometimes times per second, how much strain is on each part of the wing, and maybe you even force it to break under for, under that load. So these are these are devices that are, you know, very mission critical, for the things they're used for. And this strain gauge device in particular had 3 DSPs in it, digital signal processors. And those were programmed by the electrical engineers because it's sorta it's a signal processing problem that's sort of their domain, but it was a much more difficult software problem than they normally dealt with. And I was working with the actual software team, so not related to the electrical engineering part at all. And they were having they were having big problems with quality basically on this thing. It would it would fail in ways we didn't understand. It seemed kind of random, although, you know, computers are rarely random so we knew there must be a pattern.
And what I ended up doing was using Python. This is my first time using Python for anything serious. I used it to write what we would call what we what I should have known was a test, but I had never written a test before. But I wrote this this giant program that would put the system into all the states it could handle. Right? So a single strain gauge channel could have many units, measurement units it was reporting in. So it would try all those. And it would have multiple types of calibration you could do. So within each unit, it would try each kind of calibration. And And there were multiple frequencies it could scan at. So within each of those measurement units, within each calibration type, it would try different frequencies and just put the whole thing through its paces.
Roughly 30, 000 different state combinations that it would do, each of which is is configuring dozens of different parameters. And that would take about 2 days to run, from beginning to end. So that was my first Python. And what happened as a result was everyone became as aware as we were of how buggy this DSP was. And eventually, it led to upstream sort of organizational changes that were beyond my understanding, that led to the quality of the thing actually being corrected. And so, these customers who would pay 1, 000, 000 of dollars for multiple full 19 inch racks of these devices, weren't getting random failures time. So that really sold me on Python because before that, I was basically just C only. This company's all its software was in C because it's embedded. You know, there's not enough memory and stuff to do Python. But this is what sold me on Python as, it was my first dynamic language I really knew, I really learned well and and this is exactly why.
[00:06:04] Unknown:
Yeah. That's a very interesting story. I've spoken to a few other people who use Python in somewhat of a similar environment of doing software engineering and test where they're putting different types of electronics through their paces. So it's interesting that that was your first introduction to the language, given that that's a use case that's not very well broadcast in terms of the broader narrative of Python.
[00:06:25] Unknown:
Yeah. It's I think it used to be more so. And the same thing with, like, pretty much all the dynamic languages. I mean, the reason that they were dismissed as, quote, unquote, scripting languages so frequently in the past is that they were associated with these kinds of these tasks that are perceived to be secondary. Right? The thing we care about is building the box that does the measurement. And, yeah, maybe we have to test it, whatever. We'll use some other language for that. But the the quote unquote real work is the box itself. And, of course, that's changed in the meantime.
But, yeah, back then, I think a lot of people got into these languages because they had a secondary task, and it was a good match for Python, Perl, I think is the same thing in many cases, Ruby even.
[00:07:04] Unknown:
And as you mentioned as during your introduction, you do a lot of work with teaching different aspects of programming via screencasts and presentations and recently through a number of very well written, textual posts. And I'm curious from somebody who spends a lot of time doing that, what your view is on the state of software education, particularly as more and more people are coming into the industry who don't necessarily have the traditional computer science background.
[00:07:36] Unknown:
Yeah. So the thing you just said is is probably the, the focus of of my thoughts on this. So I I have a traditional background, meaning I have a CS degree. But I also I was programming for, something like 5 years or so before I even started that degree. So when I took my first CS class, I had already written, you know, I don't know, probably tens of thousands of lines of code. All of it super terrible for, you know, reasons, but, not the least of which was I started when I was 13. But, I had I had a lot of context for what I was learning in those courses. And the problem with the traditional university curriculum is that if you don't have that background, right, if you haven't been programming for years and you're just thrown into your 1st CS course, well, the first 1 is usually kind of a a weird outlier, but the second 1 usually is data structures.
And if you go into a data structures course, month long course, learning all these different data structures, all these different algorithms, and not in most cases, not a single indication of why any of that would ever matter to anyone. Alright? That's the problem. Now I didn't personally have that problem, which means for a long time, I didn't understand it. Because when I was in that course, I understood exactly what all that stuff was for because I'd written all this code, terrible, terrible code. And in this in some in many cases, this was showing me what I should have done, what I was failing to understand in the past. But for a lot of students coming in who don't have that background, that that, it's just a mystery as to why any of this stuff is happening.
So, this continues throughout the sort of curriculum. Compilers, like, why do we even want a compiler? It's hard to answer that question when you haven't actually used a language to build an actual thing. So why would you wanna build a language? You know, the the problem just compounds and compounds. And the so on the other hand, you have the boot camps and obviously a much more recent thing. 10 years ago, no 1 was talking about them. 5 years ago, they were kind of niche, I would say. Now they're they're a huge force. And they take more or less the opposite approach, which means, you know, you get to a boot camp, you quickly begin building actual projects, and you continue to build actual projects throughout the whole thing. And of course, at the beginning, they're very rudimentary, but at least you have this sense of what you're actually doing.
But the thing that's lost is all the content that was actually in the undergraduate curriculum. You don't come out of a boot camp understanding those data structures. You don't come out understanding what a compiler is or or, well, at least how how 1 would work, in any kind of detail. And so you basically as a student, you're making a choice. You don't realize this in most cases, but you're implicitly making a choice between, do I want, a chance at the the deep understanding of these these fundamental topics, or do I want it to not be so painful to learn this stuff?
And it's a really weird dichotomy because both ends of it are pathological in their own ways, or at least well, 1 of them is pathological, the university 1. The boot camp 1 is merely incomplete.
[00:10:36] Unknown:
Yeah. And I think that both do a bit of a disservice because with the computer science degree, 1, you have to generally start very early on knowing that that's what you want to get involved in, and then you're sort of thrown into the deep end without necessarily having any context unless you were already interested and involved in that area. And then from the boot camp perspective, you are generally looking for a quick way to be able to get a job in industry. But then because you lack that more fundamental understanding, your knowledge of software development doesn't necessarily transfer as easily when you need to start using new and different technologies because you don't understand some of those foundational concepts such as data structures, algorithms, how compilers work, all those various things that you learn in a computer science degree. So as you said, from both ends, your experience becomes somewhat incomplete because from a computer science perspective, you learn all these nuts and bolts, but you don't necessarily learn how to put them together into a final working production grade project.
[00:11:36] Unknown:
Yeah. Absolutely. That's a that's a really good summary. And, the the thing that I would say sort of poisoned my position on this for a long time is the the sort of self evident truth that if you come out of a CS program with a degree and then you get a job working to build software, You're probably not that good at building software, but you're gonna have to learn. Right? Because you're doing the job. Either you're gonna learn or you're gonna wash out of the work entirely, which I think is fairly rare for someone who actually has the degree. But for someone who comes out of a boot camp, there's very little impetus to learn the fundamentals. You don't you don't encounter a problem that has graph traversal structure.
Like, the structure of the problem is actually a graph traversal and realize that unless you studied graphs. Right? You have to you have to have some kind of blueprint of the shapes of the the problems before you can even recognize that a solution is known. Like, you wouldn't even know what to Google for. Right? I mean and you see this in whenever people say they don't use data structures in everyday work, you see this because of course they do. Every time you have a class where it contains an instance of its own type, right, whether that's a parent kind of thing or something like that, that's a linked list. And whenever well, actually, I guess. It depends on how many point to how many. That's either a linked list or a tree. And if you don't recognize that, you're going to miss out on all kinds of solutions that were known, you know, before you were born, and you're gonna reinvent them probably clumsily. So that's the the danger of the boot camp approach. And it's the thing that that is lost by making, by switching from the university approach to the boot camp approach.
[00:13:14] Unknown:
And for a lot of people who are coming from that context or who don't necessarily even go through a boot camp and just use self directed learning to teach themselves programming, whether it's just through getting involved in a project or, you know, trying to scratch their own itch of, something that they're trying to solve for themselves, and they do decide that they are interested in learning some more of these fundamental aspects. A lot of the material that's available is fairly steeped in the theoretical aspect of computer science. It isn't necessarily presented in a way that they're even able to grasp and understand it appropriately in order to be able to get the benefit that they would like to have.
[00:13:50] Unknown:
Yeah. Absolutely. And that gets to sort of I mean, I think we we got on this topic because because you asked me about the the state of education. And so all of the the sort of university versus boot camp, state state of things is really is is the stage upon which, I want to actually address that. So what you said is exactly true. The literature is all written in the turn in the in the language of mathematics, generally speaking. And if you have a CS degree, that's not a problem. Right? I mean, if you wanna learn if you wanna refresh your knowledge of, Turing machines, you can go to Wikipedia and it'll say, Turing machine is a 7 tupel of whatever, 6 Greek letters and 1 English letter maybe, and those are all sets of things or whatever. I forget the details.
But so what I 1 1 of 1 of my missions, or really probably my defining mission in in all of my work for the last 7 years has been trying to find things like that and just show them directly using the terminology the programmers actually use. So, there's a series on Destroy All Software about computation and I just like for Turing machines for example, I don't say it's a 7 tuple or maybe it's a 5 tuple. Whatever. It's not an n tuple of anything. We're just gonna write a simulator that takes in Turing machine instructions and it runs the simulation and we get a result out. And the simulation function is something like 6 lines long or whatever. It's super simple. And so if you understand Python, you can understand what's going on there. And that is, I think, a very good path to take people who don't have that theoretical background and bring them into it because that's the direction that's difficult. If you graduate with a CS degree, like I said, you're gonna figure out how to do actual programming because you're gonna be doing the work. But doing the work is not a route to get back to the theoretical stuff.
And that is the piece that to me has been a glaring, missing piece in the educational story always. I mean, it's not a new problem. It's it's a forever problem. I think we're only just starting to get a little bit of stuff that that can fill that gap. With how many people are coming into industry without this,
[00:15:52] Unknown:
theoretical understanding, are there any thoughts that you have on ways that we can provide motivation and impetus and opportunities for them to gain this knowledge as part of their general day to day work without necessarily, forcing them into it?
[00:16:10] Unknown:
Yeah. It's, okay. That's a difficult problem, but but I think there are people who are doing good work there. Not well, so, because I don't need those things, I'm I'm not, the most prolific consumer of them, right, because I took all those courses. But I would say, for example, Julia Evans' work, that's Evans like e v a n s. Her work is explicitly, very clearly designed to sort of ingratiate people to to this kind of stuff. And she's usually for her stuff is a lot more like systems programming, that kind of thing. But I think she does a really good job of approaching these topics in a way that they've traditionally not been approached that is designed not to scare people off. And it's not gonna appeal to people who have a CS degree, generally speaking, or at least a lot of them, certainly a lot of the ones I know, because they just wanna see the, you know, the mathematical form or just the super dense technical form. But there are we're seeing slowly the, proliferation of other ways of introducing this kind of stuff. And, you know, I'm trying to do mine. Julia is is doing a really great job of a completely different taking a completely different tack on it. And so I think we're seeing we're seeing,
[00:17:17] Unknown:
good stuff there. Another person who's doing some work along those lines of trying to present some of these computational elements in more programmatic terms is Alan Downey, who's the author of think Python and think complexity and some of that other some some of those other related books. He he's done a fairly good job of that as well. Mhmm. Yeah. I've heard really good things. And so we've discussed a number of ways that as an industry and as academics where we are failing the practitioners of software development and software engineering, but what are some of the things that we're doing right in your opinion? Well, I think that,
[00:17:55] Unknown:
the shift over the last, I don't know, what would it be, 10 years maybe? I mean, so when I when I was a student at undergraduate, getting a CS degree was the way that you became a programmer. So you had to, you had to slog through, you know, multiple years of effectively an applied mathematics, degree, which is kind of what it is, but without any connection to the actual work you thought you came in to do. And so, as I think I said at the beginning, unless you were already doing programming and already could make the backward connections in your mind to understand, oh, I'm learning this super arcane weird looking thing because it's gonna help me solve this problem that I have had, in the past. Unless you had all that context and the sort of, awareness to make the connections, it was just a a random slog.
And we that has all been basically blown up in the last, 10 years and especially the last 5 years with the explosion of boot camps and and hopefully other sort of more in between, organizations to fill out the full spectrum. And I think that that is something that, collectively, we've we've done a very good job at. Specifically, the sort of cultural change of you don't have to only hire people who have CS degrees. I mean, certainly, it probably still confers an advantage, like, it's not going to hurt, but it's not the kind of, you know, pass to enter the industry that it was when I was a student.
So I think that's very good. The other thing, and this is sort of along the same lines in a sense, is in certain ways, tools are getting way, way better, or at least there are new kinds of tools coming online that I think are are really filling miss filling holes that have always been in the toolset and Jupyter, for example, and and tools like notebook style tools. It alleviates so much of the the accreted, accidental complexity of our tool chain. I mean, if you if you take a you know, just even today, if you take just a a new Mac from Apple and try to turn it into a dev environment, you're gonna be typing all kinds of commands into your terminal, to do all kinds of arcane stuff. And the more we can remove that, the more we, we turn programming into something that is not well, it's along the same lines as the the degree thing. Right? You don't have to understand, understand all of this accidental historical complexity that is not there for any good reason, in order to to get up a dev environment and do your work. Now if you're doing it every day, probably it's a good idea to understand that just for practical reasons. But if you're doing, you know, data science or something where programming is, you're not writing code all the time, you're often doing other kinds of analysis or whatever. I think that Jupyter and other tools like that are excellent.
A really a really good, evolution.
[00:20:35] Unknown:
1 of the things that has actually become somewhat of an outgrowth of the focus and energy put into building more tooling is that in some cases, it can actually add complexity that wasn't there to begin with. 1 1 of the use cases that I'm thinking of in particular is with JavaScript development where it used to be you just write a flat file, you link it to a web page and you're off off to the races. But now there are all of these other steps that you need to bring in if you want to build a modern JavaScript application like webpack and babble for transpilation and things like that. And since you spend a lot of your time exploring and explaining some of the fundamental aspects of programming and computation.
I imagine that there are some lessons that you've learned which transcend specific software languages and cut to the core of the nature of software development. So are there any in particular that you think are worth sharing?
[00:21:30] Unknown:
I do have 1. Yes. I, it's hard to when you when you start, like, making abstract formulations of programming ideas, they often become so abstract that they don't seem useful anymore. But the 1 that has served me the best is your your job as a programmer is not merely to get the machine to do something. It's also to, insofar as you can, make it impossible to represent things that are wrong. Not like morally wrong. Well, maybe actually, that's probably an obligation too but that's a different kind of discussion. But in this case, I mean make impossible or make incorrect states unrepresentable which is a sort of rallying cry of of the static typing, folks, the ones on the stronger end of the spectrum like the Haskell folks.
So if you look at, like, the static language version of this, which is the most obvious version, the the sort of weakest thing there is just saying, okay, I'm calling a function. Does that function even exist? Which is a question that you can't answer in Python no matter how hard you try, at least not correctly, because it it degenerates into the halting problem, which we know we can't solve. Now the next level is I'm calling a function that takes an integer, but I passed in a string or something like that. So super basic type checking. But and and that's where a lot of even modern languages basically stop. Like, Go doesn't go that much beyond that. And, of course, neither does c or or, most of its descendants.
But there there's another level or there are many more levels beyond that. So if you take a language with d dependent types like, Idris, you can say things like, this function accepts an integer, but only integers greater than 5. And if you try to pass an integer to it that could theoretically be less than 5 or, I guess, less than or equal to 5, that's a compile error. So it statically determines that that integer might at some time go below 5, and that means you're not allowed to pass it to this function. And then even beyond that, you can say things like this function takes arguments x, y, and z, and x plus x plus y must always be greater than z for whatever reason.
And if you ever use the function in a context where that might not be true, that's, again, a compile time error. So this is all, these these error conditions are detected before the program actually begins execution. They're detected during a compilation phase. Now all of that is, static language stuff. So when you get to dynamic languages, you you lose all of those types of guarantees obviously by definition. But there's still a lot of stuff like that that you can do in a dynamic language that Incorrect states are not representable. So for example, there's a a very old, idiom in Python where you you wanna choose from a bunch of things.
So you construct a dictionary, that maps the possibilities to whatever values you want, and then you, index into it to get the thing out. So instead of doing, for example, if, you know, if x equals 1, return cat. And if x equals 2, return dog. You make the dictionary right in line and then you immediately fetch out of it. Now the reason this works is actually a particular thing about Python, which is if you try to index into a hash I mean, sorry, Ruby terminology. If you try to index into a dictionary with a key that doesn't exist, that raises an exception. So this will fail.
In Ruby, this doesn't work so well because the square bracket operator will return null. In Ruby, it's called null, if if the key doesn't exist. So in Python, you can do this and in Ruby, you actually have to do a slightly different thing, but you can still do it. But this is another example of that higher level concept of, making impossible things unrepresentable. And the same thing is true for using, an object with a constrained set of of attributes versus an open object like a dictionary. Because a dictionary can just be arbitrarily extended, and there's always a temptation to do that. And then you end up with dictionaries with, like, 47 keys in them and nobody remembers why half of them are there. At least with an object, there's a central point where, hopefully, all the attributes are listed out. Now it depends on your language whether that's true or not. In Python, that's actually less true. Python is less safe here because the attribute set is open, meaning if you have any object o, you can say o dot x equals 1, and it'll just let you do it.
That is not true in Ruby, for example. In Ruby, you have to explicitly somehow set up those, external accesses. So of course, every language has trade offs. I just mentioned 2, 1 where, we're fetching out of a dictionary and Python is safer by default. Another 1 where we want to explicitly limit the set of attributes on something in Ruby, is actually safer by default, which is usually not the case. But in this case, it happens to be. But there you know, we could talk for for well, I'm I guess I'm the only 1 talking about this right now, but I could talk for for hours about, examples of this. You know, like like null is a huge 1. Right? The the $1, 000, 000, 000 mistake.
And 1 of the things that makes me miss Python because I don't write much Python anymore is that in Python Python is a much more conservative language than Ruby is in terms of its null handling. So, like I said, hash index. If the key doesn't exist, it returns or raises an exception. In Ruby, it returns null. Same thing for arrays in Ruby. You run off the end of an array, you just start getting null. If you access an instance variable that doesn't exist, you just get null. So there's all kinds of safety things there. I think it's really a design defect in the in the Ruby language in the grand scheme of things. But, anyway, I don't know. I feel like I should I feel like I should mention a couple more of these just to triangulate the concept. So, like, using float is using float frequently allows states to be represented within your program that are actually wrong.
So the canonical example there would be money. If you use float for money and you ever receive a very large amount of money or a very small amount of money or your country experiences hyperinflation or something, you're gonna find that your your currency is not representable in the system you've designed. And, or another example actually that that just reminded me of is, y 2 k. Right? We saved we saved 2 digits all over the place. And then we spent $1, 000, 000, 000 like rewriting all this co COBOL code. And it's because in that case, actually, it was because correct states were not representable. Right? The future wasn't actually representable.
So if you if you kind of abstract out this idea of matching the states that are representable to the states that you actually desire in the program, it can guide you to choose, different possible ways of implementing things, and you see that in sometimes in language norms, community norms, things like, the Python thing about constructing a dictionary and immediately fetching out of it. We we turn that into an idiom because that alleviates the need for people to have all this insight on their own from scratch, and they can just say, yeah. In Python, we often make a dictionary and immediately index out of it.
But if you can see the higher level generalization of all of this, you can start to discover new ones on your own that are because there's just, you know, an unlimited number of these kinds of tricks.
[00:28:52] Unknown:
And if you were to pick 1 specific subset of the theoretical aspects of computer science that you have found to be most useful in your day to day work doing software development, what would you call out?
[00:29:07] Unknown:
Oh, that's such a wonderful question. It's I mean, there are definitely large swaths of it that don't really come up. But the thing it's interesting. The the thing I'm I'm drawn to answer with is also 1 of the most abstract parts of the degree, which is just, discrete math, like basic discrete math, like the the the actual mathematical definition of a function. Because ultimately, the thing I just said about making impossible states, actually unrepresentable is is exactly a discrete math thing. It's about explicitly thinking about the set of possible states in the program and limiting it to only the ones you actually want. And if you're not good at thinking about sets and just discrete math in general, I have the feeling it's more difficult to see what that generalization actually is because, you know, the the less, the fewer abstractions you have, the more everything feels like a concrete example.
And so if you don't have that theoretical background, a lot of things in programming are gonna seem like, oh, we have, you know let me come up with some concrete examples. So we have we have this situation where, in many languages, curly brace languages mostly, switch statements fall through. Right? The case falls through the to the next case, and that's the sort of a the source of a lot of bugs. And we have this weird case in Ruby where if you try to fetch out of a hash or an array and the thing doesn't exist, you just get null. And, I don't know. All these other examples I came up with. You're not gonna view those as a sing as all examples of this underlying unifying thing, which is there's a set of states and you need to make sure that that set of states is equal to the set of states you actually want. And the more you've you've thought about that kind of stuff, the more you've thought about, sets in particular, I think, the easier it is to naturally fall into that rhythm. And, that that actually gets back to something about the value of a CS education, which is 1 of the I think 1 of the most important things that I got out of my degree at least is not any of these things about, you know, oh, I, you know, understand roughly what a Turing machine is. I forgot how many elements are in the tuple, but, you know, I could look that up and and remember it all very quickly. It's not any of that stuff. It is the ability to to think directly in a symbolic system. So I don't need to use English to think about the structure of code. And I don't need to use code to think about the structure of code. You know? Like, the the relationship between the parts of a program can be thought of independently of a textual representation.
And the more you've thought about this super abstract stuff, which is exactly what a CS degree is, the easier it is for you to fall into that direct pattern of thinking, about the symbolic itself without mediation.
[00:31:47] Unknown:
I realized that just got extremely abstract. Does that make sense to you? No. That makes absolute sense. And 1 of the things that that makes me think of is that for people who don't necessarily have that theoretical background for having that symbolic representation to fall back on, A lot of times, they will latch on to whatever their favorite programming languages as that symbolic representation, which I think might be 1 of the contributing factors dogmatism that exists between language communities where people will have these, you know, very vitriolic debates about which language is better because they have this emotional attachment to this symbolic representation of how they think in terms of computation. And so because they don't have that more, fundamental symbolic representation at the mathematical level, they rely on the ways that they've learned with their favorite programming language.
[00:32:38] Unknown:
I think that's a yeah. I think that's a very astute observation. When you when you've learned how to program in I don't know. Let me choose a language that won't sound like I'm trolling. Let's let's take my own first language. If the way you learn to program is Visual Basic 3.0 and that's all you've ever used, then that is programming for you. And, it happens not only at the language level, but at the level of concept. So, actually, the I just reminded myself of a story that I've never I've never told of, in a recorded medium, and I think I should. So, as just mentioned, vb 3 was my first programming language, for better or worse.
And, this was in the nineties, like 90 6 probably or maybe early 97. I'm not actually sure anymore. But I didn't have the docs for it because it was a pirated copy of vp 3. So it was, like, made as small as possible because we all had modems. So no docs. And I and the web was sort of very young, and there weren't there wasn't really much there. There was basically nothing there to help me out. And plus, at the beginning of this, I didn't even know how to use the web. And I didn't have people around me who knew it. I had other kids, basically, who were in the same situation I was.
So there was nowhere to go to learn programming ideas. And if you try to imagine what culture of programming you build when you're a bunch of people between the ages of 13 15 and you're totally isolated from the world, and there because there basically is no world, right, around you, you don't have access to the adults who know this stuff, what culture would you come up with? With? And, the, the most interesting thing that came out of that for me in hindsight is I had this little snippet of code. I don't know where I got it. To choose 1 of 4 numbers because someone needed to do that, and I was like, that's an interesting thing. So I saved it away for later. And then I was trying to write a game, and I wanted to randomly generate the amount of damage that was done, when something attacked something else or whatever. And I was like, well, I have this code to choose 1 of 4 numbers. So I chose 4 numbers between 11100, and I and then I used the code to randomly choose 1 of those 4. So I just, like, took the existing code and stuck in, like, 4 comma 27 comma 31 comma 88 or whatever. And that was my damage generation code because I failed to see the generalization, which is if you can choose 4 things, you can probably also choose between 5 things or 6 or 100.
But I I just I had like, I had no abstract understanding of programming whatsoever. I only had this extremely concrete understanding. And this is the same this is the same reason that you see people, who who well, I don't wanna say refuse to learn another language, but, it's the same kind of the same class of mental block that you can get into even as a professional programmer. When you, you actually, you do see it a lot with people who refuse to acknowledge the efficacy of dynamic languages. So I've, you know, I've I've heard people say things, professional programmers, long time programmers say things like, you can't build real software in Python, for example, which is, you know, today, obviously silly. 10 years ago, it was merely silly.
[00:35:40] Unknown:
And that's also where you have all of these people who are advocating getting outside of your comfort zone and learning new languages so that you can bring back new understanding to the language that you primarily work in because each of these different ways of representing computation have their own paradigms and their own lessons to be learned. And so that's 1 of the ways that people can grow in their career is by not necessarily willfully segregating themselves to a particular set of tooling, and instead go out and explore the broader landscape of possibilities.
[00:36:15] Unknown:
Yeah. Totally. It's, yeah. It's all that that is all related. I was just trying to look up a really good example of this, but I've totally failed. But, somewhere on the web, there is a video I once saw of someone using the Idris programming language, which is maybe the most powerful well, not most powerful. It's it's an example of an extremely powerful statically typed language and they use it to, write something involving standard in or standard out and proving that it's that it's correct which is just mind blowing. So there's, you know, there's all kinds of weird stuff in programming. Weird from the perspective of of an everyday programmer. Obviously, you know, the universe doesn't have some kind of, like, ontological sense of weirdness under which Idris is weird and JavaScript is not. It's just the the path we've taken makes JavaScript not weird.
[00:37:06] Unknown:
That that's open to interpretation.
[00:37:09] Unknown:
I mean, you know, humans think in certain ways obviously to some extent. But but, you know, the fact fact that it's JavaScript and not, let's say, a descendant of ML, I think is totally an accident of history. But if you go out and learn, you know, actually, the ML family is a great 1 to learn. If you're a Python programmer, I would highly encourage you to learn, something in the ML family. SML is quite easy to learn. OCaml is more robust. F Sharp, if you're into the whole Microsoft thing, they they will really stretch your brain. In fact, I'm gonna add a pick for later related to this
[00:37:44] Unknown:
because I have a perfect 1. And going back 1 more time to 1 of the fundamental aspects of computation that becomes immensely useful is the idea of graphs and network analysis because everything that we do in software boils down to graphs at some level, whether it's determining the transitory dependencies of your Python packages or the call chain of a particular function or the way that a web request traverses the stack of software in Django applications. I don't know if you can speak to that and some of the ways that people can start to view their day to day work in the context of graphs and how that might be beneficial.
[00:38:27] Unknown:
Yeah. Definitely. So the the the way I like to, sometimes when people are presented with this idea, they think, well, no. They're no. It's not. Really, that's wrong. The the easiest way to see this is imagine that you're in an o 0 program just because it's easier to demonstrate there, and objects have references to other objects. In Python, that takes the form of attributes. If you think about the relationship between those objects, right, object a references b, maybe b references c and d, Maybe d references e and f. Whatever. Well, I just described a tree, so sometimes it's a tree. But in general, it's a graph. Right? It can branch. It can merge. Object a can reference b and c where b and c both reference d. So that's a diamond pattern.
Object a can reference b and b can reference a. So now you have a cycle. And this even just thinking about this graph structure I mean, throwing away all the fancy examples, just objects referencing each other. This actually has significant implications. So 1 of them is in Python in particular. I assume it's still the case that the that CPython has both a reference counter and a garbage collector. Tobias, is that still true? Yes. Okay. Cool. So I'm not totally out of date. So the reference counter will only work if you don't have cyclic relationships between objects, meaning, object a references b, b references c, c references back to a. In that case, you can't do reference counting because there's a cycle. So the garbage collector has to kick in. It's slower. That's why they have both systems. So if you care about performance in a Python system, you're gonna wanna think about this and not just, you know, create object cycles arbitrarily.
It also I mean, the same thing applies to your ability to reason about that code, about cyclic code. So for example, some languages disallows, circular imports. Closure, I think, is a good example of this. You can't have a module a that imports b, where b also imports a. And there are reasons for this, implementation reasons. But 1 of the reasons for this is it makes it easier for you to think about the relationships in the program because it's easier to understand a hierarchy than it is to understand an arbitrary graph where you might have cycles of of arbitrary length. You might have to go through 20 modules, and you realize you're back where you started. And you're like, that's why the system's so confusing.
So just understanding at the most basic level, the level of objects relating to other objects or modules relating to other modules, Understanding graphs is going to help you with performance stuff. It's going to help you with building systems that are easier to understand because they're hierarchical. So you can, you know, think of them in layers. Like, a a cyclic system has no layers. Right? Because you can always get back where you started. So, I've forgotten what you even said that prompted me to go on this whole tangent. But but I think it's extremely important, for all the reasons you mentioned and for these fundamental reasons as well, for actual programming.
[00:41:20] Unknown:
And just calling back 1 more time to the work that you're doing with Destroy All Software and the programming guide. I know that 1 of the series that you're currently focused on is the concept of tearing things down to their fundamental and building the backup from scratch, whether that is the fundamentals of a web framework and how requests get routed or the fundamentals of a text editor and how that handles state. So I don't know if you want to talk a bit about that before we start to close out the show. Yeah. Definitely.
[00:41:48] Unknown:
This goes back to something we talked about towards the beginning, which is I mean, I think I mentioned, you know, the reason I'm doing all of that or the or the thing that spurred me to do all that, is a recognition that there were a lot of programmers who who didn't know how any of the fundamental tools worked and didn't feel really any motivation to learn them and might those those blind spots, I think, will cost them. And so what I wanted to do was create something that is designed it's not designed to replace an education about, you know, whatever topic we're talking about, how compilers work. You know, I did a compiler, or anything like that. Because the compiler I build takes me 30 minutes, so obviously, it can't be exhaustive.
But the idea, instead of being exhaustive, is to sort of demystify it because compilers are actually extremely simple. It's only actual programming language compilers at a complex, and even not all those are are that complex. So Lua, for example, if you Google, the Lua syntax, the Lua grammar, which is at the bottom of their docs. It's very simple. It's extremely easy to read, far simpler than even Python's. So, my goal with that stuff is not to replace, exhaustive education, but rather it's just to show how simple the thing actually is and that all of the complications of it, the ones that tend to scare people off, are the same kind of complications that exist in a complex web app. So if you wanted to build, I don't know, QuickBooks online. Right? Very complex web app. That would be terrifying to even contemplate the idea of building something that complex.
But that doesn't mean that web apps themselves, are a topic that you can't broach. Right? Clearly, you can build a simple web app. You can also build a simple compiler, a simple editor. I do a web, an HTTP server from scratch. You can do all these things and they're all relatively simple. I mean, if I can do it in 30 minutes, it must be simple. Right? So so that's my sort of d my current demystification, crusade against, the parts of programming that people tend to view as too difficult.
[00:43:55] Unknown:
So for anybody who wants to follow the work that you're up to or get in touch, I'll have you add your preferred contact information to the show notes. And with that, I'll move us on into the picks. And this week, I'm going to choose the author Terry Pratchett and virtually any book he's ever written. I recently went on vacation, so we had a long car drive and we took advantage of that too, listen to a couple of his audiobooks from the Discworld series, and they are all fantastic and humorous and very well written and, just, you know, great story lines, great character development. So if you've never read a book by him or even if you have, you should go and read 1 that he's written. So, unfortunately, he has passed on, so we won't be getting any new material from him, but he has left well enough to keep you entertained. So thank you, Terry Pratchett and with that I'll pass it to you, Gary. Okay.
[00:44:43] Unknown:
I have a few things. In fact, my list has grown during this this podcast recording. So first, I will mention, DestroyAll software obviously has come up. The other thing that I do is Deconstruct which is a conference in Seattle. And and it is a it is weird and that it has no sponsors, no kind of advertisements of any kind. It is, very independent, unusually independent, and you can find out more about that by either googling Deconstruct or just going to deconstructconf.com. But as far as actually picking other people's stuff, there is a paper that I think actually is very related to a number of topics that have come up here. And it is, a paper. It is an academic paper, but it's, I think it's quite readable.
And its name is Out of the Tar Pit. And, it's not the kind of paper that's full of mathematical notation and all that kind of stuff. But, it is I think it will give you a new view of what programming at least could be. And not in the way where, like, I don't think it's utopian, but more in the sort of breaking out the patterns of thought that most of us have about programming and imagining just different ways that it can be, which is, I think a very empowering thing to do. The second thing is, a little bit harder to find. So you can find out of the tar pit if you just Google for it. You'll find a PDF. But there's a book called Algorithms plus Data Structures Equals Programs, by Worth.
And, this is the same Worth who designed Pascal. And, I I don't know. It's it doesn't have a lot of utility for today's programmer, but the reason, that it's interesting and the reason I would recommend, taking a look at a copy of it if you can find it is that it was written, as far as I can tell, I'm pretty sure, for people who are programmers, but they're only assembly programmers. And Worth is trying to convince them to use higher level languages. So it's a book that is about the what we would consider the absolute basics of programming, like what is an array and how might you actually build 1 in a programming system? It's about that kind of stuff, but you will casually assume that you know what a compiler is or that you know all these sort of what we would consider relatively advanced concepts.
So it's it's very interesting in that you it it shows you how arbitrary the set of knowledge that we consider basic or advanced actually is. It really inverts it. And, it was very surprising to me reading it at first because I didn't realize that. I didn't realize it was written for people who don't know a structured language but are actually programmers. No. That's that's absolutely fine. Okay. I have 1 more. I'm sorry. This is taking forever. But, on the topic of, of expanding your sort of the context in which you think about programming, There is a programming languages course by a professor at the University of Washington named Dan Grossman, that is really, really good. It's on Coursera, and you can also find it on, his website on, the University of Washington. We'll link to that, I'm sure.
But it's a series of videos, not of him, like, lecturing up at a chalkboard or whatever, but he actually does them as screencasts. And I think he's actually in a recording studio. And he's just an excellent teacher. They're small bite sized pieces. There's no theoretical stuff. He does it sort of in the same way that I do my stuff, which is I'm gonna open an editor and start writing code, and we're gonna explore the idea in that way, not using super abstract mathematical, terminology. And, the reason I was reminded of this during the podcast is that it is, he does use SML, which is a dialect of the ML family of languages. But if you don't know any powerful static languages, and Java and c sharp and so on do not count, so I'm talking about Haskell or the ML family, things like that. If you've never used any of those at all, take this course and it will show you why people are so excited about that stuff and what the real value is. Because if you haven't seen it firsthand, it's very easy to try to imagine it and fail to imagine it accurately. And then that allows you to dismiss it out of hand, which may not be fair to the technology.
So those are my extremely lengthy and, too long probably picks.
[00:48:51] Unknown:
And going back briefly to what you were saying too about the algorithms plus data structures equals programs, it's very easy to get caught into this state of assuming that either you know everything about everything that there that you need to know about or that everyone else knows everything, but you are terribly inexperienced. Expertise is very relative. You may be an expert in something that the person sitting next to you knows absolutely nothing about, and that's why the principle of just sharing, sharing knowledge and teaching each other and being open to new ideas is so valuable as human beings in general, but also as programmers.
[00:49:31] Unknown:
Yeah. Absolutely. That reminds me of when I was, just starting out. I mean, again, I was, you know, in my in my early teens. I sort of idolized John Carmack, who is the developer of the Doom well, all pretty much all of Doom, I think. And then the game engines that's that, succeeded it. So the Quake engine, Quake 2, Quake 3, Doom 3, all that kind of stuff. I mean, he's he's unambiguously a brilliant programmer. Like, there's no question. But it was really interesting to me. I recently saw, some kind of post that he had made in public where he revisited something that he had said, like, 12 or 15 years ago.
And it's it's a little bit buried, I think, in the text. But what he's really saying is is my judgment back then was wrong because I didn't under I didn't have enough perspective for programming to actually understand the problem I was looking at, and so I I reached a suboptimal solution. We can include that in the show notes, of course, but the really interesting thing about this is that John Carmack, who's probably 1 of the most widely respected programmers in the world and like, if you know his name, you probably think he's a great programmer. He can go back and realize that even when he was at, you know, the height of his sort of, output in terms of what we think of as, you know, his quote unquote great works or whatever, if you were gonna use a more literary terminology.
Even when he was at at that sort of peak, he was he can look back and be like, no. I didn't actually understand what I was doing. And it was all contextual. It was not that, you know, he wasn't quote unquote smart enough or whatever. It was that he had to narrow a, scope in his thinking, which is exactly what we've been talking about over and over again. So anyway, I'll make that a pick too. That post from John Carmack, we'll link that. Well, thank you very much for taking the time out of your day to join me and discuss all the work that you're up to and all of the ways
[00:51:23] Unknown:
that we can benefit from having more fundamental understanding of the work that we're doing. So I appreciate that. I appreciate your time, and I hope you enjoy the rest of your day. Alright. Well, thank you very much for having me on. I know we've talked about this a couple times over the years. So it was awesome to finally do it.
Introduction and Guest Introduction
Gary Bernhardt's Background and Early Python Experience
Challenges in Software Education
Improving Software Education and Learning Resources
Theoretical Aspects of Computer Science in Practice
Understanding Graphs and Their Importance in Programming
Demystifying Programming Tools and Concepts
Picks and Recommendations