tags:

views:

627

answers:

17

My CS department is currently considering a new introductory "high level" programming course. It is partly aimed at non-majors or those with other primary majors that will find it useful to build programs, including biocomputation, etc.

I have a PhD in programming languages, but I'm finding it hard to say exactly what languages currently would best fit this situation. The current contenders from my point of view are Python, Boo, Ruby, F# and C#.

Personally F# wins for me, but I think Python will be more acceptable to other people, and Boo to me is better than Python just because of the instant feedback you get with an IDE than understands the types of things which really helps in teaching introductory programming.

C# with type inference and lambdas is increasingly getting close to Python in expressability, from what I can see, and LINQ does things Python can't easily, hence it is a contender.

What advice for this situation?

+4  A: 

If you're looking at non-majors, I would be tempted to shy away from functional languages, and look at something imperative like C# (which has advanced features like lambdas, which may go some way to address any functional requirements).

Have you considered Java combined with BlueJ ? BlueJ is an IDE geared towards novices, and that may well address your needs.

Brian Agnew
Java is right out. That's what we teach out majors, and we find it hard work. Java seems behind the times these days, as a langauge.C# is a contender. But, seriously programmers seem to find Java and C# more natural, but for mathematical things many people report that functional languages are more intuitive.
RD1
@Rowan Davies people can spend years programming in C# and not realize some of the functional programming features it supports, such as delegates and anonymous functions. And as of 3.5 (or was it 3?) lamdbas.
Matt
Yes - but when teaching you can easily teach it using a "higher level" style. Then it looks pretty similar to Python or F# or even Haskell.
RD1
+2  A: 

Java or C# - both have lots of good books and tutorials available, wide acceptance in the industry and look good on a resume. Also, both allow you to quickly produce something that is usable without having to deal with a lot of the lower level details. It's a good way for people to be able to see what writing their own programs can enable them to do.

TLiebe
This isn't about industry - these people will find jobs based on another scientific or engineering discipline, not their computing skills. There are higher level languages than Java certainly.
RD1
+16  A: 

MIT has switched from Scheme to Python for their EECS introductory course. I agree with Brian Agnew that functional languages are too difficult to comprehend, compared to imperative programming.

Martin v. Löwis
I didn't want to say that. But of course I meant it :-)
Brian Agnew
Yup, QUT and a few other universities has switched from Scheme to Python now too.
Dominic Bou-Samra
I agree that Python is a good language. But, actually what I find best about it is that it does do things following functional programming ideas. But without being too committed to them. For people often just trying to do calculations, functional programming is pretty good.
RD1
RIT switched from Java to Python this year. It seems like many schools are moving toward Python, and I can't blame them. One language can be used to teach programming constructs, object-oriented programming, and functional programming.
Thomas Owens
I personally think Python would be perfect with optional static typing. Boo has that. Alas, Python seems to have the same basic limitation that stopped Lisp taking over to world: no static type system. But, I guess if these students never write large programs it is fine.
RD1
I don't think MIT switched to Python because Scheme is too hard, that would be a sad joke.As far as I understood, the focus of the course has moved from the understanding inner workings of a program (cons cells, data structures, recursion...) to learning how to reuse software without having a total comprehension of it (OO, libraries from the real world, programs with GUI and network protocols...). Which makes sense.
Damien Pollet
MIT didn't switch because Scheme was too hard to understand, though. I expect they'll still teach FP (amongst other things); they'll just use Python to do it.
Craig Stuntz
@Craig I think you are right. Python supports FP well enough. Scheme is really nice though.
RD1
Damien is correct. MIT's switch to Python was because their entire CS curriculum was updated and the new intro course is focused on robotics and a Python library for it already existed: http://www.wisdomandwonder.com/link/2110/why-mit-switched-from-scheme-to-python
thraxil
I would say that there's more to it than that, because a Scheme wrapper would have been relatively trivial.
RD1
+2  A: 

What's the goal of the class? To do straightforward procedural programming (which includes the skills of breaking a task into small steps and implementing those steps in code) or to try to seriously reshape their thinking?

In either case, you probably don't want to give intro students LINQ or use lambda heavy code. You need to crawl before you walk.

F# is probably not a good choice either since it can't decide whether or not it is functional or procedural (yes, I understand the reasons and the distinction).

An ideal intro language should be straight forward, easy to use, and especially have a low barrier to entry to doing something interesting (ie, get the student hooked).

I would argue that of the list you offer, Python or C# fit nicely. Outside of your list, I would put LISP/Scheme if you want to take the Little Lisper approach to learning to write code and solve problems.

plinth
The Little Lisper approach would be fine also with F#. Better I think given support from the IDE is really extremely good in terms of finding type errors as you go. Lisp is seriously the most influencial language of all time. But, it shows it's age now, despite being the foundation for almost everything else.You could easily stick just to the functional side in a unit like this in F#... ignore the imperative parts.
RD1
+1  A: 

IMO, a statically typed language is the best way to start teaching high-level programming. I'd therefore suggest C# or F#, or even good old OCaml.

Dynamically typed languages are advanced material; it's really important for new students to understand the issues involved in typing first, IMO. Once the fundamentals are learned, the students are ready to move on to dynamically typed languages, and for that I prefer Python.

Edit: Based on another comment and a re-read of your description, it looks like you're aiming this class at "Programming For Math and Science Majors" or something like that.

In that case, I still stick by my statically typed suggestion. Go with F#.

Randolpho
By that argument, they should start with C.
Svante
@Svante: No way, no how. C may be statically typed, but it's a screwed up language and not nearly high level enough for the original post. Maybe I dumped on your favorite dynamic language, and for that I apologize, but I've been around the block a bunch of times, and in my experience statically typed languages are a necessary foundation.
Randolpho
They learn to understand typing with a dynamic language too. Dynamic languages also has types. Python also is strictly typed, so they really have to learn typing. I don't see how the necessity of declaring a variable would make a difference in understandning.
Lennart Regebro
I'm not considering any language that would require you to declare the type of a variable. If that's what you call a dynamic language, I'm not considering those.
RD1
Wow, folks sure do seem to think that I have a hate-on for dynamic languages -- it's the opposite, people! @Rowan Davies: Then take C#, Java, and F# out of the running. Oh, and OCaml. All are statically typed, meaning you must declare a type for a variable and that variable will always be of that type. C# 4 will change this somewhat, allowing for dynamic typing, but you must explicitly declare a dynamically typed variable. Current versions of C# and F# use type inference, but still require declaration of type; they just hide it better.
Randolpho
@Randolpho: Nope. You say "statically typed, meaning that you must declare a type for a variable and that variable will always be of that type." The second half is right, the first half is wrong. Static typing means that the type of a variable doesn't change at run time. However, languages that use type inference, like C#, F#, and Haskell for example, don't require the use of type declarations. You seem to be conflating static typing with the presence of type declarations -- they are not the same thing. Rowan Davies wants a language that doesn't require type annotations, that's all.
Daniel Pryden
If you want to be pedantic about it, type inference *is still a type declaration*. You cannot do, for example, `var foo;`. This does not declare a type. `var foo = new MyFoo();`, however, does.
Randolpho
@Randolpho - I disagree, and I think you're only talking about a very limited form of type inference.In Haskell and F# you can define factorial as follows, with no types declared.Haskell: factorial n = if n=0 then 1 else n * factorial (n-1)OCaml/F#: let rec factorial n = if n=0 then 1 else n * factorial (n-1)
RD1
@Randolpho: Rowan Davies is correct. C# is the only language with type inference where type inference works that way. That simply tells me that C#'s type inference isn't nearly as good as that of F# or Haskell. It doesn't invalidate my point, which is that you are confused over what static typing means.
Daniel Pryden
+1  A: 

Look at Processing. It starts out simple, but you can do quite complex things with it. The focus is on creating a visual of data and it targets non-programmers.

Lou Franco
Like Logo, Processing gets quickly complex, too.
Aaron Digulla
I looked at it, but I think we are aiming for our students to be able to do more than that.
RD1
You might also consider Alice (http://www.alice.org/)
plinth
Yes, I know Alice well.I don't think it's right for our scientists and engineers in terms of some casual programming.
RD1
+6  A: 

Personally I think that functional languages will work well for beginners. I think that most programmers learn imperative languages first, then functional languages, which gives functional languages a reputation for being hard to learn.

In my opinion, a course that begins with functional languages might be less confusing. It would allow students to focus on the idea that a program is composed in distinct parts that fit together like a machine, which I think would visualize very well for non-majors. I'd certainly hate to be stuck explaining memory allocation, pointers, classes, and many other imperative features, when a non-major student really just wants to build something useful.

That said, there's a lot of arguments for using an imperative language, such as readily available teaching material and prevalence in most systems. In the end I think it depends on if you're aiming to send these students off into the world creating computer systems on a team, or just giving them enough knowledge to get things done.

Kai
Right - I agree here. To people not focused on programming, functional languages are less confusing.To those who have already learnt imperative ways, it's hard to go back.
RD1
+2  A: 

Python magazine had an article about using Python for the Introductory course, with excellent results:

http://pymag.phparch.com/c/issue/view/105 (Costs, money, sorry).

Basically the conclusion is that Python is just as good as C in preparing you for a programming course where you need to use C (which is a bit of a surprise) and more positively, even those who did not go on to major in CS continued to use Python after the course ended to solve their real world problems.

So there is no doubt in my mind: Python.

Lennart Regebro
Yes - but old news to some. Experience in a functional language is well known to make nearly all other languages accessible.
RD1
Yes, like teaching set theory will prepare you for maths better than addition and subtraction. Problem? It's so abstract many never gets it. Functional languages as an introduction to programming for non-majors is definitely not a good choice.
Lennart Regebro
So learning C is best???
RD1
I have said nothing that even in it's wildest dreams could remotely consider imagining anything that no matter how much you squint would look like something that can be misinterpreted in that way.
Lennart Regebro
Apologies - I'm being extreme. You said set theory is too abstract for learning arithmetic. And I thought that was similar to saying functional languages are too abstract for introductory programming. I was disagreeing. Because functional languages ARE much closer to arithmetic, and less close to set theory. They are more like a big fancy calculator. Imperative stuff is pretty abstract to those that haven't learnt it.
RD1
Most beginning students would find the `for x in some_list` idiom much easier to grasp than the functional `map` idiom. List comprehensions are a happy medium between the two, but the beginning students should learn the `for` idiom first and then move on to list comprehensions. Even weirder is the functional `reduce` when compared to a straightforward `for` loop with an accumulator variable. It gets even weirder with lambdas. In short, for stuff beyond calculating expressions that might contain function calls, the functional way of doing this is IMHO too abstract for beginning students.
steveha
No, Rowan, I can't seriously agree that imperative is more abstract than functional, sorry. Imperative is giving the computer a serious of instructions, which is does as soon as it gets the instruction. That's not abstract, it's very concrete. Functional programming is turning whatever you want to do into one huge mathematical function. It's extremely abstract, sorry. Functional programming is useful for majors, no doubt, but you did explicitly say this was also for non-majors.
Lennart Regebro
@steveha the functional map idiom is the same thing. Most modern functional languages even have a syntax that matches what you gave (but does more). I'm guessing you're thinking of older functional languages.
RD1
@Lennart: aliasing is not a concrete concept. It's quite abstract. "x is 3" seems quite concrete to me. If you tell me to add one to x, that's slightly less concrete because you already told me that "x is 3". Only by introducing the abstract notion of a store that changes over time can you explain imperative langauges. Functional languages don't need that, hence are less abstract. It may seem more abstract to you because you are already familiar with the concept of the store that changes over time. But most people aren't - it's easier to leave that out.
RD1
+4  A: 

I find that non-CS-majors who dabble into programming generally gravitate towards scripting languages (makes it easy to automate tasks) or specialized scientific languages (eg: MATLAB, statistical analysis languages, etc...)

If you want a general-purpose language, I'd tend to go with Python, which also has a simple syntax, is easily available on many platforms, and can work decently both as a general-purpose number-crunching tool AND a scripting tool.

Otherwise, for scientists and engineers, you can do worse than teach them MATLAB (which is what my undergrad school did with mechanical engineering majors). It's not a very elegant language, but it shows the basic concepts, and that's what they're most likely to use throughout their career.

These might not be the "best" languages to learn, but IMHO, the best language is the one they'll keep using to solve their problems once the class is over, and these two fit the bill.

Kena
Yes, this is realistic. We will have another course in Matlab though - this will be for those wanting to actually build programs. Matlab is really not right tool for that.
RD1
A: 

The first two-thirds of the course should be imperative language with the last third being functional. I would choose C# for the imperative segment and can't recommend a functional language since I do not use them regularly. F# seems practical to me because you could use the same Microsoft free tools for both segments. You wouldn't have to spend two weeks of the semester dealing with student's lame setup issues.

Steve
Seriously: why not make the first third functional in F#, then 2/3rds imperative in F#? There's quite a bit of experience that says that people who learn imperative programming first have more trouble understanding functional programming. When the converse isn't true at all.
RD1
That would work too. I see functional languages having a smaller domain personally, hence 1/3 dedication. I started to learn F# but it felt geared toward solving math functions. I like the concepts and the benefits, such as thread safety due to statelessness. However, I can solve the same functions using imperative languages. For me, the domain for C# is much larger. I understand this is an intro course and they won't be learning about alot of other issues such as GUI dev, messaging, advanced IO. Do functional first, conduct your own experiment on them!
Steve
Smaller domain? We shall see. Certainly OO is losing ground to functional recently, and one of the strengths of C# compared to F# is that it's turning towards functional concepts in a way that, say, Java is not.There are game engines written in functional languages. There were OO systems in Lisp before Smalltalk caught on. Functional languages have a broader domain than OO, in my view.
RD1
+6  A: 

As a recent CS grad, it's worth noting that while learning Lisp, SML, and Haskell was very influential, Ruby was the first language that made me really excited to throw around functions as first class objects. (I had learned Python before, but I found Ruby much more intuitive.) Part of the reason is that Ruby was instantly usable and made me more productive within a few days, plus there were jobs in Ruby within a couple blocks. I can't say the same thing about SML or Haskell (esp. in the jobs category), although they're definitely attractive because they're purely functional languages. (There is something mind-bendingly cool about learning that paradigm.)

From what I understand, F# is starting to change the functional language landscape. I'm not sure what implementations are out there, but keep your OS X and Linux users in mind if that's what you go with.

Benjamin Oakes
Well, F# isn't purely functional. It's in the same camp as Python really - functional plus imperative plus OO. Haskell is truly influencial though. Ruby is fine... but to me as a language it has nothing new other than being very selective on what to include in terms of complex concepts. What is better is a language that includes only simple concepts, and builds the rest from those.
RD1
Regarding: "What is better is a language that includes only simple concepts, and builds the rest from those." Depending on what you mean, this is what Ruby does. I'd be happy to discuss this if you'd like.
Benjamin Oakes
(As an illustration, you might look at Rubinius -- Ruby written in Ruby -- made in the tradition of Lisp.)
Benjamin Oakes
Oh - Ruby starts from very complex concepts compared to some other languages though. You can certainly do better than Ruby for an orthogonal and logical foundation.
RD1
I'd agree with that. But if it's for beginners... I guess it really depends on what the OP's needs are.
Benjamin Oakes
A: 

From my experience learning Ruby myself, I would lodge another vote for it. I suspect that the expressive, sugary syntax will work well for novices simply because "say what you mean" will make it relatively easy to pick up the language and feel like things are getting done.

Ophidian
The trouble with sugar is that makes things look easier than they are. In a teaching context, that's bad. You want people to be able to generalize what they've done, and that means the constructs shouldn't be sugared.
RD1
RD1, what ruby sugar is liable to confuse a novice (for the reasons you give above) ?
banister
A: 

Personally F# wins for me, but I think Python will be more acceptable to other people

Go with F# / OCaml. Here, in France, OCaml is the most used language for teaching programming in universities or classes préparatoires aux grandes écoles.

Stringer Bell
+1  A: 

Except for the fact that its documentation isn't terribly good (yet), I would recommend Boo. It gives you the easy syntax of Python and the ability to explore functional approaches (like Python), together with the great standard library of .NET.

Your point about tools being better able to understand types is a strong vote in favor of Boo, IMHO.

However, as a second choice, F# is definitely a strong contender as well, for similar reasons.

Daniel Pryden
Yes, well said. Boo and F# seem the best options currently. Alas both are less stable as languages due to the new VS2010. In fact, I'd prefer something not tied to Visual Studio and with clear Mono stability - but is that currently at the stage where you'd let first year students use it?
RD1
A: 

I would use C# , C and the other languages are too hard when starting. Pascal used to be used first year , C and Lisp 2nd year . Avoid functional UNLESS there are lots of maths /science majors.

Ben

http://www.shanghai-software.com/blog

Benk
A: 

Boo is a great language to learn on, based on your above criteria. The compiler does its best to get out of your way and it has some really crazy, advanced features like syntactic macros and an extensible compiler pipeline (which don't really apply in the context of this course, but are nice, nonethless).

If you wanted .NET stdlib access (read: not python's crazy stdlibs naming scheme) and static typing with a less-cumbersome syntax (read: c#), then Boo fits that mold pretty well.

As for Mono support, Boo supports it very well. Several of the core developers on the Boo team are loonix users and, as such, are very quick to address build issues that arise as a result of Mono incompatibilities. Also, compared to C#/F#/etc, Boo is a pretty fast moving project in terms of getting changes into the src repo as a traditional Open Source project. This could also be viewed as a drawback, depending on your POV (relative lack of good docs, lots of people are using it but few are actively "pimping" Boo in the community).

But in the criteria spelled out above, I think Boo is a great candidate. It has adequate tooling (SharpDevelop in windows and MonoDevelop in windows/linux/osx) with things like intellisense but is not so entangled in its syntax that you can easily work in a "lower level" approach (vim, etc) if that's your cup of tea.

Plus, unlike C# (but like F#), Boo ships with an interactive shell, booish.exe, which is a valuable exploration/teaching tool.

The one warning I can give about Boo is that you can get into trouble with things like the pervasive compiler inference (it will infer types of locals based on instantiation.. you can skip typing method args (they will be a System.Object, which is a Bad Thing IMO due to boxing (but who cares for an intro class?)), the compiler will try and infer return type if you omit it in the method sig.. so if you have multiple return statements with different types, then your method will be a System.Object, once again.. or that the compiler will stub out unimplemented methods on interfaces that your custom types implement (unlike C# which will cause a build error) .. things like this can get you into trouble if you aren't aware of them and act accordingly.. but these are more issues for application developers and not the problems of students in an introduction to programming languages course.

Best of luck, regardless of which language you pick!

olson.jeffery