47

I find myself repeatedly annoyed by having to teach freshmen about special language rules (like array-to-pointer decay) that have absolutely nothing to do with programming in itself. So I wondered:

What is the programming language with the smallest number of special language rules, where everything is first class and can be composed without annoying technical restrictions? Wouldn't such a language be the perfect teaching language?

Moderator Note

We're looking for long answers that provide some explanation and context. Don't just list a language: please explain why you think the language answers the question. Answers that don't explain anything will be deleted. See Good Subjective, Bad Subjective for more information.

Ixrec
  • 27,621
  • 15
  • 80
  • 87
fredoverflow
  • 6,854
  • 8
  • 39
  • 46
  • 1
    Try using Unlambda - there's close to a smallest possible number of language building blocks. A little bit more serious answer: Scheme (R5RS specifcally). – SK-logic Aug 25 '11 at 11:23
  • @SK-logic, Unlambda isn't orthogonal because `I=SKK`. The ultimate in orthogonal languages are single-instruction languages like Jot and RSSB. – Peter Taylor Aug 25 '11 at 11:58
  • 11
    @Peter - I don't think he strictly means minimal. A minimal language just ends up with all the extra definitions in the library, so the students have to learn them either way. The way I read this question is "what language best follows the principle of least surprise?". –  Aug 25 '11 at 14:30
  • I know its not a real language but anyone for psuedocode? That's what I learnt first. Then onto high level abstraction languages – James Khoury Aug 26 '11 at 00:18
  • @Steve, the languages I was talking about don't have libraries. And the reason I went for single-instruction languages is that "orthogonal" means that different language features don't overlap. If there's only one feature that comes for free. And there's nothing to surprise you, so even with your rephrasing it works. – Peter Taylor Aug 26 '11 at 08:30
  • @Peter Taylor, probably a trivial syntax sugar should not be considered as "feature overlapping". – SK-logic Aug 26 '11 at 08:38
  • 1
    @Peter Taylor: could you provide an example where Timtowtdi conflicts with orthogonality? – keppla Aug 26 '11 at 10:05
  • 1
    I think “orthogonality” is a poor choice of words here. As Peter and Steve have established, what you really mean is “principle of least surprise”, or some closely related quality. – Konrad Rudolph Aug 26 '11 at 12:42
  • Wow. Why was this question protected by @Mark Trapp? This definitely seems like a question that he would've swiftly closed. He must've been in a good mood on 8-25-11. – Jim G. Feb 28 '13 at 15:16
  • A related q: http://programmers.stackexchange.com/questions/180662/are-there-any-programming-languages-that-follow-a-minimalist-development-approac – nawfal Jul 11 '15 at 09:55

9 Answers9

54

When it comes to 'very few rules', I would argue, Lisp or Smalltalk would win. The bare Syntax can be written on one beer tab.

But in my experience, the simplicity of Lisp and Smalltalk does not mean they are simple to understand and easy to teach. While not the 'pure' way, in my experience the to-do-list-style of imperative languages is the easiest to grasp for newbies.

Therefore, I would suggest Python, Ruby or something of similar abstraction: You find (nearly) every basic concept in them (OK, no pointers), but you don't need to understand it from the start to make something working.

Glorfindel
  • 3,137
  • 6
  • 25
  • 33
keppla
  • 5,210
  • 24
  • 32
  • 1
    +1 for choosing a lang with a relatively high level of abstraction – Joseph Weissman Aug 25 '11 at 14:52
  • 33
    impressive work measuring syntax in units of a beer tab. – psr Aug 25 '11 at 17:03
  • While Python and Ruby spare you from managing memory, I'm not so sure that the *languages* themselves are simpler. – benzado Aug 25 '11 at 21:13
  • 3
    And don't forget Perl. Lot more Perl out there than most people think, and the user community is *huge*. – Randal Schwartz Aug 25 '11 at 21:45
  • 20
    Perl may be very powerful, but a guy who finds it the easiest path to programming must have the equivalent of Indiana Jones's temples' tunnels as main corridor from his bedroom to his showers... – Kheldar Aug 25 '11 at 21:58
  • 2
    [Io](http://iolanguage.com/) provides a single, simple syntax with no bells or whistles. It's also a prototype based programming Language; Io has no sense of classes that can be instantiated. Everything is a clone of an existing object. – 9b5b Aug 26 '11 at 05:51
  • +1 for Io, forgot it. Maybe it's worth an answer? – keppla Aug 26 '11 at 07:33
  • 9
    Perl's syntax could fit on a beer tab, provided you drink enough beer. – Dave Sherohman Aug 26 '11 at 09:18
  • 4
    @Randal, the question asks for an *orthogonal* language. Perl's philosophy is to be non-orthogonal - "there's more than one way to do it". – Peter Taylor Aug 26 '11 at 10:02
  • @benzado: it's not only the memory management. For example, python has first class functions, first class types (Classes are Objects too), first class modules, iteration built in (so you dont have the accidental complexity of for (int i=0; i – keppla Aug 26 '11 at 10:03
  • 2
    @keppla, functions are not really that *first class* in Python, there's a number of very annoying surprises (e.g., no statements for lambdas, etc.). I would not call Python an orthogonal and surprise-free language, it is rather an opposite thing. – SK-logic Aug 26 '11 at 11:38
  • On TMTOWTDI and non-orthogonality, there are some good examples [here](http://www.resoo.org/docs/perl/perl_tutorial/lesson07.html) with the different ways to dereference references. – Peter Taylor Aug 26 '11 at 12:38
  • @keppla +1 good answer, though I wouldn't discourage the teaching of LISP as a first language. Python is multiparadigm while LISP is more functional. It depends on the audience. I hypothesize that an artistic audience (music, visual art, literature) would find imperative languages easier to understand while a mathematical/engineering audience would find functional languages easier to understand. Although musicians, in particular, may digest either paradigm equally well. – Matthew Rodatus Aug 26 '11 at 12:40
  • @Matthew Rodatus: you're right, it probably depends on the audience. I was speaking out if my limited experience with teaching concepts of programming to fellow students, who always had a hard time grasping functional simplicity, and seem only to get it when presented as alternative to ugly imperative code. – keppla Aug 29 '11 at 08:05
  • 1
    @Peter - if you're not objecting to Python or Ruby in the original answer, there is nothing absolute that distinguishes Perl from that camp. Thus, my comment is fair. – Randal Schwartz Aug 29 '11 at 20:40
  • @SK-logic: could you please elaborate, or provide a link that helps me to understand your criticism regarding the firstclassness of functions? – keppla Sep 05 '11 at 08:52
  • 1
    @keppla, you can't use statements inside anonymous functions in Python, and there are no expression alternatives to them - which renders Python a language with no first-class high order functions, effectively. – SK-logic Sep 05 '11 at 09:26
  • @SK-logic: the aspect you talk about is in my nomenclature 'anonymous' functions. When i say 'first-class-functions', i refer to the fact that they are objects with no special case, that can be given as arguments, bound to names, etc, something that is/was not the case in pascal or visual basic. – keppla Sep 05 '11 at 12:40
42

I'd say LISP, or Scheme or a language from that family would be the most orthogonal. With let, lambda, define, if, cons, list, and ( ) you can teach pretty much anything that you'd want to in an intro course. There's also no need for preprocessing directives or int main() and stuff like that which students just include but don't see a reason for.

In my intro CS courses, we did a lot of really cool things with Scheme: implement a Turing machine, implement a TC-201 computer, write a context free grammar, use recursion, write merge and insertion sort, implement adders, and tons of other stuff.

I had done Java in AP comp sci before college, but Scheme was great because I could cut the clutter and focus on the actual concepts in my program. It was a great class and I'd highly recommend you try it for your teaching.

BlackJack
  • 3,867
  • 5
  • 33
  • 52
  • 5
    Agree. Racket (formerly PLT Scheme) is a slightly-more-friendly Scheme variant which our school uses with great success in introductory classes. – NickAldwin Aug 25 '11 at 15:53
  • 3
    What about Haskell? I do not know much of Haskell, but I would expect it to be an orthogonal language. – Giorgio Aug 25 '11 at 17:25
  • 4
    @Giorgio: Haskell syntax is quite more complicated, though only a subset could be exposed I guess. The very fact that you have to interact with IO monads from the beginning to get any interesting program is a tad annoying given the OP objective. – Matthieu M. Aug 25 '11 at 17:44
  • 4
    For "orthogonal," I vote for Scheme, particularly the [Racket](http://racket-lang.org/new-name.html) implementation. Racket's environment is designed to make a learner's path easier than something like raw Common Lisp. The language is clean, with few rules, indeed. Long ago, MIT decided to use Scheme for teaching Freshman students, using the book, [SICP](http://mitpress.mit.edu/sicp/). Those students who survived seem to perform quite well out in the marketplace. However, this approach will not directly teach students how to write commercial-grade code in the most commonly-used languages. – John Tobler Aug 25 '11 at 19:56
  • 2
    Yes! The fact that Scheme is radically different from most "real" languages lets you focus on *programming* and not on APIs. Learning Scheme is like the "[wax on, wax off](http://www.youtube.com/watch?v=3PycZtfns_U)" of coding; seems like a waste of time until you realize you have a deeper understanding of the computer than before. – benzado Aug 25 '11 at 21:22
  • 1
    @Matthieu M: The fact that you have to use monads for I/O is in fact, in my opinion, an example of orthogonality: there is no ad-hoc concept in the language to support I/O. And I do not find the <- syntax very difficult to use: you do not need to understand the whole monad theory in order to use it. – Giorgio Aug 29 '11 at 04:53
  • @MatthieuM. you do not need to understand with "a monad" to do IO in haskell any more than you need to understand buffered stream readers, abstract classes, inheritance hierarchies and OOP to do IO in java. you just need to call functions in the right way, and that's really not hard at all to do. actually understanding everything under the hood, yeah, that's complicated, but ALL kinds of IO are complicated if you wanna get down and dirty with it. – sara Aug 15 '16 at 14:58
17

Pascal was specifically designed to teach programming. It's easy to learn (it was one of the first programming languages I learned).

Henrik
  • 297
  • 1
  • 5
  • 3
    I also learnt to program using Pascal and I find it is a very clean language. The only non orthogonal feature I can think of is the syntax of the writeln() and readln() procedures, which have a variable number of arguments and allow to specify formatting. – Giorgio Aug 25 '11 at 17:24
  • I found it a very frustrating language. But I may be projecting, since I had a very, very bad instructor. – greyfade Aug 25 '11 at 20:23
14

Logo: it's still alive and kicking!

; draws a triangle
FORWARD 100
RIGHT 120
FORWARD 100
RIGHT 120
FORWARD 100
RIGHT 120

It might seem more like a toy then a programming language, but it wouldn't be a bad first step for a lot of people. The syntax is very simple, but the turtle provides a more concrete form of feedback than most languages/environments. Trying to create a specific shape is a great way to learn the process of thinking ahead to solve a problem.

If you have an aversion to turtles, though, I really think Scheme is the way to go.

benzado
  • 2,293
  • 17
  • 23
  • 1
    Believe it or not, Logo is a Lisp, just like Scheme. Most users don't get far enough beyond simple looping & turtle graphics to learn this. – Sean McSomething Feb 28 '13 at 19:58
  • @SeanMcSomething That's interesting, given the focus on side-effects (moving the turtle) rather than evaluation of expressions. – benzado Mar 04 '13 at 06:37
10

I would propose both SML and Haskell. Orthogonality has been a principal design point for both. In particular, the core of SML (that is, the portion of the language not concerned with modularity) is pretty much a typed lambda calculus. As a result, most language features are driven by types and the types in turn drive the introduction and elimination forms for the values. This is pretty much ideal.

There are a few non-type-theoretic warts in both languages (eqtypes in SML, seq in Haskell) but they still beat the pants of anything else out there in terms of bizarre interactions of unrelated language features.

Lambdageek
  • 713
  • 4
  • 8
8

Whatever the choice, I would strongly urge teaching a “real” language. Teaching toy languages works for some people, but for others it’s very, very frustrating due to the disconnect to the real world. Some people need real-world relevance as a motivation for learning, and it’s not our place to judge this learning strategy (in fact, that’s a common misconception).

This disqualifies languages such as Logo, but also domain-specific languages such as Processing. While the latter is extremely useful for certain things (e.g. producing info graphics), the use is too restricted for most uses (and thus most users). This also excludes Gofer, a useless Haskell subset. It also excludes Pascal because although the latter has been used in real projects, it just isn’t relevant any more and simply lacks essential features (e.g. built-in strings).

Of the practical languages, I’d agree with those already mentioned: modern Lisp or Scheme dialects, Haskell, Python or Ruby. Personally, I’d probably use Python but all those choices have their share of advantages and disadvantages.

Konrad Rudolph
  • 13,059
  • 4
  • 55
  • 75
  • 2
    It is a fallacy to claim that teaching a "real" language is the way to provide real-world relevance. It is the teacher's job to show how the "toy" language relates to real-world skills. Learning to juggle by starting with knives does not mean you are learning more relevant juggling skills. – benzado Aug 26 '11 at 19:50
  • 3
    @benzado You misunderstood my point. If you learn a toy language you have to *transfer* your skills to make them relevant to real-world problems. My whole point was that *this transfer is an additional indirection that actively prevents some people from learning*. Different people learn in wildly different ways, and some people really need this immediacy. Learning to juggle with knives isn’t the same thing. The real analogy would be with learning to program by writing a live missile guiding system as the first project, and I never suggested that. – Konrad Rudolph Aug 27 '11 at 09:06
  • 3
    I get your point. We just disagree. I think the transfer is important, it requires that the student has a deeper understanding than one who has a successful guessing strategy (e.g., one who "solves" word problems by picking out numbers and plugging them into the formulas in the beginning of the chapter). In other words, if they can't transfer what they learned, they never learned it in the first place. To keep students motivated, you just have to choose the right problems, which is important regardless of language, "real" or "toy". – benzado Aug 29 '11 at 16:01
  • @benzado Transfer *is* important, no argument there. But it’s a whole ’nother disciplin that needs to be taught, and some students don’t possess it. Besides, the “deeper understanding” part is also true, but also besides the point: this is already an advanced state that needs to be *reached*. Once the students have learned “it”, they can transfer it. But *first* they need to learn, and in order to do that, some students need relevance. *Transfer comes later.* – Konrad Rudolph Aug 29 '11 at 16:16
  • In math edu (where I have a tiny amount of experience), "Learning without Understanding" is a big problem: a focus on *how* to do it without *why*. My claim is that if you teach the *concepts* of programming, a toy language will do fine, and *if you succeed*, the transfer to a "real" language won't be hard. (If transfer is hard, you taught procedures, not concepts.) A toy environment doesn't prevent people from learning, but it does requires good lesson planning to be engaging. (I like this thread but I think we've crossed over into discussion territory and the moderators will be displeased.) – benzado Aug 29 '11 at 19:03
  • @Konrad Rudolph, benzado: I think it is important to learn the concepts of programming using a pure language because when you are learning you want to focus on the concepts and many practical languages contain too much **noise** (e.g. features that are there for historical reasons but are not going to be removed because there is a large community of developers using the language). At university I was taught the principles of programming using Pascal. Later we had to do projects in C but we were expected to be able to learn it by ourselves once we had learnt the theory. – Giorgio Apr 26 '12 at 18:03
  • @Giorgio I am almost certain that you are objectively wrong about this, and that current research in didactics corroborates this. You *do* point out real shortcomings of programming languages, and you are right that they present a hurdle. But this is an unfortunate consequence of reality. The alternative – using a non-real language without practical relevance is worse. But the languages I’ve listed – Python, Haskell, Lisp – come with very little historical baggage and noise. They allow students to concentrate almost exclusively on concepts. – Konrad Rudolph Apr 26 '12 at 18:37
  • @Konrad Rudolph: Maybe I have just understood your answer in the wrong way, sorry. I agree that I would like to learn programming in a real language and not in a toy language. Pascal is a language in which you can do real programming, even though it was born for teaching. Pascal is cleaner than C and therefore it is more suited for teaching IMO. – Giorgio Apr 26 '12 at 19:03
7

Tcl has 12 rules that govern the entire language.

[1] Commands. 
[2] Evaluation. 
[3] Words. 
[4] Double quotes. 
[5] Argument expansion. 
[6] Braces. 
[7] Command substitution. 
[8] Variable substitution.
[9] Backslash substitution.
[10] Comments. 
[11] Order of substitution. 
[12] Substitution and word boundaries.

There are very few special cases or reserved words or characters.

gnat
  • 21,442
  • 29
  • 112
  • 288
Bryan Oakley
  • 25,192
  • 5
  • 64
  • 89
4

What is the programming language with the smallest number of special language rules, where everything is first class and can be composed without annoying technical restrictions? Wouldn't such a language be the perfect teaching language?

To expand on my comment, in Jot everything is first class (because it's a lambda calculus) and can be composed. There is only one instruction. It's an absolutely awful teaching language.

In general, Turing tarpits have very few special rules and require you to understand the fundamentals of computation very well before you can do anything. The perfect teaching language allows students to experiment without pulling out all of their hair, so higher level abstractions are actually a good thing.

Peter Taylor
  • 4,012
  • 1
  • 24
  • 29
  • Thank you for introducing me to the term 'turing tarpit', i always needed a term for this kind of simplicity. – keppla Aug 26 '11 at 09:52
  • I agree that students should be able to experiment, but requiring understanding before you can "do anything" seems like the whole point of teaching. – benzado Aug 26 '11 at 19:52
  • @benzado, I agree that the point of teaching is to impart understanding. But with most people you have to start with the basic concepts, let them get their heads round that, and then teach them intermediate concepts. So you want a language where someone who understands a little bit can write programs which do a little bit. There's a reason that most programming courses don't start out by teaching Turing machines or Minsky register machines. – Peter Taylor Aug 26 '11 at 20:18
  • 1
    Right, I think we differ on what "do a little bit" means. If you want to (for example) appease the "show me how to make video games" contingent, you can do some things, but they will get to a point because they can't make progress and get frustrated, and then you have to go back to the "boring parts" so they can gain the understanding to move forward. At this point, they are already frustrated in a bad way and may just give up; on the other hand, doing the "boring parts" first and building upwards means continual progress. But obviously you don't start with a strip of semi-infinite tape. – benzado Aug 26 '11 at 20:44
2

The most important features in a langage you learn are:

  • principle of least surprise (PASCAL)

  • readability (Ada)

In my opinion, the second trumps the first, since reading code is even more important than writing it.

Now again, I write C#, Java, Objective-C and Javascript for a living, all of which have horrible quirks :D

Still if I had to choose one langage to start with, I'd go for C#. It's relatively easy to read, has few serious surprises in itself (they are most often hidden in MS tools/frameworks...) and a massive amount of code to be read and documentation, both of which are essential to learning well.

Kheldar
  • 219
  • 1
  • 7
  • If it's just for the readability, and not for the static typing and safety of ada, Python and Visual basic (yeah, i know, not the cool kids way) have a similar clutter free syntax, imho. – keppla Aug 26 '11 at 09:51
  • Yes I agree with you, but "if it compiles in Ada, it should run". Doesn't prevent logic errors though, as _Ariane V_ can tell :D – Kheldar Aug 26 '11 at 09:53
  • I've been thinking whether static typing is useful for beginners or not. It gives more support (like training wheels) but this can be seen both as good thing and a bad thing. It pushes some responsibility away from student to type system. – Aivar Nov 30 '11 at 11:11
  • @Kheldar, no programming language can prevent management f***ups like the one that was responsible for the Ariane V failure. You should do your homework on this one. – John R. Strohm Oct 03 '13 at 12:26
  • @JohnR.Strohm that was exactly my point: sometimes it's not the language, it's the engineering flow (eg, management) that's flawed. You could have worded your comment less aggressively though, in my opinion. – Kheldar Oct 04 '13 at 09:32