It has been reported that the University of Waterloo dropped Java in favor of Scheme for first year students. A lot of discussion revolves around whether this is a good choice.
I would argue that introducing CS students to programming through Scheme rather than through Java has a lot of beneficial side effects.
- REPL: The first thing that Scheme has that Java doesn’t is a REPL, a read-eval-print loop. This is a program that is available in a lot of languages, and only the C-family of languages seem to be lacking them. A REPL allows the user to input expressions and get an immediate answer. REPLs are great for exploration, testing and just toying around with the language. And because the result is instantaneous, students are more likely to try different things than they are to make modifications to a program and keep compiling and running it.
- Small core: Scheme is unarguably a simpler language than Java. The entire R5RS standard is 55 pages (
which I assume is the revision they will use, since DrScheme has no plans to move to R6RS as far as I know.I was misinformed regarding R6RS, PLT-Scheme will in fact support it. Thanks John and Jeremy. I wonder if the classes at Waterloo will use it or R5RS.) The book Java in a Nutshell is over a thousand pages long! There’s just a lot less stuff to learn in Scheme than in Java. - Simpler syntax: Some people argue with this claim because they get lost in a sea of parentheses and claim that Java has a more “natural” syntax. Nevertheless, in terms of simplicity, Scheme’s syntax wins. You don’t have to remember if a semi-colon goes after this particular line, you don’t have to remember that if there’s only one statement in your if/while/for/etc. you don’t need the braces, etc. A lot of anecdotal evidence suggests that students who learn Java are confused by syntax errors and that they represent the majority of the questions asked in class.
- Dynamic typing: Without saying that static typing is harmful, I think that the constraints it imposes, while beneficial in the long run, significantly complicate a programming language. If I take Haskell as an example, there are a lot of concepts such as type variables, type classes, monads, etc. that exist solely to satisfy the compiler. In a large production program, this can help the programmer, but to the student, these will get in the way of comprehension.
You want a tree in Scheme? Just use a list, there’s no need to define a new recursive type.
- Functional paradigm: Although Scheme is not a strictly functional language, it supports this paradigm much better than Java. Programmers who grew up with BASIC, C, C++ and other imperative languages will tell you that functional programming is a lot harder, but I believe that it is easier for a student to reason about a functional program than about an imperative one. As they show in SICP, all you need to do is expand your function call. For instance, to understand the function
map:(define (map f xs) (if (null? xs) nil (cons (f (car xs)) (map f (cdr xs))))) (define (plus1 n) (+ 1 n)) (map plus1 '(1 2)) (cons 2 (map plus1 '(2))) (cons 2 (cons 3 (map plus1 '()))) (cons 2 (cons 3 '())) (2 3)With imperative programming, you need to keep track of all the variables that get mutated in your program. This is harder.
- The students learn: With Java, students learn to program in Java. With Scheme, students learn to program. Because the Scheme language is so simple, students can quickly be introduced to more complex topics. In Java, the static typing, the complex syntax and the lacking means of abstraction and combination hinder this fast progress (try writing a general, simple map function in Java.)
Some people voiced concerns over the practicality of showing Scheme instead of Java; those concerns are unfounded in my opinion. First of all, a person that knows programming well shouldn’t have any problems picking up Java. Once you know the fundamental concepts of programming, learning a new language is learning new syntax, idioms and libraries. That is not to mean that it is a trivial task, but the transition is easier. Next, the job of the university is not to teach the currently popular technologies, it is to teach the fundamentals of the discipline. Technologies come and go, but the core of computing changes much more slowly and is applicable to many technologies.
March 20, 2008 at 3:22 pm |
In fact, DrScheme will support R6RS, and alpha versions already do. See http://groups.google.com/group/plt-scheme/browse_thread/thread/70a8fb9920be0df8 for details.
March 21, 2008 at 11:50 am |
Good to know, thanks John.
March 28, 2008 at 12:27 am |
As a non-computer engineer working for the past decade as a sysadmin, I think this is a great move. I learned BASIC and FORTRAN in high school, then Pascal, more FORTRAN, and assembly (CS elective) in college. Since then I’ve picked up Perl, shell, PHP, and Ruby with occasional forays into tcl and Expect. I can read C, C++, and Java but I find them uninteresting and too low-level for my day-to-day work.
In particular, Java seems to be a continuously moving target that is very sensitive to interpreter options, specifically those relating to garbage collection and memory allocation. Teaching Java at a university level seems as counterproductive as teaching (say) Perl or Python because it trains the students to do things “the Java Way” which leaves them lost when facing the next big language. Speaking from my own experience, I learned procedural programming; at the time, engineering and scientific code was still mostly written in FORTRAN and OO languages had not made much headway into the CS curriculum (for context, I got my MS in 1991 at the University of Wisconsin.) Really grasping the object-oriented paradigm took almost a decade after I graduated and only happened once I divorced the paradigm from the syntax of C-based languages.
The kids need experience in more languages than just Java and they aren’t going to get that until after they graduate. I wouldn’t worry about the industrial types that complain that Scheme is a waste because it’s not commercially viable. COBOL was once all the rage, not too few years ago Visual Basic, Delphi, and ColdFusion were pretty popular; Java is currently having its lunch eaten by Ruby.
The point is to get the kids to think, to understand there are different programming paradigms that each work very well in certain problem domains, and that a good programmer is constantly looking for different ways to view and solve problems. Knowing Scheme is valuable even though the student never uses it after college (FWIW, I really value my VAX assembly experience because I can recognize a clean CISC implementation.) Paul Graham similarly goes on about LISP.
Anything you teach now will be on its way out by the time the kids graduate, and their employer will have to retrain them anyway so Waterloo might as well teach them something interesting.
Scheme is on my list of languages to learn, along with R, Ragel, SNOBOL, Forth, and PIC and Atmel RISC assembly. I don’t have a CS degree so I have to play catch-up on all the weird languages I missed out on while I was learning to crack atomic nuclei and boil water.
April 4, 2008 at 3:50 pm |
I agree that Scheme in first year is an awesome move. My own department has moved to Python, which is a step up from things like Java where you need all sorts of meaningless scaffolding to get “Hello World” running, but Python has it’s own share of problems. Scheme is beautiful, simple, and infinitely extensible through its macro system.
I feel the need to point out a few things:
Java has for a long time had a REPL in the form of DrJava (which, not surprisingly, draws its inspiration from PLT’s DrScheme). It’s also available as a plug-in for Eclipse, which is immensely useful even in industry; if you want to test something out quickly, to be sure you understand the documentation of how a particular class works, just instantiate one and play around with it. No need to create a project, write a whole class with a main(), etc. So, while this is an advantage of Scheme, it’s no longer a hindrance to Java.Parentheses are only a problem if you let them be. Really the only thing I’ve ever had a problem with was forgetting to close parentheses, and that’s what a programmer’s editor is for. (One thing that should be imparted to any student of CS, or programming, is that coding in Notepad is not cool; better tools exist, and for free, so use them. Ditto for debugging with print statements).Type safety is something that’s important to know about and explore. I just don’t think it needs to be in an intro course.Your Java in a Nutshell example is just a tad misleading, as that book likely contains all sorts of information about things that the Scheme people relegate to libraries. Really when you “learn” Java, you’re not just learning the syntax of the core language, but also the layout of the Java “standard library”, java.io, java.util, etc. One could argue that the need for these things is “built-in” to the core language, by not making a variable-length list a primitive, for example, as it is in Scheme, by Java’s types system, etc. It’s important to note that lists in Scheme are inherently linked lists, the idea of a dotted pair is precisely that of a linked list, and for some things, flatly addressable arrays are what you want. Again, whether this has a place in an intro course is up for debate.
April 4, 2008 at 3:51 pm |
Ack, my <UL> got filtered and so that all appears as a gigantic paragraph :)