Why did we ever think a student's first programming language didn't matter?
m-cacm.acm.org
m-cacm.acm.org
It would move the conversation forward if people were up front about which metric they’re trying to move. For example, here are two equally valid pedagogical goals that are in tension with each other - helping everyone become a programmer (no dropouts) and making sure every programmer meets some pre-defined criteria (strong understanding of memory layout or type theory or ability to build products). If your pre-defined criteria includes understanding of type theory, you might start with Haskell. Certainly all surviving members of your starting cohort would succeed according to your criteria, but this is only success if you didn’t mind people dropping out. Conversely, a language like python might help fewer students drop out, but they might have “weaker fundamentals” for some definition of that.
So let’s be clear about what success looks like. Let’s state a hypothesis for success and which metrics we’ll use to measure that. Let’s verify that hypothesis by offering the teaching approach to similar groups and interpreting the results.
We can do better than “I was taught like xyz, and I’m successful now and so that was definitely the right approach”.
Lastly, some people in this thread claimed that anyone can become a programmer if the teaching is good enough. On this, I’d like to paraphrase fictional food critic Anton Ego - “only now do I understand what was meant by the motto ‘Anyone Can Cook’. Not everyone can become a great artist, but a great artist can come from anywhere.”
Lets keep the standardized tests with the standardized humans: absent.
For what it's worth, the same reasoning can be heard in other fields. I work in foreign-language education, and debates about the best way to learn another language—memorize vocabulary and grammatical rules? move to a country where the language is spoken? watch a lot of movies in the language?—often reduce to competing personal success stories.
Teachers who have taught a foreign language using a particular method often come to believe that their method is the best, even though they are usually unable to measure the actual long-term outcomes for their students. It may be just too discouraging to be uncertain about the effectiveness of what one does to make a living, so teachers become advocates for whatever approach they happen to use.
At least that's my personal experience. We studied English for 11 years in school, some studied it later in university too. Every single person my age that was good at it used English outside of the classroom - mostly on the internet. They had enough experience that even without knowing the grammar rules they got the right answers "because it felt right".
I think this applies to learning anything else that requires to recognize patterns works in the same way: programming, mathematics, listening to a different language, reading handwriting, fighting difficult bosses in video games etc. You can theoretically understand all the pieces, but still be incapable of utilizing them for a satisfactory result.
You just gave me an epiphany about why I am having a hard time creating music.
Here's some metrics we should measure a "system for programming education," of whatever form, against.
--Success is measured against new students with zero programming background.
Todo would be defining zero programming background.
Ideally people who've never evaluated a statement before AND never used a CLI interface AND without an amazing mathematical background.
--Students do not feel regret, unhappiness or anxiety before they start or after they finish a 1-2 hour programming session. Students want to program in the future. All other things being equal.
--The level of expertise to target for a "solid programmer" is creating discrete systems using higher order abstractions from scratch. Whilst using a strong mental model of what higher order abstractions actually look like in their physical state to improve their creations.
A secondary KPI might be "can the student make a compiler." But a mental model of what higher order abstractions actually look like in logical state seems like a good goal.
--Currently underrepresented cultural backgrounds show end state success at the same rate as other cultural backgrounds, all other things being equal.
Programming stuff is difficult, when there are difficult academic barriers to overcome people on the south side of social inequality fail more. Thus it needs to be a metric.
--Could possibly program for money?.
-Measure success against "never done it before with average mathematics."
-End goal is able to make cool things with a mental model of fundamental logical state that helps at creating things in higher abstractions.
-No discriminatory bad news.
-No traumatizing for life and making them hate instructing computers.
-Employable?
Either interpretation of ‘Anyone Can Cook.’ Cooking isn't just about being great art. Neither is programming.
Lets not forget that a lot of programming is making something like salesforce do something after an employee does some other thing with their account... Proverbial (and literal) CRUD. The practical requirement for this job is (1)"can program," (2)"knows how salesforce works," and (3)"can reach an understanding for what the problem is."
There's a real tendency to downplay this "use case" for an education in programming, but this is a lot of what most programmers do for a living. Whether or not it's simple, it is definitely not trivial in the sense that most people do it well. In isolation, the "can program" bar is not that high.
Programming for non-professionals looks a lot more like Excel than Python. I imagine the trend will continue where deceptively simple interfaces allow people to automate routine tasks. Those interfaces might get more expressive languages, but most programs will be at most a dozen lines long.
That's the kind of language I think we should start with. We can worry about more detailed CS topics for the students who actually specialize in that.
> In the US, 14% of the adult population is at the "below basic" level for prose literacy; 12% are at the "below basic" level for document literacy, and 22% are at that level for quantitative literacy. Only 13% of the population is proficient in each of these three areas—able to compare viewpoints in two editorials; interpret a table about blood pressure, age, and physical activity; or compute and compare the cost per ounce of food items.
https://en.wikipedia.org/wiki/Functional_illiteracy
Plus stuff like this:
https://eufactcheck.eu/factcheck/true-we-have-42-functional-...
And keep in mind Romania is average at a world level, economically, maybe even slightly higher than average.
On top of that programming is based on logic (for the layman who doesn't want to think of it as based on math; and let's not go into the layman's clear separation between logic and math), so it for sure has an extra difficulty level compared to reading or writing.
To say programming is never to attain such a characteristic is making a statement against the trends of history in all other academic disciplines. Focusing on the present state is an ignorance of underlying trend.
A couple thousand years ago, groundbreaking advances in trigonometry were made by some of the worlds smartest people. Today the average high schooler knows soh cah toa.
But if these advances take centuries, from a purely personal perspective they don't matter much. By then, I, and everyone I have and will ever know, will be dead.
In the long term, we're all dead.
Though I obviously appreciate progress :-)
And what about coding boot camps? Again, they have put umpteen more people to work as programmers. (Are they more than universities yet?) Again, you don't have to love them, but they are lowering the bar and helping more people gain access to the programmers market.
It's gotten ever so easy to learn and write programs, and people still don't do it.
That ticks the boxes of deceptively simple interface and programs a few lines long.
It also won't require as much formal training and will be more intuitive and trial error based.
GPT-3 and DALL-E have given us a glimpse of what that will look like.
I think the biggest obstacle standing between the general populace and computers is the amount of detail one has to provide for a task to become programmable. But it comes up in real life as well.
It's one of those things that is always 20 years away, like nuclear fusion.
Or maybe I'm just spending too much time with biologists.
For that to work you need some equivalent of unix's `|` for disparate systems.
It's been tried but the problem becomes a sufficiently expressive interface between systems.
There is a reason why in 2021 I still occasionally dump stuff to CSV and re-import somewhere else.
Programming is like, using mathematical structure to instruct a computer.
But many domains don't need you to use mathematics to instruct the computer. Natural language processing, like a search bar, GUI, .
Medicine, legal, so many other trades don't need mathematical instruction of a computer.
They just need not-totally-useless operation of it, through
Which one?
I'm saying that "because" you don't need operations defined mathematically, you can use whatever human computer interface.
“Programming fundamentals” isn’t the same from language to language. It’s inconceivable that a student who learned to program with python would develop the same type of fundamental understanding as a student who used C (to develop an understanding of memory-level APIs) or Haskell (to develop an understanding of type and semantic theories).
> which is a failure of teaching and testing, not some sort of 'limitation' in the student.
This is a bold claim. I don’t think everyone can understand computer science.
Every language can do some form of if then else be it machine code with goto’s or purely functional. Ask someone to find the absolute value of a number and they should be able to quickly figure out something that works in a new language. The basics of programming are not about being correct so much as not being lost.
Uh, not exactly. I had a really hard time learning prolog because it doesn't really have if-then-else. Haskell is missing the idea of something happening after something else. Stack languages don't have variables. And so on - there's a lot more to programming than python.
There's a big class of popular structured / OO languages which are quite similar (C, JS, Python, Java, etc). But they certainly aren't "every language". Not by a long shot.
And even amongst those languages there's huge variety in how the grain of the languages shape the code we write. I was talking to a grizzled old programmer at a conference a few years ago about the performance of java vs C. He said in some benchmarks he did the performance was almost identical. I got him to show me his code - and sure enough, he wrote java as if it were C. He was using native java arrays everywhere and basically everything was a primitive variable, in huge classes acting more as buckets for code than anything else. His code was unrecognisable as java because he was still writing C, just with a different syntax.
> The basics of programming are not about being correct so much as not being lost.
The basis of programming is expression. The most idiomatic way to express yourself in each language is very different. Its as much cultural as it is syntactic.
> Haskell is missing the idea of something happening after something else
A Monad is implicitly a monoid, which certainly does specify an ordering. And as for expressions, the order of evaluation of arguments is not specified either by C for example.
In Common Lisp the if-then-else construct is IF. The "something happening after something else" construct is PROGN. The whole point of if-then-else is that only one thing happens; "something happening after something else" requires a minimum of two things.
This is true only in a pure functional language; if you admit the existence of side effects, then it is a crucial part of an if statement that the code associated with the other branch is never executed.
My point is just that it makes no sense to say "some languages have no form of if statement; for example, Haskell doesn't have the concept of one thing happening after something else". That example is untrue. But if it were true, it still would not interfere with Haskell's ability to have an if statement. Thus, defending Haskell's ability to run one statement after another statement is unnecessary to refute the claim; the claim never worked in the first place.
if' :: Bool -> a -> a -> a
if' True x _ = x
if' False _ y = y
https://wiki.haskell.org/If-then-elseAlso, Java was designed to handle performance critical code like that. That’s why people call it a fast language, you can write non performance critical code however you want, but optimize for speed and it’s going to look like C.
> Also, Java was designed to handle performance critical code like that. That’s why people call it a fast language
Sure; but my point is that idiomatic java looks quite different from idiomatic C. If your first language is C, its easy to write java that looks like C. If your first language is java, you can torture C into looking like a bad version of java. But both approaches are newbie mistakes. Learning a language involves a lot more than just being able to make programs that work at all. Its also learning a culture, and learning to make code that fits well with the existing ecosystem. You won't get very far in the java programming community if you don't know how to write java in the popular style.
Thats why they say learning your second language is difficult. You need to unlearn some of how you approach programming so you can come at your second language with fresh eyes.
If you only know enough Java to be able to translate awkwardly from C, you aren’t fluent in Java. I know bits and pieces of Haskell - probably enough to make working programs. But I’m not fluent in Haskell. I can’t read the code others write. I can’t think in Haskell. And that’s not enough.
“Professional” is not what most people mean when they talk about the basics as say a welder, cook, etc.
I learned to program as a child (I taught myself, for fun!) but I didn't learn much computer science until well into adulthood.
For example, if you just look at GUIs created using Excel/VBA, you will find they seem to need endless tweaking to work just right (edge cases?), but do not at all require a formal CS degree. (I have worked with many non-CS people who are fine a mid-level Excel/VBA stuff.)
You should be able to carry very, very basic concepts over to other languages with much less difficulty than learning them the first time. A student sufficiently skilled in Python will be able to make the same intro level programs in C given enough time. Badly? Yes, but they'll function.
Similarly, a watercolor artist won't forget the basics of art when handed a pencil.
Well, sure. For some values of sufficiently and enough.
Enough time: however long it takes them to learn the syntax of the second language + the time it took to complete the project in the first language.
Unfortunately I can't give decimal precision hour estimates.
This is a bold claim. None of us are special for working in tech. Our life has presented us the opportunity and passion to invest ourselves deeply in the field, often at great opportunity cost.
Saying that a bad teacher makes no difference in student outcomes is equally ridiculous as saying an excellent teacher makes no difference in student outcomes. If that's the case, we should be able to replace professors with cardboard cutouts, no? I was a student and TA long enough to witness directly the impact that a thoughtful curriculum can have on students.
I agree that the whole bad vs. good teachers thing is off-topic, though.
And sure, the statement "not everyone can understand computer science" is technically true if you include people with mental disabilities. But in reality, some people draw the line a lot higher as a form of gatekeeping. I've known a number of professors who let themselves off the hook this way too: Poor student performance couldn't possibly be a failure of their teaching--the students must not be smart enough!
Other students seem to learn programming extremely easily. I would show them something one day, and the next day they've already used what I showed them in their code.
I'm open to the hypothesis that its my fault that some of my students failed to learn programming. I certainly felt terrible for them when they worked really hard and still failed. But I don't think its all me. I certainly can't take equal credit for the students who did very well. My star students seemed like they barely needed me to teach them anything at all.
And for what its worth, the perspective that talent doesn't matter is an awful thing to teach struggling students if its wrong. Students hear that as "If I struggle at programming it must be my fault". I don't think it is. I think some people just have brains wired to make programming easier or harder to learn. There's no shame in encouraging some people to pick a different career. If programming really isn't right for someone, the sooner they swap to something else, the better.
* The student might have other stuff going on in their life at the time. Heavy course load, personal drama, etc..
* The student might have other interests, so they don't devote as much time to studying as they should.
* The student might not yet have had a good math education, so their abstract reasoning skills lag behind. I think it can still be learned, but someone in a college compsci course just doesn't have time to catch up.
I've been an undergrad/grad TA as well as a tutor for high school students in math/programming. My own experience tells me that learning is very "path-dependent". Students will be more receptive to my way of teaching if their background is similar to my own. Part of my job as a teacher is (was) to try to recognize the gaps in their background, but sometimes I do have a lot of trouble understanding what path a student took before coming to me, so it's harder for me to help them.
And looking at my kids, this stuff matters a lot. A kid that comes in with complete zero experience has massive disadvantage against one with some experience.
The entire first year of CS courses was mostly there to instill fundamental computer skills (not CS skills!) in the ones without that preexisting knowledge.
I read a paper over a decade ago talking about this. They gave a survey to freshman students and looked for correlations with their end of semester marks. They found the students who assumed there was a consistent set of rules underpinning programming (even if they didn't know what those rules were) dramatically outperformed the students who thought the computer would "work it out somehow".
This stuff is not taught here. You either know it or are seen as lost cause.
Even more importantly, I had those games that introduced you to loops, ifs, variables, programming in general.
I teach math at a community college an I'm absolutely convinced not everyone can understand math. I'm not a great teacher and I think I'm not a terrible teacher. I've come to the following conclusion. For some people the effort required to learn the material given their natural ability is so high that they'll never get it. They won't be able to put in the effort required.
I could be wrong though and might be one of the people who let themselves off the hook as you mentioned.
Computer occupations as a whole have a median intelligence at least 1stddev in excess of the population median. https://www.gwern.net/docs/iq/2002-hauser.pdf I have to imagine that programmers in particular are even higher.
Bootcamps took off shortly after I graduated from my top-ranked CS program, and I remember being extremely dismissive of their value: there was no way that you could fit the four years of my CS degree into ten weeks. I've since realized that being good at Computer Science grossly overqualifies you for many programming jobs, and that bootcamps do a great job of giving reasonably smart people an on-ramp to these jobs. I know three separate people who jumpstarted six-figure careers from scratch after attending a bootcamp: one was a waitress, one an artist, and one's entire career thus far consisted of a decade of changing tires at Costco. One of the three wasn't college-educated, and two were first-generation Mexican immigrants (as children) from working-class families, belying the assumption that privilege and educational access fully explains programming ability. Unsurprisingly, all three are fairly intelligent people.
I can't think of another industry that has a similarly egalitarian entry path, and I think a very plausible explanation is that suitability for these types of entry-level programming jobs is little more than a test for high IQ (relative to the population norm).
This is my experience as well. During an ill-advised foray into building the tech org for a mediocre startup with a poor candidate pipeline, the quality of candidates we got was so poor and the work we were hiring for so easy that I pretty immediately found myself dropping every requirement except for knowledge of basic programming + intelligence. This worked pretty well: The no-experience, very-smart guy that I strongly recommended hiring became the capable workhorse of the eng team, and the dumb guy with a decade of experience that the founders hired over my objection was an absolute dumpster fire, unable to work with any autonomy and bounced from area to area in an effort to find a place where he would do the least damage.
IQ has always been a good indicator of programming skill. Unfortunately school grades and specialisation aren't a good indicator of IQ, and (I think?) it's illegal in the US to require job candidates to take IQ tests.
So the issue for companies is that without the usual whiteboarding or educational paper trail you have to find a way to identify high IQ people without being too obvious about it.
The other issue is if you find no-experience very-smart people you have to spend time training them before they start being productive. This works if you're not in a hurry, but it's harder to justify when runway is limited.
> So the issue for companies is that without the usual whiteboarding or educational paper trail you have to find a way to identify high IQ people without being too obvious about it.
Yup. I was surprised to find myself gravitating to this through trial-and-error, since I had pretty thoroughly absorbed my affluent coastal background's bullshit religious conviction in the pure blank slate of every human mind and the uselessness of intelligence as a distinct concept.
> The other issue is if you find no-experience very-smart people you have to spend time training them before they start being productive. This works if you're not in a hurry, but it's harder to justify when runway is limited.
Right, the other ingredient that I mentioned was that the engineering work we needed didn't require any specific skills. The vast majority of our engineering work was just a Python backend, which is about as "pure" an exercise of manipulating logic as you get in engineering.
Thank you. What a naked and honest thing to say on HackerNews. My brother is so much smarter than me. I went the CompSci route and suffered (toiled!) for years at a university. His boot camp was less than three months and he landed a just fine job. Internally, I was incredibly dismissive of his boot camp, but was proven wrong (again!) by my own horrible elitism.
No everyone needs to be working on cutting edge ML/AI. My brother makes websites for shopping. (Yay.) His income easily doubled after a year of cutting his teeth.
> This is a bold claim.
I disagree. What makes computer science so special that it can be understood by everyone, while it is generally accepted that other disciplines cannot?
After all, saying "Not everyone can understand chemistry" doesn't draw the same ire.
People who can do any version of STEM with some minimal basic competence are unusual. They're not exceptionally unusual, but they're certainly not the population median.
Media numeracy is around Level 3 on this list. Numeracy in the US is lower than the OECD median and is somewhere between Levels 2 and 3.
https://www.nationalnumeracy.org.uk/about/what-numeracy/what...
I'd estimate you need Level 4 for programming to make any sense at all and maybe get you started with very simple programming tasks, Level 5 to be able to do basic code construction on a daily basis, and Level 6 to be a competent senior with some useful modelling skills.
Level 5 is maybe 20-25% of the population. Level 6 is probably less than 10%.
Those who think anyone can learn programming should pick an acquaintance ages 25-45 who has sufficient time, and attempt to teach them to program, and see the results. Or inquire about the actual success rates of coding bootcamps (which are already self selected groups and have filters themselves, far from the average population to begin with).
I've done the above with very mixed results, it's pretty clear that for a litany of reasons the average person is functionally incapable of being a useful programmer. I don't see the average citizen coding a lot in the next few decades, even casually.
Perhaps I should be a little more specific. When I say "everyone" below, I mean "the overwhelming majority of people in the average range of human intelligence, without debilitating mental deficiencies". This group spans virtually everyone you are likely to encounter, from car mechanics to school teachers, to postal workers, to professional software engineers.
People have blind spots, but in general they're pretty smart when it comes to the things they think about every day. I believe:
* Everyone has the mental capacity to learn $RANDOM_DISCIPLINE if they put in the time and effort. A good teacher can dramatically accelerate the process, while a bad teacher can bring the process to a grinding halt.
* Everyone has a limit to how well they can understand $RANDOM_DISCIPLINE, (even Terrence Tao) but most careers do not demand that workers reach that limit. One can be a successful researcher without performing at the same level as Terrence Tao. One can be a successful software engineer without being a computer science researcher. One can understand advanced topics in math or computer science or chemistry without having personally discovered them. One can work as a chemistry lab technician, or a high-school chemistry teacher without winning a Nobel prize.
You can replace $RANDOM_DISCIPLINE with things like "computer science", "constitutional law", "how to reassemble a car", "chemistry", etc.. If you start getting very specific, you might be able to get me to disagree with statements like "Not everybody has the mental capacity to have invented Inter-universal Teichmuller Theory".
At least 5% of the population can’t understand algebra. If you can’t do algebra then you might be able to follow recipes but you can’t do chemistry. Without algebra you can’t do stochiometry and that’s essential for even high school level chemistry.
I invite you to tutor some middle school students then. For values of algebra that include “can be taught to draw the appropriate line given the corresponding equation” there are plenty who can’t understand algebra.
No powers, quadratic equation or differentiation and the like yet, but I can see the QE coming up in next years books (which we recently bought since 3rd grade just finished)
I’m pretty sure that when I was at school, this was a “senior school” (age 11-16) topic, and I was maybe 12 or 13. Kids are learning stuff earlier than they used to, at least it feels that way to me.
That's a very low bar, though. It would mean that 95% (ok, maybe slightly less) of everyone out there would be able to understand chemistry.
I think there is a huge difference between currently being unable to understand something and being unable to understand something indefinitly (e.g. because you have mental deficiency that blocks you from forming the necessary pictures in your mind).
Having thought math to mentally challenged kids, I had only one kid where I would really say he could not learn algebra at that point of his life. Mainly because he had a memory span of 10 minutes and severe developmental issues.
All the other kids where really bad at math, but given the right effort I could really improve things by just working on their stuff for 1 hour a day.
I know many tech guys like to see themselves as some kind of elite that has a secret knowledge very few others can master. But in my eyes that is just a failure of an education system.
A programmer can make a song. A musician can make a program. I'm sure you could train those kids to sing as well. I'm sure you could train those kids to play basketball.
You wouldn't be able to train them enough to make any professional league.
Programming is genetic. Recently I met my birthparents and I discovered the whole family are programmers. I thought I came up with the idea myself I pushed myself through school. No one in my highschool did programming or elemetry school. I thought I determined my own choices.. I was proud of the unique path.. then I met the birthparents and realized how predetermined everything is.
Good educators will always target multiple of those patterns. Bad educators always target the same pattern and will therefore only have auccess with the same kind of person.
I am currently teaching electronics and programming to artists who quite uniformly hated math and physics in school, and it kinda works. You just cannot teach it in the way they would teach it to a STEM student.
I didn't say that I did. My belief is irrelevant anyway, because it is generally accepted when someone says "not everyone can understand chemistry".
I was pointing out that saying such a thing only draws ire if you say it about CS.
> When I say "everyone" below, I mean "the overwhelming majority of people in the average range of human intelligence, without debilitating mental deficiencies". This group spans virtually everyone you are likely to encounter, from car mechanics to school teachers, to postal workers, to professional software engineers.
And yet there is no controversy if postal workers, car mechanics and hairdressers say that they are not able to understand chemistry. There is only controversy for CS.
I feel that you would do well to explain why only CS is controversial, while chemistry, auto mechanic and art is never controversial in regard to this particular assertion.
That isn't my premise. My premise is that saying such a thing isn't a bold claim, it's a commonly accepted claim.
When you said "This is a bold claim", I replied with "I disagree", because "Some people just aren't any good at $DISCIPLINE" isn't a bold claim.
I am a physical embodiment of a person who can not understand chemistry. Basics hell yes, organic chemistry for most parts yes, process chemistry ... iffily, but when it comes to physical chemistry, I'm hopeless. And I tried. Over many years. I changed my major in university from chemical engineering to CS because my head simply would not work the way you need it to work in physical chemistry.
On the upside, I think there are surprising parallels that have made my recent life (~15 years) easier because of the lessons I picked up from chemical engineering. Conflicting feedback loops, S-curves and equilibrium states are not that different from the concepts and safeguards you encounter in distributed systems.
I know that this feels like something that should be true in an ideal, just world or in the HN-reading bubble, but I've never agreed with this. I know people who are incredibly smart, I know average people who are not very intelligent, but are fairly knowledgeable, I know rather simple people who live simple lives, and I know people who are, bluntly said, absolutely fucking stupid.
I am absolutely sure that I know people who wouldn't be able to get from zero to doing my job exactly the way I do it (and I'm certainly no rockstar programmer, I'm like in the bottom 10 % here) in any reasonable timespan, like 20 years even. I would literally bet any amount of money on it.
I often tried helping friends and classmates, in one-on-one sessions, to understand basic (primary and/or high school) math. Sometimes, you just end giving up. This was after trying a number of different approaches, different learning techniques, different ways of understanding / visualising abstract concepts, etc.
Not everyone can understand abstract concepts (or our teaching methods are too primitive).
However only a few have what it takes to regularly sit in front of a computer and power through long term. It’s definitely special for better or worse. Let’s face it: We’re nerds!
"That document was very misleading and, in the way of web documents, it continues to mislead to this day. I need to make an explicit retraction of what it claimed. Dehnadi didn’t discover a programming aptitude test. He didn’t find a way of dividing programming sheep from non-programming goats. We hadn’t shown that nature trumps nurture. Just a phenomenon and a prediction."
You could think of there being a universe U of programming fundamentals. Each language uses a subset of U as the language's fundamentals (no language uses all of it), and each language uses a different subset.
Some languages have subsets that overlap, but that isn't always obvious, because they clothe the same thing in different syntax and, sometimes, different semantics. Even when the semantics are the same, they talk about the semantics using different terms.
So the problems with transferring knowledge of the fundamentals from one language to another are that they aren't the same fundamentals (different subsets of U), and that they are expressed in different terms and in different syntax. That can make it hard to recognize that the parts that are in common actually are the same. And then there's the new parts.
Now here's a class in C#. One student comes in knowing Haskell; one comes in knowing Python; and one comes in knowing C. The "fundamentals to transfer" differ from student to student. It's asking a lot for the teacher to be able to help each student recognize what part of their background transfers, what part of C# it transfers to, and what the deeper fundamentals are that are expressed in both languages. An exceptional teacher could certainly do so, but as the adjective implies, such teachers are the exception.
But it's not really fair to blame the student, either. It's asking a lot of a 19-year-old to understand deeply enough to make those connections.
My own guess is that this happens best after working as a professional for several years, and in more than one language. Then it's somewhat easier to see what's going on "under the hood" of the languages.
I think this is a pretty good point and it touches upon something I was thinking about: what language you use to introduce students to computer science says a lot (not everything!) about your pedagogical attitude towards what "computer science" is. If you think that it's fundamentally about humans interacting with machines, then low level languages make sense. If you think it's fundamentally about math, then functional languages make sense. If you think it's about building things which provide a lot of real-world value, then something like Python makes sense. Now of course (1) students probably need to learn about all three at some point; and (2) there are a number of other factors here, perhaps most importantly making the material enjoyable, approachable, and rewarding for students such that they'll want to delve into each of these aspects.
I will never forget the moment 11 year old me saw a message box appear with text that I specified. I made that happen, I built it. I felt so powerful and cool. That 1 line of code in an obscure language got me hooked and over time I moved on to other languages.
People see what they do and have instant visual feedback.
It's crazy that programmers think this to me and just a form of ingrained tribalism that tells them that what they do is somehow special. Probably because they get such crazy time-valuations in terms of salary. But that's just a supply and demand curve.
Concretely, I can't fathom how people learn Rust without learning one of C or C++ first, and I'd think the underpinnings of how you understand code and systems is probably different if you are subconsciously mapping new concepts back to Python or Java or whatever.
C++ overall obviously isn't simpler then Rust; C++ in its entirety so complicated it's like three languages stapled together. But with C++ as first language, you can study programming for 6 months before ever even hearing about std::move, and with Rust you'd need to already learn about move semantics on like week 3, when people are still having trouble with loops
Some students (and programmers) can excel in one programming language and struggle with a different one. Programmers don't want to admit this because it suggests a superficial focus on syntax.
Developers often say: it's semantics that matter in programming, not syntax. But you can't separate syntax from semantics - they are so closely entwined. And for many developers it shapes the way they solve problems (me included).
Some programmers develop a deep understanding of semantics that makes them easily see beyond syntax regardless of the language. I'm definitely not one of them. Dare I suggest (with no judgement), that a substantial number of programmers, possibly even the majority, also find it difficult to see beyond syntax for more complex programming topics?
Aside: A tweet from Sahil Lavingia (founder of Gumroad) from 2019:
"For those who think they can't learn how to code: try another language.
I tried PHP a few times and gave up. Then JavaScript: gave up.
Then the iPhone came out, I tried iOS development, and everything started to click!"
I'm not sure "do SICP exercises in scheme having learned Python/C++" is really about transferring programming fundamentals. The SICP exercises seemed really geared towards a small lisp.
Maybe I was a shitty student but I think I went to a general well taught undergrad program that grounded me in the various concepts (although not functional programming and lambda calculus - that was a pure CS-only thing at the time). It took a long time to actually build that level of intuition through experience. I wouldn’t expect someone who is just out of college to have that trait but it is to me a strong signal of seniority (eg you can start helping someone proficient in the language/more familiar with a codebase try to spot tricky system performance issues because you know what kinds of things to Google). Similarly language fluidity is a skill that not everyone develops (due to whatever mix of available time, interest, or natural talent) and that’s also OK. There are plenty of meaningful contributions made by people who only specialize in expressing all the CS concepts in one language and that’s OK too (or even just building useful tools/OSS contributions that are unrelated to CS topics).
But the fundamentals of different classes of programming languages differ. For instance, Haskell's model of computation is not Turing machine but a G-Machine. It's a different matter that G-Machine and Turing machine are equivalent and that doesn't mean learning one is sufficient to understand the other. There is very little that can be transferred between the two.
To take another example, Javascript supports continuation passing style coding where as Java didn't until very recently.
Can you teach "programming" without conveying a fundamental model of how the machine operates.
Should you?
Because how the machine operates is very simple.
Fundamental units of state are read from memory to an evaluator, evaluated to extract meaning, and this can result in units of state being written to/assigned depending on certain conditions.
Data structures are a complex arrangement of state that has meaning other than the literal evaluation of said fundamental units. Algorithms are logically proven concepts represented in state. Compilers are a tool for converting "abstracted instructions designed for humans to work quickly in" into operations supported in hardware.
How each language abstracts it is pretty secondary.
There are so many unanswered questions in programming education.
"Whether you should attempt to teach the model of fundamental state" to all novice programmers, or just a few shorthand rules, is the biggest.
When I was a wee coder I thought BASIC was the bee's knees. I don't think that any more, but it was a painful series of transitions until I discovered Lisp and never looked back.
Learning C (and even a little ASM), gives a better understanding of the underlying layers. I think that provides a great foundation for learning a scheme, and then branching out from there.
Also, for a lot of first-time programmers, Scheme and other lispy languages, can come with heavier cognitive friction.
Unlike procedural languages where you can think about what you want to do, break it down into steps, and then make those steps, there is a higher-level (or deeper-level, if you like) of thinking that needs to goes into functional development, where one thing feeds into the next which feeds into the next.
If you already have a very strong background in mathematical theory, this might not be so bad (and might make a lot more logical sense), but it is a shift in thinking from how many people do day-to-day tasks, which is more similar to procedural programming.
While I understand where this is coming from, can you suggest any language that is closer to the mental model of how the underlying hardware works than C (other than assembly)?
But my point was more like, there is no reasonable difference between eg. C and another language that compiles down to machine code — the old saying that a seasoned C programmer can reasonably guess the created machine code of a program is no longer true with today’s heavily optimizing compilers and the amount of magic happening is almost comparable to eg. Haskell.
Memory handling of course is the other big area. So many developers grown only on higher level languages have varying level of confusion about memory allocation, passing buffers around by copying vs. pointers, modifying memory vs. copy on write vs. reallocating everything. You couldn't possibly come out confused by any of this after a solid stint in C.
And just like threads, it's very valuable understanding even if later you mostly program in higher level languages.
So yes, while it certainly true that in the 80s you could squint at C code and see the generated assembly code, and that's no longer necessarily true today, it is still true that having a solid foundation in C will help tremendously in understanding what's going in the CPU and memory in ways that probably no other language (that I'm aware of) will help you learn.
I do need to spend a solid season in Rust sometime to have a deeper opinion about it!
At the same time they had the Scheme-based course (and possibly before, but I know at this point) they also offered a MATLAB-based introduction for non-CS/CMPE/EE students (EE and CMPE had to take the first 2 or 3, respectively, CS courses with the CS majors as part of their degree program). This MATLAB course was targeted more towards ME, AE and other majors who really just needed something that let them write programs to solve problems in their domain. Many of them did much better. The problems assigned were better motivated for them and they were able to apply it within their broader course of study or internships or research work.
That a first course should be appropriate to the desired outcome for the students seems obvious, I'm rather surprised there's much debate around this topic.
Some of it was so silly that I was accused of cheating in the C course for using and citing the hashtable implementation from the assigned textbook. On just talking to the graders and professor, they dropped it and were amused that anyone used the book.
For the other sciences, they would shake up the rules on how to capitalize figures. Idea being that cheaters would use last year's rules. Or, lazy people would just not pay attention..
It wasn't really overblown, it was a problem with that course. The instructors and TAs were grossly unprepared to teach hundreds of freshman a semester in a language they (the instructors and TAs) weren't familiar with that was fundamentally harder (especially for an arbitrary student rather than those actually interested in the topic) than what was done before.
The rest of my comment was about appropriateness of the first course to the students and their objectives. MATLAB being a much better first language for the engineering majors than the general CS requirement provided.
So, yes. They had evidence of massive cheating on a level they had never seen. They also had evidence of near incompetence in teaching at a rate never seen before. Not shockingly, they focused on the cheating.
My assertion is that the behavior in the cs students was no different from any other students. They just had more mechanical grading schemes and were less prepared to teach such a variety of students.
Edit: and apologies for skipping the Matlab assertion. As an EE at the time, that was my intro. I don't recall it being particularly good. Or bad. It just was. They shifted to java soon for many folks. As someone that was a TA for the Java classes. Then the VHDL classes. Then the C classes. I can't really see any benefit of any one over the others.
Though I couldn’t read the full article, but that’s what it seemed to say in the first two paragraphs.
There seems to be two slashdot threads discussing the issue from 2002. Perhaps it was worse after you left?
[1] https://www.chronicle.com/article/georgia-tech-concludes-che...
Rather, a lot of what they classify as cheating in that time was stupid close to standard practice for sorority and fraternity members. Having banks of previous years tests and assignments, for example. (I say this as someone that was not in one, so mayhap I am misrepresenting.)
So, my request for hard evidence is mainly to get to a root cause and to establish norms and base rates of behaviors. Yes, it could have gotten worse or had some bad years. It feels highly suspicious that it just happened to correspond with the rust of automated graders. Yes, coincidences happen. Feels really shaky, though.
As of 2016, CS1301 was still in Python. CS1331 was in Java. MATLAB was present either in specialized CS classes (like computer vision) or in the Intro To CS for Engineers (CS1371). Not aware if it remained this way afterwards though.
Depending on who you ask, a first programming language (I'll say 1PL to reduce repetition of the phrase) should do one or more of the following:
1) Be practically useful even if the student drops computer science immediately.
2) Be low-level enough to teach the fundamentals of what's really going on with the machine.
3) Be high-level enough to teach the fundamentals of true computer science.
4) Be stringent enough to allow the users to learn precision in their programming.
5) Be lax enough to allow the users to not get bogged down in endless boilerplate.
6) Be in common usage to help ensure immediate practical users for the language.
7) Be an exotic to avoid turning the first year and a half of CS courses into a competition to see who spent the most of their formative years messing with computers.
8) Bonus round: claim that the 1PL is a bogus fixation and instead the learners should learn several different languages.
The problem with all these arguments is that they are all sorta-kinda true, but the consistent application of even a few of them result in a learning load that would result in the first year of computer science (or some "intro to programming" course) being not so much a major but a 2-3 year full time job carried out to the exclusion of all else.
It might make a lot more sense to think not about the 1PL but how the 2ndPL, 3rdPL, etc. are introduced and when. Instead of overloading the 1PL with a host of contradictory and pretentious goals, maybe we teach people the basics of programming as quickly as possible and move on?
For my part, I think the experience of the 1PL should be focused on usability and fun. I'm not really a fan of the whole Java thing for reasons not germane to this, but "Processing" really had a whiff of what was fun about messing around with Commodore 64 BASIC back in the day. Maybe that's more important than making sure that the language in which everyone adds up columns of numbers and prints an invoice for some fucking stupid imaginary warehouse application properly inculcates everyone into the One True Way of Thinking About Computing, whether that's being close to the hardware, or being able to write metacircular interpreters, or be a service course for some miserable engineering department.
The fact is, most of these first-year courses are dull, miserable and unappealing.
As a bonus, it is close enough to (Java, C, etc.) that the move to a next language should be pretty straightforward.
One of them also did a ton of Scratch, which is very different in a bunch of ways - and he seemed to spent a lot of time wrestling with the fundamental limitations of Scratch. It felt so specific to Scratch that I often felt like what Scratch led to was, well, more Scratch - and also getting caught up in the politics of putting things up on their public forum.
I felt that both Processing and Scratch certainly hit the 'fun' point, and that Processing also had the advantage of being a lot closer to actual coding. I imagine that there are probably also JavaScript setups that might tick some of these boxes too.
Folks getting huffy about the fact that people aren't learning metacircular interpreters or assembly code (or logic gates!) right off the bat forget that (a) even the basics of solid imperative programming, and the inexorable way the computer does what you told it to, not what you "meant" is hard enough and plenty to get started with and (b) computing is one of many things people could be doing with their time, and making it shitty and esoteric and unpleasant to pass some purity test is not going to necessarily attract the people you want in the field.
Notably the latter point - weird culty languages, ultra-low level approaches, etc - are going to filter out your students down to the people who knew from Day 1 they were going to be computer scientists. Nerds, like me. This is by no means going to filter people down to the 'best possible student cohort'.
Then: "while some of us had done it for 15 years" -- I'm confused. Are some people learning to program a 3 years old? This is breaking new records for HN exceptionalism.
At one time, computer science required a good understand of what's in Vol. 1 of Knuth. That's not in much demand any more. Just about everything in there you now get from a well-debugged library.
There are people who still write hash tables, and they're serious hash table theorists. I'm impressed with how good hash table technology is today. You can get over 90%+ fill and near-constant time. But only a few people today need to know about that.
Usually you find people like this making libraries or programming language runtimes I guess.
I just linked to a google search on "hash tables" because that's what you asked for, but some of his other posts are really quite fascinating.
I'll believe that when employers stop giving preference to people with university credentials.
Until they do that, the primary reason most people go to university for CS will continue to be 'for vocational training.' People follow incentives.
Just because there is a need for vocational experts doesn't mean the universities should try to fill it. The place in society for universities is not a short-term-practical one.
Now that I’ve put enough years I don’t get the treatment any more, just strenuously opposed with script-kiddie hacks when I put some intellectual effort in what I’m doing.
There’s a ton of people out there saddling down the industry who are totally our of their depth and terrified of becoming irrelevant.
Arts funding is being drastically cut: https://www.theartnewspaper.com/news/plans-to-cut-higher-edu... partly because arts graduates make less and partly because studying liberal arts makes students liberal, which the government perceives as a threat.
University started out as a trade school for the clergy, then added law and medicine, and then became a finishing school. At all points the median student was more interested in drinking than studying. Scholarship has always been a minority pursuit at universities and research universities haven’t even existed for 300 years. Universities are now and always have been vocational institutions. The supply of idle rich who don’t need a job has never been all that high.
See Cambridge as a counter example of everything you said: https://en.wikipedia.org/wiki/University_of_Cambridge
> The university arose around mutual aid societies (known as universitates scholarium) of foreign students called "nations" (as they were grouped by nationality) for protection against city laws which imposed collective punishment on foreigners for the crimes and debts of their countrymen. These students then hired scholars from the city's pre-existing lay and ecclesiastical schools to teach them subjects such as liberal arts, notarial law, theology, and ars dictaminis (scrivenery).[17]
The idea that this is “not what it was meant for” which is oft repeated on HN - and I presume in academic circles too - is not only inaccurate as you point out, but also arguably irrelevant, because the people paying the bills and justifying its existence expect otherwise.
It's an idea from the middle of the 20th century. For much of the 20th century, university was just something you did if you were upper class. Then someone noticed that upper-class people had good jobs and decided that must be due to their university attendance. It wasn't.
Ditto the lawyers, who certainly don't need to go to university to read law or argue. Being a lawyer is also basically being in a special club.
Medicine, I can only see a vocational aspect. But that is only 1 in 3.
> At all points the median student was more interested in drinking than studying.
A good use to time in the club. But only relatively rich students can afford to do this. Anyone who drinks their way through a university experience is either rich or busy trying to join a club.
I'd like to know where the author thinks mathematical learning can stop. In the US we live in a society where people will say with a smile, as though it was a badge of honor, "Oh I can't do math, I always hated it in school."
I'm sure the author isn't talking about that level of learning and would still want a reasonable degree of knowledge for all people, but their opinion on what that should be would be would be interesting in this context.
The most applicable is, "It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
But do not forget, "The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offence."
Dijkstra was right: I've wasted a lot of time unlearning BASIC to re-learn, if I wasn't exposed to BASIC at all I could have learnt from scratch a proper modern programming language/paradigm
IMO it is more important to try and find out if programming is even something they REALLY want to do.
The language maybe better selected for what they might want to ....do.
My first language was C, in a classroom where someone read from the book and then you were on your own.
I dropped out of school (for other reasons) and 20 years later I got back into programming via web development.
I wish I had a different experience in school.
I came back to C later and enjoyed learning it properly, but it is very much not a gentle introduction into the world of programming for the average person!
> We don’t have to make programming about mathematics.
I also don't understand the article's interest in decoupling programming from math; that seems like trying to have physics without math or philosophy without logic. The power of the field is founded on math; you can't just sidestep around it and gain its power at the same time.
It's an unfortunate side effect of America's long acceptance of anti-intellectualism. And people like this perpetuate it by coddling Americans who were somehow allowed to get through high school without even a basic understanding of the fundamentals of math. I am also a victim of this defeatist way of thinking, and have worked hard to appreciate math and learn it on my own to undo the trauma instilled in me by math teachers who simply taught formulas for us to remember to pass tests that we immediately cleared from our memory afterward.
But the article states near the end:
> Conversational programmers struggle to find resources that help them learn because so many of them require a focus on the logic and mathematics, but we are developing approaches to help conversational programmers learn without the math. We might be able to teach a lot more people about programming if we don’t expect students to know mathematics first
I'm just not sure that's a great (or entirely workable) idea. Embrace the math!
That said, I don't think one has to learn the math first; you can learn math and programming at the same time. In fact, it is perhaps easier to learn math when you have a concrete programming context to apply it to. I taught myself the basics of algebra by teaching myself BASIC in elementary school, years before I had a clue what "algebra" was. By the time I was taking algebra classes, it was a breeze. (Calculus on the other hand....)
- Machine language (not assembler)
— Assembler for a couple of different architectures (i.e: Von Neumann vs. Harvard, CISC vs RISC, etc)
- Forth (written from scratch with one of the above)
- C
- LISP
- APL
- C++
I think of everything else beyond these mostly as C/C++ cousins or derivatives. With languages like Javascript and Python it’s far more about learning the libraries than a massively different programming paradigm.Learning each of the languages is my list —in the suggested sequence— will provide someone with a deep understanding of different ways to solve problems with computers.
I recall the class which used a 6800 derivative in one of my college courses had a _very_ well written developer's spec manual for it. Complete with a (large) table that showed the logical relationship between the binary value of an instruction and the assembly mnemonic.
Today that might be RISC-V.
'x86' and ARM should also be used, and at least a taste of very constrained systems for super cheep stuff and very low level state machines for components would help round out the package.
Forth should be a semester project for one of the classes. This should include some practical case where either a manually clocked serial link, a set of dip switches and memory transfer captures, or some other constrained input method (maybe that 'boot sector forth' I recall seeing recently?) are used to trickle the core into RAM and then add higher level instructions. This might also include a small boot blob that inits the platform and opens an external data link; a useful example for subsystems.
The way I would prefer to teach machine language would be to start from scratch. This means you would create and define a simple set of instructions in the context of an equally simple 4 bit processor the students would build on a breadboard out of simple chips. And, yes, the microcoded instructions would be coded by hand using a diode matrix.
I truly believe such an exercise has enough value that it should be the starting point of a real education in computer science.
From there it's on to assembler on preexisting processors.
The reason Forth follows assembler on my list is that you can easily bootstrap Forth from scratch on any processor. Building the language from scratch is, again, to repeat myself, a worthwhile exercise. You would use assembler to get started and then switch to the embryonic Forth to build upon that. At some point you write your own code editor in Forth. From there there are a number of interesting applications (PID motor controller?) that could be implemented with the language you just built from scratch.
C offers an entry point into a world of languages that look and feel like C. It provides a tool that is close to the hardware, yet high level enough to allow for much greater freedom of expression. Doing arrays in Forth is a very hands-on proposition. In C it's pretty easy.
Once you are good with C you can easily pick-up languages like Javascript and Python. Not the same thing but you "speak" the same words to the computer to achieve pretty much the same thing. A "while" loop and an "if" conditional are the same incantations.
LISP opens the mind to an entirely different paradigm. It is well worth learning. The same is the case for APL. I don't think of these languages as "career level" languages. That may have been the case ages ago. No longer the case. However, the perspective gained is invaluable. As we try to solve more and more complex problems the limiting factor might very well become our ability to express ideas for a computer to solve these problems. Having the perspective of languages such as LISP and APL makes someone realize there are other valuable approaches to solving problems computationally.
Finally, C++, well, it's the entry point into object-oriented programming.
This, BTW, was pretty much my path through computing. I can't complain.
- LISP / Scheme - Python - C - Assembler / machine - whatever else beyond here
maybe leave out the LISP depending on how religious one feels about it (I'm a fan, from a pedagogical approach at least).
Most students have a very weak understanding of what a computer does (i.e. Von Neumann arch, executing an infinite tape of instructions, etc). I like LISP / Scheme because it really helps bridge the gap between expressions (which students can pretty intuitively grok from high school math education) and it really has no language design warts; you can write a metacircular evaluator in ~10 lines.
Python is a next step because it goes from "how does coding work?" to "okay how can I do stuff with this?". The language itself is pretty straightforward (although certainly has its warts too, e.g. the odd methods of variable scoping), but there are a ton of libraries and it is pretty much useful straight away for anything one wants to design a course around. Many unis combine "learning Python" with programming some robot, doing an AI thing, or other such practical outcomes.
Importantly, whenever I taught a "relatively beginner Python course", I would always spend a huge amount of time on teaching students about ipdb / pdb. Allowing students to explore the state and stack of a running program is a critical doorway for them to step through to not only learn how to debug their own problems (less of a load on me!), but also really start to grok the "program is a sequence of instructions that change state" thing.
C before assembler, although I have found it's often useful to "combine" them so that the concept of a pointer seems less odd and more useful. Also, C still has tools that students can use to explore their code (e.g. gdb), whereas they're much more on their own with assembler.
After that, it really depends on what students want to do. They can stick with systems stuff and do Rust / C++ / Go or go to Javascript or go crazy with the PL stuff with Haskell, etc.
Certain people (perhaps yourself) really understand this "program is a sequence of instructions that mutates state" thing, but in my experience, most of my students really don't get that. If I were to throw them into that deep end of the pool where they lack the tools to debug their own problems, I would get a lot of bad reviews / people switching out of the major. On top of that, students often like to really be able to produce cool stuff, which they can in Python very easily. Many students may bounce off the lower level stuff if they just want to do front end too, which is perfectly fine in a "top down" approach from higher-level languages.
If you know assembly, you can understand why arrays exist in C ( because CPUs have base-and-offset addressing), why records exist (same reason), what pointers are (assembly is pretty much about pointers), why ints are different from floats (ADD vs FADD) and so on, how functions are called (system stack).
Absolutely. My first year of programming we took both Fortran and IBM assembly. It all made a lot more sense, and still does.
When I first learn C in highschool the asign statement was what bugged me the most because I had already has a math background at that point so statements such as x = x + 1 made no sense, and even in natural science general, the idea that you can "asign" new intrinsic property to a thing is very unintuitive. 20 years later mutablity is the exact idea that I have to unlearn everyday.
My point is all these languages and learning hierarchy were made up by people like us, and in an era when frankly, they had no idea where this field was headed. We should not just blindly think because they're written in a book and sound important, that students should be condescendingly reminded about them in programming languages while they're trying to learn to solve real-world problems.
I eventually decided that what we actually got was a very simple problem, so simple that the answer was trivially obvious.
In contrast, it was trivially obvious to me what "x = x + 1" was doing, even on day 1.
Maybe I'm unique. But I suspect that different people trip on different things. Some trip on "x = x + 1", but that doesn't mean that it's a bad syntax. "x := x + 1" is going to make you type an extra character in every assignment over the next 40 years, in order to prevent confusion in a high school or college class. That may not be a good trade off. It especially may not be a good trade off when not everybody trips on it. (I didn't ask them to change the way they did algebra problems.)
(Re)assignments exist in social interaction so I guess it's intuitive to people that way, but if you look at code from a perspective of modeling reality that's just not a thing that exists in nature. Maybe it's just me.
Maybe a full course in assembly is too much for freshmen, but they should at least understand that RAM isn't like VCR tape: you can fetch any RAM memory location in constant time, unlike with a serial storage medium like tape. And they should know some of the hardware memory addressing mechanisms that make arrays possible.
Again you learn how computer works in computer architecture class, you learn programming already know that, or not, if it's irrelevant to your learning goals. You don't design programming languages to teach how computer works, nor do you learn programming to learn how computer works, that makes zero sense.
High level languages are expressing informational logic that actually can have nothing to do with computers, formally.
The way that the language maps to assembly, memory, cpus etc. is obviously incredibly important, but that's crossing a major boundary of abstraction.
Assembly is an under the hood implementation detail to quite a lot of CS work.
That said - of course it has to be taught - but I actually don't believe it's a 'precursor'. That's just how computers evolved. Imagine a day in 50 years when we switch to Quantum computers. Maybe 'assembly' will be something completely different then.
Your criticism is valid, I think, because the chips are now so complex "under the hood" that assembly is, in practice, no longer the thin abstraction it used to be, eh?
It's a much sharper and better motivated method to teach computer architecture, in my opinion.
The ultimate frustration is in trying to support beginners in learning assembly, as they will feel absolutely bogged down whenever they hit an error and will be completely incapable of being independent in figuring out their problems. They will lean on the teaching staff like crazy (ask me how I know....) and it's this feeling of "my code is broken and I have no damn clue what is going on!" that drives people away from the field. They have to get eased into it.
When I taught undergrads a primarily Python-based class, I spent the first third of the semester teaching them how to effectively use pdb (or better yet, ipdb; tab completion!). Although my section did not get as far as other sections (i.e. we got to the end of the required material only, whereas other sections advanced to some optional stuff like numpy and Django), the profs teaching the following course told me how much they appreciated that the students from my section really could dive in and solve their problems (or at least give them a good first go). If you don't give beginner coders the tools to debug their own problems (which are lacking in the assembly world), it may hamstring them for the rest of their careers.
I'm not sure it matters, but I think most people would do best learning a simple imperative language like BASIC or Python to start. I didn't really "get" Scheme/LISP functional programming until after I graduated, but now it's my favorite style and Erlang is my favorite language.
Python and Javascript have very low barriers to entry for the overhead (it can get complicated but for small programs it's easy).
You can use those to teach a lot of basic things.
In my own education we started with C/C++ and we were all drowning in pointers 80% of the time, the actual course material was pedantic.
What Uni tends to not focus on very well is just teaching the real, applicable basics of a language, with some good professional 'best practices' and students can spend years wasting their time trying to get things to compile, lost in bad manpages etc..
Start with something 'very light' and for everything else - provide a short 101 course for languages of instruction which focus on the practical mechanics of the language and nothing else. Those courses might even be taught by professional developers, outside of the regular kind of pedagogy. It feels 'not very academic' but that's the reality of the discipline.
If you want to teach architecture, and expect students to 'build buildings' ... you need to teach them properly how to use the hammer, nails, measuring tape - even if that in and of itself is not particularly academic.
I don't feel like this specific heritage affected how I learned programming. But then, I was mostly self taught with a generous amount of solicited input from older engineers and contractors I worked with/around (looking back, I'm a bit self conscious and just how annoying young me probably was--I did try to load balance at least). So maybe this article doesn't resonate much with me because it comes from the realm of common computer science pedagogy.
In fact, my first "college programming classes" were a year or so later, two classes in C that all mechanical engineering students at BYU had to take. I was able to wow my peers by making a faster sieve of erastones than others. And then for the "chose your own project", I used Smalltalk 80 to model quantities with units and a symbolic algebraic equation modeler/evaluator including a graphic visuallier that could plot arbitrary equations like PV = nRT -- the TA marked off points because my code didn't include enough comments even though the next closest program was a Fortran piece that prompted for a few values and it then spit out the correctly interpolated u, h, or s values from the steam tables. Needless to say, my impression of computer science pedagogy in the early to mid 90s wasn't that great. My take away was not so much what language was first, but who I learned from first.
* Simple Syntax - I think it's important for this to be a 'typed' language rather than blockly-style as otherwise people find it hard to transition after. It's important to learn typing in syntax otherwise that's a band-aid that's harder to rip off after.
* Mix of dynamic and static typing - On the other hand, words like 'integer', 'string', 'for' e.t.c. confuse people who are starting. A good starter language would allow people to dynamic type and then encourage them to static type in the future, getting them used to the terms.
* Very helpful error messages.
* Standard functions that support drawing simple stuff to screen (I'm looking at you python - how hard is it to draw a circle for a beginner! Beginners want to break out of the terminal quickly).
Would love to hear everyone else's thoughts!
I suspect this is aimed more at people who can already program and want to learn functional programming, rather than people who have never programmed, but I might be wrong!
- it's /highly/ accessible (any computer with a browser can compile and run javascript - you just need to get your browser to load the file)
- it shares a lot of its syntax with C-Style languages (which makes transference to other languages much easier
- it's 'relaxed' on how it enforces rules (now, this is contentious, should a learner be allowed to get away with mistakes that will haunt them later, or should a learner be hobbled and forced to be precise from the get-go, IMO the former is easier for people to upskil with than the latter)
- it's (currently) got commercial value (that is, you can get a job with javascript on your CV)
However to reduce the complexity, it's possible to restrict students to a subset, using eslint and one or two plug-ins. I like eslint-plugin-unicorn to restrict my co-workers.
Even Python has some quirks beyond the usual monkeypatching madness that can occur, e.g. with regards to name scoping.
I'm honestly not sure what could fit here that isn't a LISP dialect (which I think is pedagogically the right choice, but is usually impractical unless one is sure that one wants to do "hardcore" CS stuff, vs. using coding as merely a tool in another field).
I had to use java for a robotics course, and it wasn't too hard to pick up the differences.
I'm going to have to pick up rust in the next few months for work. Reading through the reference manual, it's going to be a bit painful to rewire my brain. So far none of the concepts seem alien, though, just a bit weird.
Me in an incredibly dull Java class in college: This is awful! I dreamed of making computers do interesting things, but it turns out programming sucks and is mind numbingly boring to learn! (I eventually dropped out and went on a different path)
Learning Python on my own 20 years later from various free online resources: This is incredible! I can make computers do anything and it all makes sense! What else can I learn?!?
For me, having both the right starter language and the right form of resources were required for it work out (ingesting lessons via video as I am curious about a certain topic works infinitely better than a classroom).
With mathematics, a student entering a math degree program is expected to have taken several math courses in high school. Students take placement exams to determine if they need remedial courses, but in general, you'll need to have taken algebra, trigonometry, geometry, and maybe a level of calculus.
But for computer science, we don't do any placement testing. Everyone goes into the same Java 101 course. And it's often the same course that everyone else in the college are taking as a gen-ed requirement.
Yes yes, insert any Dijkstra quote you want. I've read a lot of his papers. He was a professional troll. We need to stop holding him up as a paragon of computer science instruction. He did some great work in algorithms, but the dude is not the role model we should be pushing.
For as much as people like to parrot "computer science is as much about computers as astronomy is about telescopes", at least a telescope is conceptually quite easy to understand. A computer is a vastly more complex beast. Imagine trying to teach mathematics with students who don't even know the basics of the symbolic representation that algebra teaches. Such a student would fundamentally lack the tools necessary to succeed in a math program. But with computer science, we have students who don't know how to use their computers as tools. They only know how to use the software that other people have written and probably not even all that well. Even though "computer science is not about computers", being able to effectively use the tools of the field is still a necessary prerequisite.
So either shift the expectation to students having to learn the basics of programming on their own completely, or introduce a course of remedial programming classes in a variety of paradigms. But this purgatory of holding students hands through essentially nothing more than learning how to use the terminal and run a compiler, with only the most basic of procedural programming scattered on top, then throwing them in the deep end, that has to stop.
I probably should have done it anyway as I didn’t end up getting seriously into development until 2008.
Teaching isn't about knowing the one right way... teaching is about giving people information that relates to their existing knowledge base. In the language of RF Design, it's about impedance matching.
If you want to turn out Rust programmers, it's probably a bad choice to teach them COBOL first. BASIC would be less bad. The closer the languages are in terms of impedance, the easier it is likely to be to transit between them.
Tangent: Bear in mind that in RF Design, impedance is only a complex number, in a person's mind, there are an infinite number of dimensions, you'll never get a consistent number.
Tangent: Teaching someone BASIC on a machine with 2K of RAM is also radically different that teaching someone QBASIC with megabytes of RAM and a hard drive. The constraints are different, the language itself has differences.
Tangent: Non Von Neuman systems like Verilog, FPGAs, solder, and Excel are valid tools as well.
The course turned out to be surprisingly worth it! Since it had kids up to 15yo or so (I may have been the youngest), they introduced some advanced topics. I quickly picked up HTML (with Netscape and Notepad) and at the end they even taught us C in a UNIX environment (we worked on IBM terminals).
I'm really glad and thankful I had a chance to learn C that early. I have been taught Pascal, Java, C++ before reaching Uni years but I have always appreciated the compactness of C and compared every other language to it.
Discovering Python on my own in high school was like a eureka moment for me. It was the first time since my primary school C episode that I felt "home" with another language.
At the start, the goal of teaching is to produce highly-skilled graduates who can contribute greatly to the task at hand. During that phase, there's no problem with a high drop-out rate, and no need to "sell" the discipline by extending its reach. This is basically an exponential phase.
Later on, as faculty slots fill up, a steady state can be reached, in which the supply of graduates meets the demands of the community. That's when things get extended, and the goal can start to shift from turning out highly-skilled graduates with narrow focus to simply educating. Every university has a psychology department that has huge classes. Students in those thousand-seat classes are not going on to become psychologists; they are enriching their experience of life. And the dividing line between what they are learning and what they could learn in grade 10 is very thin, so this kind of material can also be taught in high school. Again, those 15-year olds are not destined to work in psychology, any more than they are destined to work in history, literature, or all the other fascinating courses that are being offered to them.
It looks as though the author is suggesting that education in computing is entering this state, in which there is very little probability of the student becoming a professional. And, in that scenario, I agree fully with the theses of the article.
But I still think there is a place for the old system of teaching a language and expecting that some of the students will go on to contribute at the cutting edge. It's great to have classes on photoshop and the like, but there is a question about what they ought to be called. Perhaps CA (computer applications) is a better acronym than CS for that student in sixth grade.
Using the same title for everything that happens to involve using computers is a mistake, not least because it gives students an incorrect impression of the pathways they might want to follow.
public static void main()
has a huge number of concepts built in and "just trust us, we'll cover that later" is a terrible excuse.
Edit: Even now, years later, I still got them in the wrong order. Arg.
Processing is Java but doesn't have public static void main.
Python has a the beginners problem that a small error won't block compile but will make the program behave on completely bizarre ways.
I remember the same exact thing from Java, and similar "magical words" that weren't explained but I was simply told had to be there.
Learning for/while/do loops and variable assignment and all of that is fine for a programming course, but the first semester of a CS course shouldn't just be sticking a fahrenheit to Celsius converter or a string reversal or simple sorter in between magic words and symbols.
It all depends on the first couple of language that one learns and how they are learnt and taught. 10-15 years ago people would find it hard to grok Python's functional concepts. But as it began to be taught as the first language in universities and those graduates join the working population you see how it's super natural for them to grok Python.
That said, in a professional environment, one should be able to pickup ~70% of proficiency in 6-8 months if they aren't constrained by crazy timelines. This is based on my own experience.
It's a ridiculous straw man, deals with symptoms instead of problems, and leads to an "everyone has an opinion" situation beyond any usefulness.
The professor was forced to stay surface-level on the math, so the coursework was a task of glueing together code from scikit-learn. Unfortunately, the exams were much easier if you had the mathematical intuition.
To put it another way, using Notebooks with pandas is a great way to wrote biology programs. Using Notebooks to write pandas is a terrible way to write software.
I believed in miracles. I believed in illogical things.
I was bad at Maths.
I however didn't stop. I took a critical thinking class and become an atheist three years after.
I was to able to see things differently after that.
Still, it was not enough to be able to program, but certainly boosted speed.
I took a Python class. I was able to understand basic concepts of programming.
It's still not enough because I can't make something real world.
I was looking at real world Python projects but they are hard to read and has obscure short names.
Then, I spent my time understanding what an API is. I found bubble.is and there I used my skills to build a real world app and made some money.
I moved to Outsystems and there I boosted my understanding on a lot of concepts.
I started to feel that I was like ready but afraid to swim into a real programming language.
I got angry one day. I wanted to build an API in real world language. So, I googled and found a result for express.js
I hated Javascript because a lot of people hated it in online. But I started to copy paste express.js example it on my machine and modified it according my needs.
I felt relief. I finally started real world programming with Javascript.
I made a lot of money with JS for 6 months.
I then discovered about C++ and the static typing world.
I went to learn C++ despite people telling me you should learn C before learning C++
I got understanding about pointers and memory management, compilers after learning C++
I then moved to embedded space where I did a OS and kernel from scratch.
That's my journey and of course I'm still learning Maths.
Actually, learning critical thinking & programming helped me to see what Maths really is. I'm studying basic algebra and going thru a lot of concepts right now.
Basic web stuff MSSQL C and C++ Bash Intel Assembly
Overall I'd say a little bit of everything is good for a CS student. Don't keep them hooked on one thing for too long. Not that students will be using C/C++ or assembly upon graduation most likely, but then are just another tool. I just wish we learned more about REST and doing CRUD operations. That took me a long time with my internship for it to "click" on what was happening.
Subsequent languages should match the content and focus of their classes (i.e C for Data Structures and Algorithms, C/C++/Rust for Systems Programming, Java / C# / C++ for OOP classes, Haskell/Clojure/etc. for Functional Programming classes , etc)
Another point is, are we really taking about programming language on the surface, its syntax? Or programming language as its whole ecosystem with library, tools, edge case and best practice. The former, arguably is very very easy. The latter is very very hard.
For example, I typically do better with reading than watching video. But it also depends on the subject matter.
Ultimately, when it comes to education / teaching / learning one size does not fit all.
It probably does, but for a long time, it was hard to tell exactly why. Now, however...ha, just kidding. It's still the same.
The syntax is so unlike other languages that I might have been better off learning C outright.
Hm. Ada and Eiffel have very similar syntax to Pascal and Ada is used in various industries.
The hypocrisy is real. It is definitely a real problem. If your field has confined itself in formalism without a consideration for HCI, you are doing yourself harm. Not only is the transfer of knowledge to industry and other domains harder, you miss out on equivalent but more accessible ways of expressing the same ideas.
It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration.
The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offence."
- How do we tell truths that might hurt? Edsger W.Dijkstra, 18 June 1975
https://www.cs.virginia.edu/~evans/cs655/readings/ewd498.htm...
My story: I have been programming since I was a little kid, having used mostly stuff like Logo and BASIC for years; after spending a bunch of time with Visual Basic I kept failing to learn C. In high school I took a course on some slideshow programming system whose name is escaping me right now, and then one on Pascal. OMG Pascal was hard for me: I made flash cards to try to learn the keywords, and I was struggling. There was something concurrent I was doing with simple JavaScript, which seemed to be going OK-ish.
I then started taking a second course in Pascal--an AP class--but by this point it had all clicked: I had been programming at that point--even writing software for local companies sometimes (in Visual Basic)--for like 8 years and I finally got it. The teacher noticed, and since I was only a junior he said I shouldn't bother continuing in Pascal: I'd help him learn C++ and co-teach the class the next year with him, and take the AP test in C++.
That was... over 20 years ago now? I now feel like I can just learn any language almost immediately. I remember being in the audience when Apple announced Swift: I was looking at the slides and thinking "ok, I see what they are doing here: this is like Objective-C crosses with Scala but with some of the syntax of Ruby... I bet I could program in this". I spent the next day playing with it and had already befriended the Swift compiler people as I was finding tons of bugs, and then I gave a talk on Advanced Swift Internals two days later across the street at AltConf.
I personally feel like this kind of mental process is "teachable". I thereby sometimes have gotten to teach a course at UCSB (I have sometimes been hired as a "1/8th lecturer" or something like that to do this) on programming languages, where I try to take students through the breadth and depth of syntax and semantics, rather than just focusing on a couple examples. Sometimes we look at a semantic and how it evolved, sometimes a syntax and how it got reused, and sometimes a use case and how various languages tried to support it. By the end of the course I expect you to "know" none of the languages, but to hopefully be able to quickly use any of them with some examples. The big project for the class is to design and implement your own "esoteric" language.
FWIW, I "thereby" personally am still in camp "it doesn't (exactly) matter"... as long as it inspires the student! Which I actually think is what this author is kind of getting at (and so I actually do agree with them) with that paragraph about "what about a student who X"... a lot of teachers seem to think "learn this toy thing and you will be able to eventually learn anything", but the toy is boring and doesn't do anything the student wants to work on and by the end of the entire experience you are lucky if they did any of the work at all. It is like teaching someone to play some horrible sounding musical instrument using example pieces that the student doesn't enjoy listening to with the goal of establishing enough musical theory and experience that they can learn a second instrument / style some day and eventually get good enough to do what they wanted. It is just unrealistic? I was able to get as good at the languages I was able to largely because they were useful to me... and honestly, that Pascal wasn't was probably part of what made it so hard :/.
Then again switching programming paradigms not so easy, but when you can...
Even learning JS + HTML, or Spreadsheet + Bash/PowwrShell, with good instruction, should be enough to instill the key idea that languages are abstractions and there are radically different languages for different problem domains, and you should find ones that fits the applications you are interested in.
Perhaps a prerequisite of the major would be demonstrable knowledge of 2+ programming languages that exist in nearly orthogonal domains.
I think low-level to high-level, with the right amount of history, is the best way build rather than relying on mysterious abstractions below. Microcode, assembly, C or Fortran, are the fundamentals CS graduates should be required to have or the accreditation bodies aren't doing their jobs.
Also:
If you can teach monads, you're a great lecturer.
If you're Sean Davis from UC Davis, you are/were a great lecturer.
A great lecturer of technical minutiae both has an expressive personality and explains concepts as simply as possible using learning aids such as analogies, examples, and diagrams.
One of the motivating examples in the OP is "conversational programmers". OP defines that as people who want to be able to have conversations about programming stuff, but won't program. -- For those people, sure, assuming heavy technical/math background when teaching programming isn't helpful.
But many topics in Computer Science heavily rely on applying math. (3D rendering, Computer Vision, Machine Learning).
I self-taught myself computing concepts all my life.
I self-taught myself Python (in earnest) while in MBA school (because I believed spreadsheets needed to die and Python would be a good spreadsheet killer).
I've been teaching Python to other students in the last few years. It's usually their first programming language (if not, R probably was).
I've always believed in being a computer language polyglot, if only to be able to communicate with others from other languages and to learn what those languages have to teach us, but I'm also of the opinion that one should stick to one's strengths.
I would agree that we should think the initial programming language doesn't matter - if we're simply looking at whether we can communicate or translate fundamental mathematics of computation.
However, when a student is an adult trying to get immediate value from the learning (instead of the gratification of increasing pure knowledge, like I did) their choice of language matters greatly.
My first recommendation to anyone asking me is of course Python, due to broad applicability (which means learning one time a language that can be used to scrape the web, provision a restful API, or do complex data analysis), license (free to use), cross-platform compatibility (MacOS, Windows, Linux), popularity (which leads to ease of getting help), all leading to a good reputation for readability and maintainability (which is encouraging broad industry adoption meaning more jobs for Python programmers).
Of course, for specific applications, the recommendation may be different, such as JS or TypeScript for front-end development, or C or Rust for low-level programming, or Lisp, Elm, or Haskell for functional programming in their respective domains.
Further, Haskell and Elm have greatly informed my approach to object oriented programming - I feel like they have made me better and made my Python more robust and straightforward. I didn't learn them first though. In retrospect, I feel like I could have easily learnt them first. I wonder how I would look at my Python if I had done so - what would indeed be different? I don't know.
But I do know, for pragmatic purposes, first programming language does matter greatly.