Some thoughts after completing the UW Programming Languages courses

这篇文章并非使用中文书写。您可以用Google Translator来辅助阅读。

After a december spent in projects, my main activities during the February were not about projects, but related to three courses in Coursera. Concretely, that was three parts of a same course - the Programming Language course from the University of Washington.

It's the Coursera version of the CSE341 course of sp.2014 version. The course briefly introduces some basic but core concepts of programming languages. It covers a large extension of topics like abstraction, static/dynamic typing, scopes, syntax and semantics, first-class function closures as well as algebraic datatypes. With these discussions, it gives some in-depth insights to various programming paradigms like functional programming.

I have been looking at this course for years, but always with a lack of time and effort. Finally, with some extra time, it was quite a delight to complete all this course. On Coursera, the programme suggested 5+3+3=11 weeks to complete it. Since I have already had some background knowledge on FP and compiler, with some extra time spending for each week, it took me about slightly more than a month to finish all the programme.

Like mentioned above, the coursework was a bit oriented to FP style, but it also talked about a bunch of OOP-related concepts, like the double dispatch and its visitor pattern implementation, or mixins (which I am more familiar with the name trait), as well as covariance and contravariance. As for the FP part, since we talked about the closure, it's then a natural extension to continue on topics like thunks, promises and streams. Although the courseware aged nearly 10 years, these concepts are still up to date with last trendings in the SWE/SDE industry. In general, although both FP and OOP are covered, this course is neither a FP course or an OOP course. It uses FP and OOP to give motivations for various topics, using languages from both sides - SML, Racket and Ruby, to analyze these fundamental concepts that most of programming languages have in common.

Of course, it also covered discussions about soundness and completeness.

But the most impressive takeaway for me, was that subtyping is not a matter of opinion. During the course, Dan provided an example of nested subtyping, which is sound only when all variables are immutable. That is, composing features in programming language design is not a constraint-free thing. The existing syntaxes and rules will have critical impacts on the future extensions of this language.

Of course, this constraint does not only exist in OOP languages. When talking about scopes, it was also mentioned that dynamic scopes are unreasonable, and that closures can only have a sense under the lexical scopes. Well, closure is the core concept of the FP ...

That made me rethink about the discussion of software compisitions of Marisa.

The homework was also quite interesting. It started from very simple helper functions, then with a little data types, and a little more additions ... The final homeworks were implementations of a pattern matching mechanism, a simple (but Turing complete) language interpreter, a Tetris and another interpreter based on the visitor pattern aka double dispatch.

Globally, the coursework ranged from easy to medium. For example, the topics regarding the typing are really trivial than those unification, parametric polymorphism and Functional OOP topics covered in TAPL. The discussions on FP stop at ADT and closure, without need to know things like Monad, typeclasses or GADT.

In another word, I have already known quite a few concepts before studying this course. But it's still a nice chance to refine my knowledge and recap some principal ideas.

I also tried to implement a Java version of the MUPL homework, and got the idea that we can always implement some core features of a FP language, even in Java, without language support of the FP. Then I found the extra assignments of MUPL which asked you to implement some more complex concepts like unification and equality, like, once you have done this extra homework, you have already implemented a simple but complete FP language compiler.

The main drawback is that the coursework stopped updating since long time. The installation guide of Ruby on macOS was totally obsolete so I had to use a backup Windows machine to install old version Ruby. The discussion forum was also quite empty and you have to wait for weeks to receive your grades.

I had a look at the website of CSE341, and seems that the original course has changed quite a lot lately, like the replacement of SML by OCaml, and usage of OOP feature of Racket instead of Ruby. There have also been lots of changes in homeworks and labs.

There's also another course called CSE425S which seems to follow the sp.2014 of CSE341, but I only found the course information of 2022.

I am planning to complete the extra parts of this Coursera PL course and then see if I can port things on Java.

And then I would like to seek for other courses. 61A or 61B or the EPFL FP courses seems to be nice.

Or maybe I would come back to read the Programming Language Pragmatics book.

Some thoughts after completing the UW Programming Languages courses