5
$\begingroup$

Every year I focus on one of my courses to overhaul a bit. Partly because I'm supposed to have professional goals, and this is one that's pretty easy to admin to understand. But I also get bored teaching the same thing every year.

Right now I've got a third-year independent study course (high school). When I started the job a few years ago I basically just continued what the previous teacher was doing. Students propose a project during the first two weeks and then have the year to build it. The biggest catch is that there's almost no accountability for the students.

I'm wanting to change it into a more formal curriculum, and I'm leaning towards a languages class. These are 3rd or 4th-year students that have taken AP-A and Data Structures which are both taught in Java and may have a bit of experience with Python or JavaScript depending on the year.

So with that lead-in, I'm looking for some feedback on the plan.

We do 6, six-week grading terms. The plan is to do a different language each six-weeks. I'm leaning towards doing Python and a crash course in HTML/CSS/JS during two of the terms. And then I'm skimming 7 Languages in 7 weeks and the sequel for ideas on what other languages to do.

They'll have already done 2 years of Java, so I'd like to stay away from OOP and C-family languages as much as possible.

And I'd like it to be project heavy. Maybe one big project per language. I don't want to do many, if any, small lab type assignments.

Any thoughts or tips from those that might have been down this route before?

$\endgroup$
10
$\begingroup$

First, some caveats come to mind. The difference between languages isn't primarily syntax, even languages in the same paradigm family. Once a student has a solid basis of programming in a single language, say Java, they have developed a way of thinking about transformation of problems into solutions. They have ways to assure that their programs are correct and complete. One hopes, at least. Changing to a different language requires that they learn to think in a different way, whether it is small or large.

I once considered applying for a job where the focus was to be on languages (my specialty). They wisely specified in the call for applications "Principles of" not "Examples of".

The basis of my suggestions, following, is to focus on the principles, not the examples. And the principles involve ways of thinking, not syntax. It is pretty common for people moving from one programming language to another to just write in the old style. A Python program that is just "misspelled Java", isn't really a Python program. It isn't pythonic, in the jargon.

In a university curriculum there are often (or were) two courses devoted to languages: Language Principles, and Languages and Compilers. I taught both of these for many years. By the time students take the first course in the sequence they are well grounded in at least one language and have likely seen a couple more, mostly in passing.

I think you are correct in wanting to stay mostly away from other OO languages, except:

The difference between Java and Python (or Ruby) isn't the syntax. It is that Java is statically typed and the others are dynamically typed. If a Java program compiles (and you haven't used casting incorrectly), then it is type correct and will not fail for type errors when running. That isn't true for a Python program since the (still strong) typing is done at runtime, not at compile time. So, one major problem for the Python programmer that isn't faced by the Java programmer, is what tools and techniques (ways of thinking) does the Python programmer need to employ to assure that the (compilable) program they write will actually run to completion.

But, if you want students to learn to think in a different paradigm than what they learned first, you will need to give them time and experience. I think that six weeks per paradigm is probably sufficient if it is done well and fairly intense, focusing specifically on how to think like a whatever programmer.

Some possibilities for languages after OO.

Scheme (Racket) or Standard ML (aka SML). A minor point, but some functional languages use eager evaluation of function arguments (like Java) and others use lazy evaluation. The programming style is a bit different for these two cases.

Modula 2 (or Dijkstra's presentation language) or Oberon. These are for pure procedural programming. Top down problem decomposition, solution of simple problems as procedures, bottom up solution integration.

SQL and the underlying Relational DB theory that underlies it. A really different paradigm. Recent versions are Turing Complete and can be used (awkwardly) as general purpose programming languages. A chance to explore Turing Completeness and maybe even Turing Machines.

Some concurrent programming language. Maybe Rust, which is both modern and a C replacement, Erlang. Or even a data flow language like Swift -- note: That isn't Apple's language of the same name.

Some simple and uniform Assembler Language (not Intel). You need an emulator, though. A simple memory model. A uniform Register set. Both pdp-11 and MC68000 fit the bill-- more --

Prolog Logic programming where the program is descriptive, not algorithmic. Actually, SQL has that characteristic also. The algorithms are (almost) all built in.

Perl or bash scripting language

Lots of choices - the list isn't complete at all.

Late in your sequence you could have students work in small groups to produce a report (with examples) on some language of their choice, taken from a list that you supply. You could use a lottery system of some sort to make sure each group has a different language. The language can be wildly different, There are a lot of possibilities. I would probably include R, Self, Processing, Forth or Postscript, Bash, ... -- more -- for my own list. You could also let them make proposals for languages not on your list if they can give you a (written) reason for another language. Don't let them misspell Java, of course. And make sure a processor is available to them for any language.

I suggest that the last few weeks (you say six week terms) would be to summarize what has been learned in the previous segments and make some things very explicit. For example, dynamic v. static typing. You could also give them an idea about what a compiler might look like for a simple language, in particular the separation of lexical, syntactical, semantic, and optimization components of a compiler. A good source for the latter (instructor resource) is Per Brinch Hansen's, On Pascal Compilers. You can probably find a copy in a good academic library. Another good source (again, for the teacher) is David Gries's The Science of Programming. The latter book does an interesting thing beyond its stated purpose, which is to you how an imperative programmer should think in terms of pre and post conditions while developing algorithms. It uses a simple language for exposition that is the same as that used by Edsger Dijkstra in his scholarly papers. A compiler for this language is, like the Hansen book, quite accessible.

You obviously can't do all of this. Nor would a university course. But, I would use at least the following in developing the course.

Choose languages from different paradigms and focus on that - the deep semantics, not the syntax.

Think about all the variations open to the language designer and try to cover as many as you can. Static v. Dynamic typing. Concrete v. Abstract syntax. Strong v. weak typing. Garbage Collected v not. General purpose v. special purpose. Many v. Few abstraction mechanisms. -- more --

In going from one fragment of the course to the next, I'd think about how different the next language is from the previous. Scheme is very different from Java (no syntax, no variable state, dynamic typing,...). SML, at least has syntax and a very interesting type inference system that permits typing at compile time in a functional language.

Summarize at the end. Provide room for a lot of discussion. Have the students write reports and not just programs.

$\endgroup$
  • 2
    $\begingroup$ I think you nailed it with the distinction between different paradigms rather than just different syntax. That's really what I'm after. I hadn't thought about SQL. That's a good one. And the report idea is on point as well. $\endgroup$ – Ryan Nutt Nov 10 at 16:13
  • 1
    $\begingroup$ If they write reports based on research, help them a bit with proper quoting and citations so they learn how and why to avoid plagiarism. $\endgroup$ – Buffy Nov 10 at 21:22
  • $\begingroup$ Note that, according to the Spiral Pedagogical Pattern, it is good for students to return (several times) to a topic with each cycle going deeper into the subject. An implication is that a first exposure need not be terribly deep if they will return later for more - even if that return is in a later course. $\endgroup$ – Buffy Nov 10 at 21:25
  • $\begingroup$ I agree about the importance of ways of thinking. When I am learning a programming language I prefer a book that teaches the language from first principles, rather than a conversion from a language I already know. The point is to learn e.g. how to think about variables in the new language. $\endgroup$ – Patricia Shanahan Nov 11 at 9:48
  • $\begingroup$ For assemblers: an early ARM. It might even be possible to do away with the emulator and use a cheap development board. And if you want to go even lower level (although probably needing a more expensive development board), Verilog or VHDL. $\endgroup$ – Peter Taylor Nov 12 at 9:22
1
$\begingroup$

I took a class in programming languages that was absolutely awful. We spent about 3 weeks per paradigm, and had 12-16 hour labs due every week. Each paradigm was different and new, and I couldn't morph my mind around them fast enough. (I was also not that motivated at that particular moment in my life, which certainly didn't help matters.)

I have spent much of my career working around that class, and making sure that I didn't do something like that to my own student's. There was too much variation, it came too fast, and it was just too hard.

Interestingly enough, a fellow student on that class who has since become a CS professor and researcher in programming languages also flagged that class as one that was quite important in his own teaching. Apparently, he has been also madr avoiding those mistakes a centerpiece of his own teaching career.

The problem, as we both agreed, was that real paradigm shifts (such as to functional languages) take real time to absorb. If the goal is to meaningfully be able to think and program in a functional language, them give that the time it deserves. I currently teach Scheme to kids in a very, very similar place to the one you describe. (High school, having had AP and Data Structures)

I start functional programming in November, abd find that it takes about 2 months to get them vaguely comfortable, and the rest of the year to get them really able to think in the new way. I cover other topics in CS during the remaining months, but assign all of the labs in Scheme.

Now, you don't have to take it that far. After all, anyone who goes to college for CS will take another functional language, so you can just be a first exposure. But be aware that it takes real time, and real effort, to think in a completely new way.

$\endgroup$
  • $\begingroup$ This sounds like the 'examples of' sort of course, With students expected to somehow grok it by osmosis. $\endgroup$ – Buffy Nov 10 at 21:23
  • $\begingroup$ @Buffy It was deeply, deeply awful. I abandoned CS for years as a direct result of that class. $\endgroup$ – Ben I. Nov 10 at 22:02
1
$\begingroup$

I teach a high school independent study class that does this but it is a course intended for beginning programming students. The languages are therefore beginner languages. It does give them an intro to an interesting spectrum though. I use code.org (Star Wars or Frozen or Classic Maze), Alice, Small Basic, Thunkable, micro:bit and, depending on the student, a little Python. Right now I am spending a large chunk of the semester with Thunkable and a couple of Indian Ed projects. At one time I was going to include a HTML/CSS/Java script module but there was simply not enough time in the semester to do it correctly. Thunkable fitted easier.

My goal is not for the students to get fluent with each platform, but to get a taste for what is out there and to get comfortable with finding learning resources. I feel learning how to learn a language is a lot more important than having a particular syntax or paradigm memorized. Several of the comments mention the difficulty switching between language paradigms if going with heavy languages. I agree, that is why I use simple languages intended for students. The languages are simple but fun to tinker with. For example the Alice project is to find a Shakespeare scene to build an animation of. The Small Basic is a simple turtle graphics project. Nothing complicated but enough to get the general idea of the possibilities of each environment.

The fact your students are much more advanced would maybe require more depth in the projects but it still could be a course for the kids to have a lot of fun making artifacts with fun languages.

$\endgroup$
1
$\begingroup$

I took such a class at university. (This was in the 1980s, so most of the classes used some imperative language, at the time the primary languages were PL/I and Pascal, with some FORTRAN and COBOL; but these were in the process of being replaced by Ada and C.)

I did find the course to be very enriching, but the students (including me) had already had a minimum of 4 semesters' worth of CS classes, including at least one required upper level course. (It sounds like your students will be at least as well prepared; I note this mostly for the benefit of other readers.)


The first few weeks of the languages course were spent using SNOBOL and the last few weeks using LISP, mostly because the instructor wanted us to understand that there were very different paradigms out there than the imperative mode we'd mostly been exposed to.

The "middle" weeks were spent looking at various features typically associated with imperative languages: input/output formatting, record structures, scoping (including nested functions/procedures), etc. IIRC we used a textbook called Programming Language Landscape or similar.

Concerning the SNOBOL and LISP portions of the class, the lab assignments were small and focused. The instructor was explicit that his goal was not to make us experts, but rather to "raise awareness" as it were, and prepare us for further and more focused learning in those areas if we wanted to pursue that. (For example, there were a couple of AI classes, but those were electives).


For an introductory / survey course I think I would recommend going a similar route, i.e. small assignments rather than large projects.

I would also echo some of the other answers @Buffy's in particular and say you should perhaps not focus so much on different languages as different paradigms.

Or perhaps a different twist on a familiar theme. The C standard I/O library design is generally considered to be an object-oriented abstraction (and a fairly good one), despite not being written in an OO language. So implementing an OO design in a non-OO language might be an interesting idea ... or to look at how a non-OO language such as Modula or Ada (8x) handles encapsulation.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.