How does your school/university teach it? What have been the pros and cons of that choice?
Obviously, teaching students logical and foundational concepts is the most important part, but a student’s first programming language does color their internalization of the concepts and how they approach solving different problems. For example, OOP is really hard to grasp coming from a functional background. Learning how to manage memory efficiently and use appropriate data types is really hard coming from an interpreted language like Python or Javascript. What have you and your peers decided works best for you and your students?
When answering this question, I think there are big differences between
- teaching college vs high school vs middle school vs elementary school students.
- self selected students vs compulsory
- prior exposure to programming, eletronics, or mathematical analysis
So I have to ask what kind of students are you teaching?
For me, college, but I was really just wanting to get a breadth of experiences from other folks. Frankly, my department is considering switching from Java to Python, and I was curious about pros and cons of that decision beyond what I could think of off the top of my head.
It seems to me that many well respected CS departments in the US make use of multiple languages in introductory courses.
Some examples:
- CS50 at Harvard uses Scratch, C, Python, SQL, JavaScript, CSS, and HTML.
- CS 61A at UC Berkeley Primarily uses Python but also makes use of Scheme
- CSCI 0190 at Brown primarily uses Pyret but also makes use of Python.
So it seems that it is common among introductory CS courses at a collegiate level to make up for the limitations of a particular language to use more than one.
Further, it seems that schools make an attempt to have a cohesive sequence of two or three introductory courses where courses build upon prior coursework to provide a broader breadth of foundational understanding. My favorite example of this is Cornell’s CS 3110 which uses OCaml to teach Data Structures and Functional Programming.
I know this doesn’t actually address your original question but I hope it inspires you to be flexible with the approach to the new curriculum.
I’ve been advocating for a CS50 style course at an introductory level. A little bit of python, some light data science labs with an SQLite database, throw some javascript at it to make some quick and dirty web representation. Really, all we want out of students are basic problem-solving skills, a familiarity with programming basics, and for students to be excited to learn more. I’ve got one other instructor in the department on board with this approach, but the rest are still having a little bit of trouble moving our courses out of the 1990s.
Awesome! I hope you can drag them along.
I’m not a good comment writer so here’s some text:
Not a teacher, but Python is great to discover various aspects of programming (algorithmic, flow control, I/O, OOP, metaprogramming). It’s also easy to setup.
Java is just painful. The environment setup and the various frameworks available there are just way too overwhelming.
JS is actually close to Python in my opinion, and better suited for getting introduced to functional programming while still using a non-functional language. See anonymous functions/arrow functions. APIs are heavily callback-oriented which is also a great thing to get used to: You can register a bit of computation (a function) to be executed some other time, i.e. when something happens. You are not in control of the execution of that function, someone else is and will call you back. This is something important to learn (imo).
Finding the optimum algorithm is not important in the beginning (imo). When writing code there’s often two pretty different activities that happen:
-
Defining and organizing your abstractions and flow.
-
Identify bottlenecks and search for fast enough/memory efficient solutions.
In most real world scenarios, having good program flow and abstractions will be enough. Not everyone works on real-time terabyte-sized data processing. See gamemaking: it’s a very performance sensitive domain yet frameworks allow anyone to make a decent game. Why? Because for most problems, someone already wrote a library that’s fast enough. You just need to wire things properly together.
Teaching something lower-level like C/C++ is great, but you need to spend time deconstructing all the goodies people got used too when dealing with other languages. i.e. Why you can’t create an array with different types/structs inside anymore (not without pointers).
And then just get them to practice writing different bits of software with increasing complexity, over the year(s). The most exposure to writing code the better. Trial and error is how anything is learned, and while you might try to warn your students about common pitfalls it might only really click once they’ll make the mistake. Push them in situations where they’ll make mistakes.
The most important mindset to have (imo) is to constantly challenge yourself and your work: find ways to break your own stuff. Maybe you’ll miss cases but the better you get at anticipating breakage, the better you’ll get at writing robust software.
The second most important thing is to seek to understand every line of code you write and as many implications as possible. A program is supposed to be deterministic, there’s very few surprises to be had when dealing with code (there are some though). What I mean by that is: if someone reports a bug, it can often be enough to read the code with the unexpected result in mind and work your way back to the places that allowed for this bug to occur, just by reading statically.
Lastly one thing that was motivating for me when learning programming was when our programs would run against one another. Competition fosters innovation.
I hope these pieces of opinion help with anything…
By “the most exposure to writing code the better” I might have meant to expose people to as many paradigms and patterns as possible and them have dealt with it. i.e. Writing a (shitty) eventloop is what really made it stick for me with async/callback-based programming.
-
For what it’s worth, I posted this link a while ago on what Dykstra had to say about changes being made to a programming course. He came down in favour of (keeping) Haskell.
I wish I started with Golang! To me it has the perfect balance of simplicity and power. You need to care about types but only a little bit. Most everything you need is in the standard library. It can be shared very easily as a binary. The concurrency model is quite different than anything else but that could be out of scope for a beginner language. Go also has memory areans (in experimental) and generics so there is enough to chew on for the more advanced students as well.
I went from python and JavaScript to rust and now I’ve settled onto Go. Python really hurt the way I understand programming as a whole and rust mostly corrected that but is overkill for most things I do.
How did Python hurt your understanding of programming?
No types, anything async is a pain, the strong push for OO, no errors as values, std lib is not the most extensive, pip/virtual environments are cumbersome and hardly portable, and I find it’s ability to do everything well hampers its ability to do something specific well. Not that any of these actually regressed my understanding of programming, they merely slowed my development. After some time spent in rust and golang I have a much deeper understanding of programming/cs in general.