Which Programming Language Should I Teach First?
25 points by mjn
25 points by mjn
“Your first programming language can be anything, as long as your second language makes you ask what the hell was wrong with your first.”
I think boxing yourself into a monolingual programmer is problematic & you will lack good perspective if you can only take on one language/paradigm. The minute you fully immerse in a different paradigm, you really do start to question who/what is subjectively ‘right’, which are great questions to be asking yourself.
In this light, How to Design Program’s student languages are quite cool indeed! After bashing your head against a problem and coming up with some trick around it, illustrating precisely what’s wrong with the current language, they give you a new language eliding that problem!
The way we solve the problem, is just by introducing a new symbol that solves the problem https://www.youtube.com/watch?v=8wQepGg8tHA
Love this quote! Where’s it from? I couldn’t find it anywhere
I wish I could remember! I have a feeling it was someone from the #emacs IRC channel, but it must have been like a decade ago.
If the goal is to choose a language that is:
The obvious choice is AWK.
Disclaimer: I am mainly a highschool teacher, and not a software developer.
Starting this school year, computer science is compulsory for grades 8–10 in my city. Students who want to go deeper can choose a “profil” that lets them focus on computing through grades 11 and 12.
For the compulsory course we begin with block-based programming. We’ve set up Lego robots, each paired with an iPad, so the kids can explore the logic of code without wrestling with syntax. From grade 9 onward we shift to writing code using Python.
Our Python curriculum follows the Python Crash Course book from No Starch Press. I like its incremental approach and the wealth of small exercises. We digitized the whole thing, ran up our own Jupyter servers, and now every student can code from anywhere. That portability is a lifesaver: many students have no laptop, only phones or tablets (a frustrating reality for another day). With Jupyter I can embed exercises, tests, and code cells that I edit in Emacs’ code-cells-mode.
Still there are lots of things that I dislike in Python. I dislike how casually Python treats variables. Variable a can be 32 on one line and “hello” on the next. I dislike how its readability lets students write almost-English code without grasping what’s really happening. I dislike the fact that I can’t practically teach anything using recursion, until I teach how functions work in Python. Features such as list slices are handy, lists themselves are handy, but what is a list? Python alone won’t tell you. I can’t help the feeling that knowing how to drive a car is fine, but knowing how the engine turns fuel into motion is better. I’m not advocating we start with C, yet Python’s very high level does let too much of computing’s texture slip away - I think by teaching Python, we are only teaching Python.
Ever since I first worked through SICP, I’ve thought Scheme is an elegant way to teach programming concepts. SICP’s heavy use of recursion and functional style really forces students to think, and that depth feels missing in Python. The language’s friendliness—its “literateness”—often obscures what’s happening under the hood.
Sadly Schemes relevance is being diminished. I’ve heard that MIT is moving its introductory course to Python too. I think that’s a loss. Python is wonderful, but learning Python never taught me how computers work; it only taught me Python: learning Scheme taught me how algorithms work, learning C taught me how computers work.
PS: I’ve been meaning to start working on htdp! Seems like a great book and a great concept.
Disclaimer: I am a software developer, but I consider a big part of my job as teaching the devs below me.
I’ve found that the most important thing to teach very junior people is how to solve the problems that they want to solve. That means things like recursion, what is a list really, what’s really happening in a language, all of that is really subordinate to, “How do I solve this problem?” This is a tension between “computer science” and “software development,” where obviously you want to cover the theoretical underpinning of computer software but it’s got a lot of abstraction relative to, “I make a robot go.”
I’ve been writing software professionally for about 15 years now and I’m not going to pretend I’m the best at this job, but I’ve been largely successful in my career in the environments that I’m in and I chalk that up to a practical mindset more than a theoretical basis of software. My dad was my first teacher - him being a career developer starting in the Before Times prior to the Dot Com bubble - and there were plenty of times where I’d ask a question about something and he’d say, “For now, it’s magic. Just know that it does this.” And while that might be unsatisfying to a lot of students it did help me focus on actually writing working code.
From this basis you can then begin to start backing into theory.
I can’t help the feeling that knowing how to drive a car is fine, but knowing how the engine turns fuel into motion is better.
For me, it’s really hard to conceptualize any process until I’ve had some hands-on time operating it. I can’t imagine trying to teach most students software from first principles. It’s too abstract. Some brains are wired that way and they’ll latch on nicely, but I’ve barely got two brain cells to rub together and I need to drive the car for a bit before I can internalize a mental model of an internal combustion engine. The obscurity of what’s happening under the hood is a benefit so you can first teach people how to operate the vehicle, and only once they’ve successfully operated it for a little bit you can begin to explain how those actions come to be.
To paraphrase: writing working software taught me how to think about how computers work.
The obscurity of what’s happening under the hood is a benefit so you can first teach people how to operate the vehicle
Voila abstraction! It hides complexity so you can operate something with less attention/investment. Some want to build from scratch to grok every abstraction and some want to start at the probpem level and only delve lower into the system if that abstraction turns out leaky.
I share your reservations about Python, and am also a big lisp fan.
Have you ever looked at Lua as a kind of middle-ground between Python and Scheme? It has proper lexical scope and tail-call optimization, without the awkwardness of trying to represent associative data structures using nothing but cons cells. Because of its accessibility to beginners, there is a lot of bad Lua code out there, but well-written Lua programs lean heavily on higher-order functions, and having access to full, stack-based coroutines for advanced students is a life-saver.
I’ve had some experience teaching Lua to middle-schoolers and have had it go pretty well. (Using TIC-80 to teach kids is like a secret weapon the way it includes “view source” for every game published.) In fact, the author of the Lua IDE ZeroBrane Studio works as a middle-school teacher: https://studio.zerobrane.com/
The main downside is it’s easy to make it so a typo turns an intended local reference into a global reference, which is frustrating, but using ZeroBrane or LSP makes this easy to catch.
I appreciate the suggestions, but the real advantage of Python for us isn’t subtle language feature, it’s the ecosystem. The kids already dig Jupyter Notebooks, and Python is one of the four official languages on the 12th-grade final exam (alongside Haskell, Scheme, and Java). That’s a deciding factor.
Because I manage the lab with Ansible, rolling out ZeroBrane Studio is trivial; I’ll probably experiment with it next year after I’ve had time to explore it myself.
How did your time with the middle-schoolers go? Were there any topics that turned out to be surprisingly easy (or hard) - to teach?
Python is one of the four official languages on the 12th-grade final exam (alongside Haskell, Scheme, and Java)
That’s wild that Haskell and Scheme are allowed; very cool.
How did your time with the middle-schoolers go? Were there any topics that turned out to be surprisingly easy (or hard) - to teach?
Things that were surprisingly hard:
==
for equality instead of =
; this one is so dumb and tripped them up all the time
if cond then return true else return false end
vs return cond
(but you see this in every language I think)table: 0x558e8817b7b0
so you can’t actually see your data. relatively easy to fix with a 3rd-party repl but annoying.Things that were surprisingly easy:
I’m surprised you don’t go the step higher to Fennel, solving those foot guns. Why couldn’t you teach the middlr schoolers Fennel?
Well, Fennel didn’t exist at the time, but yeah, if I had to do it over again it would be a hard decision.
If it were just about the language, then yeah, I would certainly prefer to teach Fennel, but beginners get a big multiplier applied to the difficulty of extra installation steps, work needed to get editor support, smaller amount of documentation/stack-overflow/examples, etc. You have to consider the whole experience beyond the language. (Python didn’t get where it is today on the merits of good language design.)
The blog post is coming from the perspective of a university curriculum, by which time the students ought to have encountered programming already. And at that point the main question is whether you are teaching computer science or programming as a tool for some other discipline. For most non-compsci purposes Python is going to be the right choice.
But the first step in primary school or high school (or maybe the second after Scratch) should be HTML and CSS, to get across the idea of the kind of formal notation that computers use, with its fussy punctuation. Discover the browser dev tools. Then add some Javascript and play with the REPL in the browser console.
The browser is the closest modern analogue to the 8 and 16 bit computers of 1980-1995, from the perspective of learning to program.
Hmm, is there a “JavaScript: the good parts” for modern JS?
by which time the students ought to have encountered programming already
I think that really depends on the country - in france most university students will have never touched a line of code in their life outside maybe a 4 h introduction by a dedicated educator when they were 12 year old
E.g nowadays with the NSI option, around 8 to 10% of the students that can go to university should at least have done some python before reaching university.
The blog post is coming from the perspective of a university curriculum, by which time the students ought to have encountered programming already.
Sadly not.
Even among bright teenagers nowadays, the app abstraction is so ubiquitous that most of them don’t realize that “Your phone/tablet is a computer.”
Let that sink in.
I had to break that abstraction for a couple of teenagers lately and the process is fascinating.
Watching them go from:
Watching them speedrun the stages of mobile tech grief brought a tear to my eye.
The blog post is coming from the perspective of a university curriculum, by which time the students ought to have encountered programming already.
Where in the world is that consistently true that you can expect people starting a degree to have programming experience already? Even in places where programming is part of high-school curricula it’s usually elective and the quality of teaching extremely widely variable.
And at that point the main question is whether you are teaching computer science or programming as a tool for some other discipline.
I’m not convinced of that either. Yes, if you are doing a computer science degree there are more considerations, but unless it’s a very theory-focused degree giving people a good allrounder language early on is a good idea anyways.
It would be healthy for industry (if not the wider populace) to have more elitism and require even programming tests to study computer science. To do very well, a someone should have the passion and draw to already do it before.
But that is a fairytale because of our economic structure and the expansion of unnrcessary degree requirements for work.
And at that point the main question is whether you are teaching computer science or programming as a tool for some other discipline.
Often the answer is both! Or at least some awkward mix. Which gets at the “constraints” part that Shriram’s post discusses. For example, we have considered moving our intro class in compsci away from Python, but several other degrees now require the class for their majors, and they prefer Python. We could try to ask (or force) them not to require it (e.g. by creating a separate CS101-for-nonmajors class), but that has various academic-politics and budget implications, especially at a place like ours with a small CS program.
The non-compsci audience here is also pretty diverse in what they would ideally like. While Python is the majority preference, the data-science program strongly prefers R, the game-design program mostly teaches Unity/C#, and there is an increasing smattering of data-journalism and graphic-design majors who are JS-first. And in smaller numbers there are pockets of Matlab, Fortran, and Mathematica scattered about.
edit: I forgot to add another opinion I found interesting. If you ask undergrads, a substantial number wish we had started with making mobile apps. That isn’t a language preference per se, but would imply something pretty different from what we’re teaching in the intro sequence.
From what I’ve seen and heard over the years people still can’t agree if you do “easy, common imperative language” first (Python, Java, maybe even JS?) or if you do “mathy/lispy/FP” first (I have personally had SML+Ocaml, heard about Haskell and Racket).
Hmm, is there a “JavaScript: the good parts” for modern JS?
https://javascript.info and https://eloquentjavascript.net are both good.
One nice property for the first programming language is that it is a good choice for the only programming language for the people who learn a little programming on the side and don’t become professional programmers. I think Python makes sense as the first language since it’s both reasonably useful as the only language for not-really-programmers and a good tool in a professional programmer’s toolbox even though they might go on to use a different language for most of their career.
You don’t start with them, you end with them, relative to everything else.
I don’t think ending with the programming language is the right way. At a certain moment in your learning process you have to learn which questions are important to ask.
If your first programming language is C, those questions will be different than if your first programming language is Python, or C#. And there are more questions in C.
In fact, it’s easier to from C to C# than it is the other way. Going from C to C# means: oh, less questions to ask, and less things to care about.
Going the other way is much harder. When you learn Java (and C#) as your first language in college, you create habits that aren’t compatible with how you’d solve the problem in C/C++/Rust.
You can overcome that, start with the lowest level questions, and then prune towards higher level if you don’t need the answers.
I am really unsure about using toy/synthetic languages like Pyret for teaching programming. One one hand, this does hopefully shield the student from the tedium of tooling and dependencies, but on the other, I think it misses an opportunity for training some “real” muscle.
Just for fun, let me try to reconstruct my path into programming
The only lesson I can draw from all this is that knowing multiple paradigms definitely helps with your understanding (though might alienate you to some people who have a specific way on The Right Way Of Doing Things).
as a language, pyret isn’t a toy or synthetic, it’s really superbly designed. the implementation is admittedly geared towards “teaching language running in a restricted environment”, but that’s fine for a first language; the actual programming techniques you learn from it will carry over just fine when your second language also makes you deal with an unrestricted environment, build tooling, etc
My first language in highschool was object pascal, but by the time I was in college learning Java, Ruby 1.8 was released.
Learning a language with a solid C implementation turned out to be a perfect way of getting under the hood to what really was going on.
The endless depth of that ended up being the most important part, so yeah, python works well.
ocaml and prolog should be mandatory just for making people think about what a program is at all.
“Which programming language should I teach first?” is the least productive question to ask in computer science.
Spoken like someone who doesn’t care about their students?
I’m absolutely not arguing that universities should be churning out Java consultants, but just ignoring what people might have encountered before, might be interested in, or will completely demolish their interest… is certainly an opinion. And yeah, terrible language choice can be somewhat fixed by a good curriculum in that lecture but in my experience not all lecturers are great at that.
I gave Code In Place a try this year, which used Python to introduce, programming, but started with Karel which is an interesting approach for introducing computing concepts, but for a first language Scratch from MIT can be fun for kids (and might be useful for Undergrads as well), but I would like to try Hedy which might be even more universal in its approach.
Depends on the course I guess. I like the idea of working up from C to C++ and beyond but the reality is that there are only so much hours in a course so it’s probably best to get something that has market share.
My 2 cents would be Java, I personally don’t like Java all that much but it teaches the right foundation for a lot of other paths.
Working up from zig could be really nice. It has the same experience but withuot pointless footguns and trauma. Nand2tetris to pascal to an Oberon style OS would be very cool! Or even change the course to build a prescheme and scheme OS.