I don't believe that programming is something you need to just get. I've seen a lot of people struggle on assignments like these as a TA. Usually, it's that they're missing certain concepts, but they don't know which ones and they can't debug themselves. If you know 70% of basic Java, you won't be able to create a working solution. You'll get tripped up on a type mismatch error that just makes you bonkers until you give up because you don't know what the error message means or you tried to make a templated array rather than an Object array and casting it to a templated array or whatnot.
There are lots of little pitfalls in programming that are just terrible. In C, you can just walk off the end of an array (or the beginning). In Java, you can store an object in an array and then modify that object in both the array copy and the one you have in a regular variable because Java works by reference, not by copy. A lot of the time, you just need someone who is a lot more learned in programming to notice that. It's not that you don't get a concept like object references, it's that if it's not in your mind, you don't notice when your code does it and it takes a long time for these things to really get into your mind to the point that you catch them fast.
And most people give up. You get hit enough times with silly things like these and you just want out unless you're truly dedicated. I know when I was learning, I hit all the trap doors. It's why I noticed them when other students made them. Heck, back in the old days of Java, you could easily screw up things like int vs. Integer and not notice it - especially since a lot of professors might not make a distinction because for veteran programmers, we know that pitfall, but also because its place is at the start where students get inundated with syntax and such a distinction might go unnoticed (or abbreviated as int in notes).
I would think schools should hire more TAs to help students through those pitfalls except that most students like to do assignments at the last minute where these errors become the source of the mind-breaking stress.
To hire sufficient good TAs, schools would have to pay much more than they do, as they are competing with a lucrative commercial industry. However academic hierarchies won't tolerate paying elevated salaries to people with lesser paper qualifications just because they are talented. So every year you get the people who want a bit of cash on the side, but aren't yet good enough to do part-time contracting.
I have to wonder if a language with less syntax would be easier to pick up.
Start people that are totally new to programming with something like Scheme or Ruby (surely there are even better ones than these) that requires less arcane punctuation to do things like hello world, then once they get the hang of things, slowly introduce them to more structured languages.
My university started the introductory course (for all majors, courses were common for the first 2 years) with scheme and most student seemed to understand it fairly well. We still had the 20% that were extremely fast because of having programming experience before (but learning scheme was a nice change compared to what they used to do) but the numbers of students completely lost seemed rather small.
So I think scheme is a very good choice for an introductory course...
Ruby is very nice (I'm mainly programming in it nowadays) but I'm not sure it's such a good choice for beginners, there are a lot of small details that could trip up beginners I think (block vs procs vs lambda vs method(:name_of_method), the eigenclass...)
The problem with Scheme is that it's very difficult to learn in a vacuum. You can do all sorts of interesting things with it, but if people can't use it to do real work then they quickly lose interest (I'm not talking about CS types who are interested in computing anyway, but others who would fine programming a useful skill in their "real" jobs). From that POV the best teaching language is something like VBA, awful tho' it is, because it gets people from zero to "look what I did!" very quickly. Or MATLAB or some other language that's looked down on by purists.
Well, I think Python has one obvious preferred way of doing things, but then tends to let you do it anyway you want. Which I guess is a part of the whole "Python supports multiple programming paradigms (primarily object oriented, imperative, and functional)" thing. Not that I know that much about Python either but it is my preferred language.
You can experiment with some functional ideas in Python, though -- once you're familiar with basic Python, exploring the stuff you can do using higher-order functions is likely to be quite educational, with the caveat that (in that language) recursion will blow up on you when it gets too deeply nested.
So, while it doesn't really support FP fully, it's probably sufficient for basic FP from a pedagogical standpoint. (I also think it's one of the better candidates for a first programming language overall.)
I have read email list anecdotes of Smalltalkers who introduced their kids to Smalltalk as a first programming language. In the majority of cases, their kids liked Smalltalk and their reactions to subsequent languages are, "Why are they so complicated? They don't do anything more than the simpler one."
Smalltalk as it exists today has about 8 terminals & nonterminals in its grammar. Python has something like 30. Ruby has something over a hundred, but for an intro to programming, you can just ignore most of the grammar and use a subset which makes it very close to Python in simplicity.
Smalltalk was specifically designed to be usable by children.
I think the problem with those languages is they're too different for a starting course. Scheme is obviously very powerful, but its syntax is wildly different than most popular programming languages used today. As for Ruby, don't even get me started. There's practically no syntax at all; merely reading it agitates me.
I think, in the beginning, people are most likely to understand concepts like Objects (Circle, Square, etc.) and how they relate to other stuff since it's so based off how we normally think. Also, since Java is statically typed, I think it makes things appear to contain less "voodoo". Then again, I could be completely wrong; I had been programming in other languages for years before taking my first Java course in college and only attended the class when there was a test.
Ruby has quite a bit of syntax (parens, methods on objects, blocks, etc), whereas scheme has almost none (parens, special forms like lambda, #t, '()).
Of course both have less obtrusive syntax than Java, which requires the famous
public static void main...
just to get started. That is the kind of stuff that I think confuses true beginners. They look at that stuff and think "holy crap memorize these voodoo incantations" and never really leave that mindset once they get there. Even if they eventually learn what static means, they will always treat it as such.
I think once they get the hang of programming in something, it's easy to build up from there. I just think it causes people to focus on the wrong thing (syntax rather than semantics) when they are first starting out.
I dunno--I started community college with an HP-48 instead of a TI calculator, and reverse polish notation wasn't a problem at all once the friend who'd convinced me to get one explained how the stack was like the way you do arithmetic on paper.
>>Also, since Java is statically typed, I think it makes
>>things appear to contain less "voodoo".
No way. It's better to learn other programming concepts without the distraction of having to maintain types. Duck typing makes a lot more sense to new people, in my experience. Most of the popular languages with non programmers (PHP, VB, JavaScript) fit this mold.
I have tested it (in http://github.com/kragen/peg-bootstrap/tree/master/peg.md) and it seems to work for that fragment, although I haven't examined the parse tree to see if it's right. (Obviously the definition of namechar is wrong, and there's no $end token separating statements, and you can't call methods on things that aren't constants or self, etc.)
I remember checking out a first-year CS textbook from a library, back when I was in HS. It described one-bit adders and other hardware and then prescribed a lab assignment that required stuff I couldn't buy at a computer store.
Later, I signed up for a CS course at a college, and their textbook was just a glorified Visual Basic tutorial, because at the time, all the companies were looking for Visual Basic programmers.
Now, companies are looking for Java programmers, so the schools have switched over to that. Never mind that programming languages have a long history of turning out to be short-term fads (COBOL and Pascal before Java), and the real skill is in understanding the logic underneath the language.
I don't think syntax is the problem the problem is getting people to understand that programming is about changing what's going on in memory. In math when you solve (X + 7) = 15 the value of X does not change but when you say X = 7 the value of X changes.
IMO, the only thing which would help most into students "get coding" is using an inline debugger to step though their code and understand what's happening. Because people don't get the idea that software is a dynamic thing once you run it.
Well with any language you have to teach a little bit of convention to go along with the rules, and the convention on when to use parens in ruby is mostly standardized from the code I see.
But yeah, I'm sure there has to be a better language for learning out there, I just don't personally know it. I originally learned with C++, and I remember the terror that were pointers at first. When I had a class that taught me Scheme, I remember thinking: "hey, I could write this code on paper without even testing it out if I wanted", which was the polar opposite of my C++ experience.
I agree with you. I started my CompSci degree a few years ago without any programming experience. The first intro-class was quite challenging as I had never programmed before. It took me a while to get used to the quirks but I became better after sufficient practice. Like anything else, programmers only get good after they have put in the hours to learn programming and the programming language. Its like music or sports or even academics. Practice makes perfect.
I think that programming is indeed something that you either get or don't.
I had an interesting expereience a while ago where I helped a friend doing a website. There was a backend involved where he would have to type some numbers into a table (how much of x, y, x... do you need when you are a certain age). I spent hours trying to explain to him why he couldn't just draw a graph on the screen, like he would on a piece of paper, and let the computer find out what the values were. He simply didn't get the basic concepts behind it and thought that the computer should easily be able to see the graph and decide what to do. He thought that is should be just as easy to draw a graph on screen and get the numbers from there as entering numbers manually.
It became apparent that he just didn't think sequentially and logically. Notions like if x is larger than y and y is larger than z then x is larger than z were extremely difficult for him to grasp. He isn't stupid by any means, he simply thinks about the world differently. And he would never get even a simple program to run no matter how much he tried.
> regular variable because Java works by reference, not by copy
I haven't read the other replies, so somebody else may have pointed this out already but Java is a by-copy language, like C and C++. Not by-reference like you claim.
In Java, you can store an object in an array and then modify that object in both the array copy and the one you have in a regular variable because Java works by reference, not by copy.
LOL. In what language does array assignment result in a new copy of that data structure rather than a reference of it?
In Pascal, Ada, PL/1, Perl, and C, array assignment or passing an array as a parameter results in a new copy of the array, at least under some circumstances. (For example, in Pascal, it has to be a value parameter, not a var parameter, and in C, the array has to be inside a struct.) These are not exactly obscure languages, so it's surprising that you assert there are no languages that work that way. Do you know any languages other than Java?
“Every real language has types,” you say. Except for BLISS, BCPL, almost any assembly language, Forth, B, the Bourne shell, dc, QED, TECO, sed, and old versions of Tcl, to name a few. Again, these are not obscure languages; every piece of software you use is inspired by some of them and implemented in part in others. (There are also languages like Python in which there are only dynamic types, but I agree with your point of view that those are still types.)
And that's why I downmodded your comment: not because it was arrogant, but because it was wrong.
I don't mind downmods on political subjects (too much), which are matters of opinion to a degree. But when I correct somebody's laughable mistakes, please either correct me in writing or leave it alone. Thanks.
Java is a whipping boy, and I also have my problems with it, but one of its minor strengths is that it is clean enough for a teaching language (especially for total neophytes). Here is the much lambasted manner of outputting:
System.out.println("Hello world");
...in fact, this is well organized. "System" is a namespace. "out" is a static variable. "println" is a static function. "Hello world" is a String. These things all exist in an orderly world. A professor could explain a lot of key elements of language design with that one line. What's this:
print("Hello world")
...it's shorthand for much the same. Easier? Yep. But it's glossing over a lot of details that students need to know.
So when you come at it from a teaching angle, you're maybe making a mistake. Python/Ruby/LISP all have their WTFs that will throw off students, even if they're all better languages than Java.
Java's a horrible language for teaching. If you think this...
System.out.println("Hello world");
Is easier to understand than this...
print("Hello world")
Then you've forgotten what it's like to be a beginner.
Java's not even a good example of what OO is, and it has way too much syntax and special keywords (something like 50) for teaching.
Python is a far better language for teaching, Smalltalk would be even better because it's much simpler, has only a handful of keywords, and a much more consistent and simpler syntax.
In any case, students should begins with a dynamic language where they don't have to think about manifest types that they aren't ready to understand anyway. It's also much faster working in a workspace or REPL where you have instant feedback and can experiment without messing around with compilers.
I should also point out that your Java example won't even compile, you need to wrap it in a class and a main function to even attempt to compile and run it. Tell me again how simple this is..
class World {
public static void main(String args[]) {
System.out.println("Hello World!");
}
}
Not to mention that you have to save it in a file called World.java and it will compile to World.class. If you change the contents of a file, the first line, you also have to change the name of the file. How does that make sense to a beginner?
I still think Java is just a cruel joke on the part of the authors. I don't think they really thought manifest typing was a good idea. I don't think they really thought that Java's OO system was any good.
I think we will be seeing a paper soon that has a title like, "How bad could a programming language be before people stopped using it? A case study on Java."
I think judging a language by "Hello-world" is a mistake.
Sure, some languages have a fixed overhead for creating a program. Some have needless syntax fluff that doesn't do all that much, but it's actually a good skill IMHO to be able to identify and see through that fluff to the core elements of the code.
When we pick up a book do we judge it based on the index at the back and the preface and the publishing info at the start? We probably just ignore those bits.
I think in these sorts of classes it'd actually be a good idea to spend several weeks looking at other peoples code and analyzing what it does. Being able to read code properly is a really important skill I think people should master before they even start with writing hello-world themselves.
Like I said earlier, you've forgotten what it's like to be a beginner or you've not had much experience with teaching them. Beginners don't need to be able to see through fluff, they can't, the fluff needs to be gone entirely.
They need to be taught with languages that have no fluff so they learn the basics of thinking logically, algorithmically. They aren't ready to deal with the complexities of dealing with a particular languages quirks and learning to please its compiler with voodoo incantations like int, char, string, long, etc. They aren't even ready to understand that there are differences between languages, so their first language needs to be one that teaches concepts that apply to all languages.
They need to learn what functions are, what conditionals are, what loops are, what recursion is, in their simplest forms, and more than anything they need to see immediate success and running programs or they won't maintain interest long enough to get anywhere near the harder optional stuff like types and compiled languages. As soon as types come into play, you've advanced to an intermediate level, way over the head of beginners.
Beginners and manifest/statically typed languages do not mix well. The closest a student should get to Java, is JavaScript, but they'd be much better off learning Python, Scheme, and Smalltalk before getting anywhere near any of C's bastard children.
One of the best skills to learn is to see through fluff and understand what is going on. I'd actually say that the best first language to learn would be assembly language. It's insanely simple, but there's a lot of fluff, so you have to learn how to 'read' code in terms of overall structure/flow instead of focusing on each individual instruction.
I'm still not convinced learning in classes is going to produce anything but mediocre programmers though.
Learning to see through the fluff is not a beginner skill. I'll just stop here and say I think you'd make a poor teacher because you show little if any empathy or awareness of what it means to not know something or how important it is for a beginner to have small successes and working programs right from the start.
I agree I would make a bad teacher for a general class. I think programming skill is largely natural talent and isn't something that can be taught.
I'd also say that the biggest skill anyone can have is the ability to self learn. Being taught the fundamentals of programming in a class doesn't bode well for future hacker ability IMHO.
If someone has a natural talent for it, it can be nurtured, but trying to teach just anyone how to program is the reason we have so many mediocre programmers in the industry. Some people should give up on programming.
Imagine anyone could go to art college, get a job as an artist, and be employed at big industries "blending in" and never really rated on their art work. This is the issue with programming. At the moment, there's this strange belief that anyone can be a great programmer - that it's just typing. Mediocre and bad programmers who may have a piece of paper saying they completed courses, are allowed jobs in industry.
I think programming skill is largely natural talent and isn't something that can be taught.
I disagree, sort of; thinking logically is the natural talent, being good at programming is a mere side effect. People who are inherently bad at associating cause and effect, just aren't going to be good at anything that requires logic and rational thinking.
but trying to teach just anyone how to program is the reason we have so many mediocre programmers in the industry.
No it isn't, people who have no natural talent for programming don't just do it for no reason, they do it because the pay is attractive and this is one of the few fields where one can get a pretty high paying job without any degree at all.
The dot com boom and the absurdly high salaries that were thrown out to anyone that could slap together some HTML is the reason we're currently stuck with so many mediocre programmers. As long as someone can fake it, and land a nice paying job, hordes of mediocre fakers will continue calling themselves programmers.
It's not even that these people can't be taught to program well, they simply have no interest in programming well. They learn just enough to get by, collect a paycheck, and go home. The thing missing isn't ability, it's interest. This isn't something limited to our field either, it happens in any field where $$ is not linked to actual performance or proof of skill; managers are another good example.
I agree - methodical scientific thought processes are the talent. I disagree about degrees though. When someone says they have a degree in computer science, I'd always be very weary.
If you were to commission a portrait of yourself, would you choose an artist based on his previous works, or based on some certificate saying he completed a course on art at some college? I know which I'd base it on.
I wasn't claiming a degree was necessary, or even an indicator of success in programming, merely that it tends to filter out the people who have no interest in the subject. Sadly, many people who are interested are ruined in college by being taught Java.
Past work is always a better indicator than any recommendation, be it on paper or verbal, but past work is proof of skill, which I already mentioned.
I find that the preface of a book is often highly indicative of the content of the book. The preface of a good book will generally talk about a few abstract themes which guide the exposition. The preface of a poor book will be a sort of random collection of notes, ideas, and guidelines. One textbook I looked at (on EE) started with a paragraph that went something like "Scientists understand the world by creating models. A model reflects reality. A model has components, each one of which corresponds to something in the world." The book was, unsurprisingly, no good.
In a similar way, Java's verbosity in even the simplest examples speaks to a certain kind of language design. Java's design is based on indulgence in the idea that difficult things can be made somehow easier or more reliable if the difficulty is hidden by a lot of simple, but needless verbiage.
"I think in these sorts of classes it'd actually be a good idea to spend several weeks looking at other peoples code and analyzing what it does."
I think that would just result in a lot of students dropping out. As a beginner, it's nice to get the computer to actually do something - even if it's just printing out a stupid message.
If I was setting up a curricula, each incoming student would deal with a digital logic trainer. Okay? Wires and transistors. An 18 year old should learn the fundamentals and not the shortcuts. That's my opinion--maybe I'm wrong. Java is hardly the best teaching language, but it is closer to the bone than a lot of things....
The problem is that you're confusing a concept with its implementation. If it is a basic programming class, there are a whole lot of concepts that should be learned before worrying about the implementation.
Algorithms, variables, program flow, functions. Those are the real fundamentals... things that can even be analyzed in pseudo-code, no need to get into a particular language's idiosyncrasies.
<pedant mode>
java.lang.System is class, not a namespace (although classes in Java are overloaded to function as namespaces as well as modules and data type definitions). println() is not a static method, but an instance method of the java.io.PrintStream class. out is a static variable in the System class of type PrintStream which refers to an instance of that class, on which we invoke the method println().
</pedant mode>
...which is a lot to demand of a beginner to understand in his very first program.
I'm self-taught myself, and for me, having a humanities background, C/assembly and Scheme was a perfect combination for understanding both how computers actually work and what computation is all about (to the extent that I understand either!).
I think Java is a nice language in many ways, but I think its dominant position as a teaching language is due to market demand more than any inherent suitability for that role.
>glossing over a lot of details that students need to know.
If you're teaching them object oriented programming. Why would you be teaching beginners object oriented programming?
I give the engineering programming classes at Pitt a fair amount of credit. Two semesters -- the first semester covers HTML as a reasonably useful introduction to the idea of structured text files, then Matlab to introduce if statements, loops, and functions in an environment with a friendly console. The second semester was C. Mostly everyone got it -- those that failed out of engineering didn't fail because of programming class.
The classes were taught/conceived by a professor whose primary research interest is engineering education.
There are lots of little pitfalls in programming that are just terrible. In C, you can just walk off the end of an array (or the beginning). In Java, you can store an object in an array and then modify that object in both the array copy and the one you have in a regular variable because Java works by reference, not by copy. A lot of the time, you just need someone who is a lot more learned in programming to notice that. It's not that you don't get a concept like object references, it's that if it's not in your mind, you don't notice when your code does it and it takes a long time for these things to really get into your mind to the point that you catch them fast.
And most people give up. You get hit enough times with silly things like these and you just want out unless you're truly dedicated. I know when I was learning, I hit all the trap doors. It's why I noticed them when other students made them. Heck, back in the old days of Java, you could easily screw up things like int vs. Integer and not notice it - especially since a lot of professors might not make a distinction because for veteran programmers, we know that pitfall, but also because its place is at the start where students get inundated with syntax and such a distinction might go unnoticed (or abbreviated as int in notes).
I would think schools should hire more TAs to help students through those pitfalls except that most students like to do assignments at the last minute where these errors become the source of the mind-breaking stress.