
Don't Distract New Programmers with OOP - ColinWright
http://prog21.dadgum.com/93.html?HN2
======
bane
IMHO, the thing that new programmers _really_ struggle with is learning how to
break a problem down into the steps their language allows them to express.
Lots of people have never had to logically think out and algorithm to do
simple things and it takes them lots of practice to understand how to do that.

For example, suppose I'm a new programmer given the notional task of making a
program to make me a sandwich, can I just:

    
    
      makeSandwich(); 
    

and be done with it?

Or do I need to break it down to the n-th degree?

    
    
      //make bread
      bread=harvestwheat();
      bread=millwheat();
      bread=bread+water;
      //and so on
    

is that the right way to even make bread? Or do I already have bread I can
work with someplace?

Do I?

    
    
      Sandwich=bread+jam+butter+bread;
    

Or

    
    
      Sandwich=Sandwich.add(bread).add(jam).add(butter).add(bread);
    

Or do I need to do something else? Maybe this particular programming
environment doesn't need me to make bread, but I have to transform a milk
object into butter for some reason that seems entirely random to the new
programmer. Who knows? Lots of the things that we take for granted seem
entirely arbitrary to the new programmer and learning to break a problem down
in a way that maps to the environment is a _very_ hard problem to learn to
solve repeatedly.

 _edit_ in a way this is a common topic even on HN with the "do x in n number
of line" posts that are common.

~~~
spion
Here is a methodology that I recently started using:

Describe, at high level, what needs to be done to make a sandwitch, in your
head. Then write code that looks exactly like what you said in your head, as
much as possible. Dont worry if it turns out to be impossible to implement
that way - you can always tweak it later until it becomes possible. Just try
to make sure it reads more or less clearly.

Repeat with each of the steps, checking whether there already is a library
that does that for you.

    
    
      function makeSandwich() {
        var breadSlices = getBreadSlices(2);
        var ham = getHam();
        var butter = getButter();
        var butteredSlice = spread(breadSlices.first(), butter);
        return foodPile(butteredSlice, ham, 
                        cheese, breadSlices.last());
      }
    

Continue the same way with getBreadSlices, getHam, getButter, pile.

As you progress this way, you'll notice that you'll be able to implement some
processes in terms of more generic functions (e.g. spread and foodPile).

You'll also notice that you need an environment (macro, such as kitchen, or
micro, such as frying pan) to temporarily place stuff that you're working
with, while you wait for some process to complete. Thats when you start
creating classes and objects that represent this environment.

Real code example:

[https://github.com/jlipps/async-
showcase/tree/master/promise...](https://github.com/jlipps/async-
showcase/tree/master/promises-bluebird-topdown)

~~~
tseabrooks
I know it's a bit silly but the thing that jumped out about your comment and
the parent comment is the butter. You butter a hame and cheese sandwich? Is
this a cultural thing I'm not familiar with? _zooms off to google to check_

~~~
CalRobert
I moved from the US to Ireland a year ago, and while I love it here the
constant vigilance against sandwiches slathered in mayonnaise and butter can
be exhausting. I go to the sandwich shop and they helpfully ask "Butter or
mayo?" \- to which I respond "mustard", and immediately reveal myself as an
outsider.

I thought garlic fries, like the sort at Giants games, were delicious! Some
garlic, olive oil, parmesan, etc. I was shocked to discover that here and in
the UK garlic chips consist of chips (fries) with garlic-accented mayonnaise
spread all over them.

And don't call it Aoli. That's just dressing up a disgusting condiment with a
fancy word.

~~~
dkersten
I'm not an outsider, yet I always answer "no thanks".

I use butter and mayo for one of two things: flavour (eg I love kerry gold on
toast ;-) often nothing else) or moisture - but if I don't need the moisture,
usually because I've got tomato, peppers, coleslaw, relish or something else
providing that, I will leave butter and mayo out. Unless I want them for the
flavour. (As an side, I don't understand why people would ever want butter on
a _breakfast roll_ )

~~~
stan_rogers
_"... usually because I've got tomato, peppers, coleslaw, relish or something
else providing that..."_

These are precisely the instances in which I would want something oily
(butter, marg or mayo) as waterproofing for the bread. (Mustard also works, if
it's appropriate for the sandwich.) "Everyone has the gout," as they (don't
actually) say in French.

------
pixelmonkey
In Python, OOP boils down to a style choice, which is exactly as it should be,
IMO, and is very helpful to beginners.

In Java, you're forced to use OOP for every problem. No beginner understands
why to define "hello, world", you also need a class, and a 'static' method on
that class, and to invoke a weird-looking special class called "System".

It isn't obvious why there are "String[]" types and "ArrayList" types, and why
I should care about the difference. Why does "main()" take "String[]" yet I am
encouraged to use "ArrayList" in my code? This is just a sampling of
difficult-to-answer questions that a beginner encounters in using Java that
don't have a grounding in computer science, but just in Java.

It just so happens that among design choices, the choice to implement your
Python code using OOP is a trade-off. It always is, but Python makes the
trade-off clear as day. The win is increased ability to implement interfaces,
language protocols, inheritance, polymorphism, the ability to bundle state and
behavior, and the ability to bundle related behavior together. The loss is
reduced readability and reduced beauty. Since these latter things are counter
to The Zen of Python (PEP 20), idiomatic Python programmers will tend to
torture themselves over OOP usage, to the point where only data structures
that truly demand OOP's features come into existence.

This means that beginners will more often see a useful_function than a
UsefulClass in Python's stdlib and associated ecosystem, and this is A Good
Thing, since functions are much more composable than classes are (not to
mention simpler).

I think Python will therefore also teach beginners vigilance in the use of
classes, which the entire software community could use a little more of!

~~~
bad_user
You're saying that in Java you're forced to use OOP for every problem and then
you exemplify with "hello world". Well ...

1\. function definitions being constrained to classes has nothing to do with
OOP

2\. static functions or members have absolutely nothing to do with OOP

I see a lot of criticism of OOP, but when I get to reading the details, it's
all about Java's flavor of OOP.

~~~
possibilistic
I think you missed OP's point. Beginner programmers introduced to Java are
forced to grapple with OO from the outset.

What is a class or static method? These are OO constructs and require
additional mental overhead when learning.

~~~
bad_user
And you missed my point. Static methods are not an OOP construct, unless we
would be talking about class methods on classes that are objects themselves,
but in Java we don't.

~~~
saraid216
The problem with Java has always been that it assumes the programmer is
incompetent and requires an OO straitjacket around their code in order to
produce "robustness".

You're right: static methods are not an OOP construct. They're a hack to allow
the user to _break out_ of the straitjacket at a specific moment, because it's
impossible to write anything but a library otherwise.

The issue, thus, is that Java requires a beginner to learn a paradigm-breaking
manuever as a basic operation. "Java is a glorious OOP language. If you want
to write anything that's pure Java, though, here's how you stop being OOP in
order to do so."

(Also, for the record: I _like_ OOP. I like Ruby specifically because it makes
OOP so natural and honest.)

~~~
jafaku
Static methods are not a hack, they are methods that don't depend on a state.

I like how Rubyists/Pythonists jump to criticize Java, but they don't know the
first thing about OOP.

I don't even use Java but these critiques are retarded, seriously.

~~~
bad_user
By "methods that don't depend on a state" I guess you mean methods for which
"this" is not passed implicitly.

Technically, such methods are not methods. They are functions. And the
distinction between a "static method" and a function is completely arbitrary,
dictated by a completely arbitrary limitation of how bytecode is organized on
top of the JVM (e.g. class-files instead of package files) and by somebody's
flawed vision that all function declarations should happen inside a class,
even if those functions are not methods.

And actually, what I've said in my first sentence is wrong. "this" may not be
passed to static methods, as classes are not objects, however classes are some
sort of pseudo-objects that are special for the JVM and "this" does exist in
certain contexts, like when declaring a "static synchronized" method, which
does use this pseudo-object for acquiring an intrinsic lock. Also this pseudo-
object does have a constructor.

So you see, classes play the role of packages for static members and methods,
except that in a language like Python, packages are objects themselves,
whereas in Java they aren't. Plus, if you look at classes with static members
as being packages, they are retarded packages, because you can't pass them
around as values, you can't override imports and so on.

I can keep going btw.

~~~
jafaku
By "methods that don't depend on a state" I mean that you don't need an
object. The point of objects is that they manage their own state, and you only
need to worry about sending them messages.

I agree that they are just functions, but no one is trying to "hack" or to
break encapsulation. They could have used packages instead, yes... But having
them inside classes is pretty convenient as this allows us to have a better
syntax.

Oh and not being able to pass classes around is a language-specific thing, so
you can't really use that as an argument against static methods.

------
VLM
In a world of circular time, not linear time, all syntactic sugar, or all fads
in general, naturally rotate endlessly thru:

"You'd be crazy to use that"

"Um, OK"

"Often, I use it"

"Everyone must be forced to exclusively use it"

"Sometimes its sucks, but its the only sane thing to do"

And then right back to start. Endlessly. Forever.

So in 2014 OO is rapidly nearing the "you're nuts" and I see functional is
rapidly nearing the "I use it" with, inevitably, "Everyone must be forced to
exclusively use it" coming up soon. The relevant point is, have we started
preparing for functional fundamentalism or whatever you want to call it? Also
have we started scrubbing our resumes and githubs to remove the stain of OO
programming?

~~~
bad_user
Personally I like OOP and I think a lot of its criticism is flawed, since the
OOP flavor that most people are exposed to nowadays is Java's OOP. And
personally, whenever I see class names suffixed with "Executor", "Manager", or
anything really that ends with "er" and "or", I feel like puking.

Besides, the state in which we are in is rather healthy. Back in the late
nineties, early 2000, everybody was into class-based designs described with
UML.

And I do wish people were forced to use functional programming, because that's
the only way many people end up learning something new. OOP is not the best
choice for every problem. Sometimes a function is better than an
ExecutorManager. Sometimes a Map or a type-class are better than an
inheritance chain. Sometimes a monad is better for manipulating data streams
instead of iterators. And so on and so forth.

Also, the Gang of Four is seriously outdated.

~~~
pjmlp
> Besides, the state in which we are in is rather healthy. Back in the late
> nineties, early 2000, everybody was into class-based designs described with
> UML.

UML is great as collaboration mechanism at the enterprise level across sites.

> Also, the Gang of Four is seriously outdated.

Still largely unknown on the enterprise, sadly.

~~~
bad_user
Ah, the mythical enterprise. I've yet to see an example in which UML Class
Diagrams have been useful, but whatever, I guess that's the same enterprise in
which you've got "architects" outlining stuff in UML, then passing that to the
monkeys to fill in the blanks.

~~~
demallien
I find UML Class diagrams useful for a one-look document describing the
overall architecture of a piece of software. Where they are weak is that you
really do need a couple of paragraphs of plain English describing each class
as well, and there's not really anywhere to put that on a UML Class diagram.
The other really useful diagram in UML is the sequence diagram. If you write
out the Sequence diagrams for a few key processes in your software, you've
gone along way towards giving a roadmap to people that need to get in and
modify the code. These are both documentation use-cases though. Using UML as a
design tool (other than very informally on a whiteboard) seems wrong to me.

------
thomasz
I think beginners should be confronted with OOP very early, but not in the
typical way:

\- DO teach encapsulation of state.

\- DO NEVER ever try to teach about objects as representations of real-world
things. And for the love of god, do not give out modelling assignments where
"Human inherits mammal" is an answer.

\- DO start with collections: Vector, List, Stack etc. are easy to implement
and showcase the virtues of encapsulating.

\- DO teach polymorphism, but only in terms of interface inheritance. The
collections you have taught before are a good starting point: ICollection,
IRandomAccessable etc.

\- DO NEVER EVER talk about class inheritance. Do not even use the word
inheritance. Call it "is a relation" or something like that.

\- When the time comes to teach inheritance, emphasize the Liskov substitution
principle.

~~~
dhimes
_\- DO NEVER ever try to teach about objects as representations of real-world
things. And for the love of god, do not give out modelling assignments where
"Human inherits mammal" is an answer_

I have to disagree with this. I think this is exactly how to think about this.

I once explained the shift to OO to an older gent who was familiar, not just
with ancient scientific programming, but also with building a house. I told
him that the idea was that code was so large and complicated that it was
divided up among teams with each team getting specific parameters that their
code had to fit. He said, well of course.

Then I said it was much like constructing a house. You had to put the frame
up, and know where the windows and doors would be, but the details of the
windows and doors could be decided later. Every door had to be able to respond
to an "open" command and a "close" command, some may have a "lock" command,
and so on, but the builder of the door worried about getting that stuff right.
All you had to specify were the dimensions and the direction of the door.

Now this was a pretty technical person- and perhaps doesn't qualify as a
beginner, but I find, in general, real world metaphors to be powerful for
teaching.

~~~
oneeyedpigeon
"I told him that the idea was that code was so large and complicated that it
was divided up among teams with each team getting specific parameters that
their code had to fit."

IMO, this is the first mistake. Code should _not_ be large and complicated;
when it is, few things can save you, whether it be the language or paradigm
you're programming in, or the structure of the team doing the programming. OOP
is a solution to the wrong problem.

~~~
dhimes
But how do you avoid it in today's world? How do you actually build an app
without a large code base?

~~~
oneeyedpigeon
What is it about "today's world" that makes software require a larger code
base? If anything, we have much higher-level languages which require far less
code than in the olden days. Anyway, my point was more about the unix nature
of building small programs, that do one thing well, and using those progams in
combination.

~~~
betterunix
"What is it about "today's world" that makes software require a larger code
base?"

The fact that we are still not using the high-level languages we have
available to us. Vast amounts of new C, C++, and Java code are written each
year. We are solving bigger problems, but we are using languages that are
still catching up to the state-of-the-art of the 1970s.

------
skrebbel
Unlike many HN'ers, I'm a big fan of OOP (yes, even in the Java sense). Still,
I think the author is absolutely right.

OOP is useful because it helps tackling some common _non-functional_ concerns,
mostly modularity and as a result extensibility, reusability and, to some
extent, maintainability. These are architecture concerns. They're vital to
take into account when you're writing any piece of non-trivially large
software (and OOP is one, though not the only one, good approach to deal with
them). They're entirely unimportant in small little programs, which includes
nearly anything a beginning programmer makes when learning.

This also means that languages that religiously enforce OOP, like Java and C#,
might not be the best starting points indeed.

~~~
marcosdumay
This may be the wrong timming, but I'll dare say it anyway: OOP (and OOP-like
namespaces) is the best known approach for creating modularity. Other
approaches are so far behind that they are not even in the same game.

Yet, there is an entire generation of programmers that learned OOP at school,
and are hitting that hammer on everything, hoping for it to be a nail. That's
all that's wrong with OOP: it does not solve all the problems in the world.

~~~
weavejester
I definitely agree that namespaces are a good idea, but if by modularity you
mean isolating pieces of functionality, I'd suggest OOP is one of the worst
approaches to take, because it results in a lot of implicit connections. Only
global state is worse.

~~~
vdaniuk
So is OOP is one of the best or one of the worst approaches to modularity?

~~~
weavejester
One of the worst, I think, because it encourages developers to make
connections, rather than enforce isolation.

------
mikro2nd
With respect my experience is the diameteric opposite. One of the most
talented and brilliant programmers I know learned object-thinking first,
starting at about age 10 or 11. Spent the first several years doing stuff like

    
    
        window.open();
        Line aLine = new Line(...);
        window.add( aLine );
    

I will never forget the day he came to me - after about 3 years programming in
Java to ask, "Where are the methods for ints documented?" and I and we had to
have a Birds and Bees conversation to the effect that not /everything/ was an
object. He vanished for several days after that conversation to process this
oddity. I began to wish we'd chosen Smalltalk rather than Java. (Actually I
still wish that as a matter of general principle.)

No. I believe that we simply approach the problem wrongly. I think that
objects are (and were deliberately intended to be) closer to the way we
naturally think about the world. It's the baroque mental twists and turns we
have to learn to make on procedural programming that are the problem. If you
don't learn that odd way of thinking first, you're just fine with learning OO
first - streets ahead, in fact.

~~~
ufo
TBH, your example is not too different from

    
    
       openwindow(window);
       Line aLine = make_line();
       addwindowtoline(aLine);
    

A small pet peeve of mine is people insisting that encapsulation and
abstraction are exclusive to object orientation even though abstract data
types are also a core concept in prodecural or functional programming.

To make your example "trully OO" you would need to be using dynamic
dispatching and polymorphism in those method calls. But are we really going to
need multiple Window and Line classes and even if we do, is this really going
to be the best way to architecture our code?

~~~
userbinator
To take that example even further down the "procedural with OO-ish
conventions":

    
    
      Window_open(window);
      Line aLine;
      Line_make(aLine);
      Window_add(window, aLine);

------
munchor
Another reason I approve of Python has a first language is Turtle[1]. It
allows new programmers to approach problems in a modular way, i. e., if they
have to draw a pyramid, they'll easily learn why a draw_square() function is
important. You can extend this way of thinking to many other exercises using
Turtle.

Additionally, it makes students have fun programming, since it gives them some
graphical power and making a computer draw things is much more exciting than
making a computer print things on a terminal (especially for newcomers). Plus,
even though it's very simple, you can write some very interesting stuff with
Turtle[2].

[1]:
[http://docs.python.org/3.0/library/turtle.html](http://docs.python.org/3.0/library/turtle.html)

[2]:
[https://github.com/FranciscoMSM/IPRP/blob/master/4linha.py](https://github.com/FranciscoMSM/IPRP/blob/master/4linha.py)

~~~
analog31
Thanks for those links! Regarding making programming fun, I've observed that
certain kids (well OK, my kids) get a kick out of programming that interacts
with the physical world.

Kids seem to prefer writing programs that "do" something, where their
definition of "do" might be different than ours.

------
Bahamut
This is a good article I think. I've helped mentor a couple of people learning
programming and helped get them to understand the web development environment.

One person we started out with some Java since he was taking a Java class, and
then I quickly found that he was very confused with Java. I shifted gears and
had him start Python from scratch. His understanding skyrocketed, since he was
getting to understand how control structures worked, defining functions, and
using them.

There is something to be said about the importance of understanding a compiled
language though. While it depends on the individual, I think most people would
benefit from learning with a language like Python first since some of the most
basic concepts of programming become more accessible.

------
yconst
"The shift from procedural to OO brings with it a shift from thinking about
problems and solutions to thinking about architecture."

Interesting thinking, never thought of it this way.

~~~
userbinator
If you view OO as a set of organisational facilities above procedural code,
then it makes a lot of sense.

------
brudgers
Python might be the best programming language for an introductory pedagogy.
But it is hard for me to take seriously assertions of that which are not
backed with a comparison to the languages created by the PLT group and their
research.

To put this in perspective, the PLT group of languages starts off eschewing
not only OOP but mutation as well. Even more relevant, these are not options
in the introductory languages.

This means the practice of not using OOP (or mutation) does not rely on the
beginner practicing a type of discipline that even seasoned professionals
might struggle for, i.e. a large class of kludgey habits _cannot_ be developed
when the PLT languages are used. A side effect of the PLT sequence is that it
suggests the idea that switching languages isn't a big deal - rather useful
since different languages are suited to different problems.

------
macspoofing
Programming is hard. There's no magic bullet. OOP is fine. Functional is fine.
Procedural is fine. Every generation of programmers started with something
different than the previous and turns out fine.

At the end of the day, every abstraction leaks so the student has to have a
good working mental model of computing. And your first programming langauge
does not dictate your career. You're expected to keep yourself up to date and
have continue honing your craft.

------
lettergram
I agree with the author for the most part, however here is my experience:

I have taught three people how to program (not a large sample size I know...)
each one I have chosen a different approach. It honestly depends more on the
individual than the language.

Individual 1: They were interested in history, video games, politics and
desired to learn programming. For him, he seemed more interested in the
history of programming, so I chose to help him learn BASIC as his first
language simply because of the history associated with it (I could have chose
FORTRAN or COBOL). He enjoyed it more because he could connect, he thrived off
imagining the other early programmers writing in BASIC. Further, he felt as if
he was building and learning in a similar fashion to most programmers and that
made him want to learn more languages advancing in a similar fashion.

Individual 2: For her, NetLogo was the simple choice. She understood nothing
of programming and honestly did not want to at the time, but knew she needed
programming knowledge to help her obtain a job in biology in the future.
NetLogo offered a way to both teach her the basics of programming (objects,
loops, etc.) while being pretty fun, we made an eco-system. This actually
excited her about programming to the extent that she is now learning python
and joined ACM.

Individual 3: For him Ruby was probably the best introduction to programming,
he was interested in learning how to develop website applications. Due to the
fact he had no programming experience and was interested in web applications
it seemed clear (to me) that Ruby was going to be the easiest way for him to
learn to program. He loved it, and has since moved on to learning C, since it
turns out he loved the control programming offers him.

The point, is that each programming language has a community/documentation and
specific uses, it depends on personality and what ones goals are when
determining what language to learn first. Since I have always been interested
in both improving myself and others I have read a few books on the subject, my
favorite is The Talent Code [1]. The book explains that each person has a
different personality/experiences and in turn "learn best" in different ways,
which is essentially what I employed here (without explicitly meaning to).

I agree with the author that Python (in many cases) is the best language to
have a want-to-be programmer learn. It offers simplicity, logic, standard
libraries, community, and tutorials in abundance, however it may not excite a
person or have applications in what a persons interests are (which can reduce
enthusiasm and in turn learning).

[1] [http://thetalentcode.com/](http://thetalentcode.com/)

~~~
andyidsinga
re: "early programmers writing in BASIC"

thanks. I feel oooold :)

~~~
lettergram
Hahaha I started with BASIC myself and I'm only 22, so...

------
userbinator
Python advocacy aside, I agree that OOP is best taught when it "comes
naturally" and NOT the first thing programmers should be learning. That is,
the ideal sequence of concepts I think would be (along with a possibly
contrived but relevant example):

1\. Very basic, sequential computation. Add two numbers. 2\. Conditional
computation. Find the absolute value of two numbers. 3\. Computations over
homogenous data: Arrays and loops. Find the average of the absolute value of a
set of numbers. 4\. Computations over inhomogenous data: Structures. Find the
area of a set of rectangles. 5\. Computations over "even more inhomogenous"
data: Objects. Find the area of a set of shapes of different types, and find
the centroid of them.

That's where you ask "how would you do this with what you've learned so far",
and the learners should start to build different structures with a lot of
similar aspects and duplication of code (I realize I didn't explicitly talk
about the value of functions/procedures above, I guess it'd go somewhere after
3), and then you show them how much more straightforward it is to do with OOP.
Now they know the value of OOP and what "doing it without" would entail, and
you end up with a bunch of more knowledgeable programmers who won't needlessly
create baroque class hierarchies and write more code than they need to, but
will use those abstractions when they have value. There is a huge difference
IMHO between e.g. being taught dogmatically "you MUST use functions because
abstraction is good" like it is something you should take at face value, and
being taught by being given a problem in which you do not know about functions
at this point and thus write lots of duplicated code and then being shown the
value of eliminating that duplication via functions.

I've seen way too many learners create half a dozen classes with a ton of
methods in them when given a problem that could be solved in a single function
of a few lines, then have trouble figuring out what to put in the method
bodies... it's completely backwards! No matter how much "architecture" you
manage to create with deeply nested objects, in the end all the functionality
of your code is essentially based on a series of statements executed in
sequence, much like they would be in a purely procedural language. The fact
that many otherwise highly-regarded educational institutions are churning out
programmers who can create dozens of classes with dozens of methods in them,
and then not know what goes in those methods, i.e. the actual "meat" of the
computation, is something I find highly disturbing.

~~~
betterunix
Why start with computation as a sequence of operations? It might be equally
useful (maybe even _more_ useful for some students) to start with computation
as a series of reductions e.g. with combinator logic.

~~~
userbinator
Because that's how a computer actually works, and the sequential execution
concept is something that is intuitive to anyone who has followed a schedule,
a recipe, been taught how to tie their shoelaces, ... , in essence, done any
sort of living.

~~~
betterunix
"Because that's how a computer actually works"

So what? That is kind of like saying that people need to understand how an
airplane works in order to ship a package overnight. Sure there is value in
understanding how a computer works, and that will probably be taught later in
the curriculum; but teaching students how to think abstractly is far more
valuable.

"the sequential execution concept is something that is intuitive"

So is the concept of reducing one expression to another; we teach algebra as
exactly that long before we teach anyone how to program.

~~~
Goladus
Sequential instruction is learned before expression reduction in real life...

 _So what? That is kind of like saying that people need to understand how an
airplane works in order to ship a package overnight._

But people DO need to understand a bit about the process of shipping a
package, if they want to estimate when it will arrive, or if they want to be
able to read the online tracker, or even know that they must bring the package
to a particular place before fedex will ship it. Or if the package does not
arrive, what would you have to do to find it?

Generally speaking, understanding how a computer works is important to
programming because the essence of programming is mapping a real problem onto
the available computational hardware.

Not that I want to argue against learning about expression reduction, I would
agree that should be done sooner than later, but it's not an argument against
learning sequential algorithms.

------
vinceguidry
I don't understand why inheritance is always taught before composition. I
almost never reach for inheritance these days, composition winds up more
accurately modeling the domain. I'll define a bunch of classes modeling the
actual behavior of domain objects, then get some code working using those
classes. Then I'll start cleaning up, figuring out what goes together and
creating composed classes out of the individual pieces of behavior. As I'm
doing this, a lot of times I'll pull out functionality in one class and put it
where it seems to belong.

------
analog31
I keep my eye on which programming languages and techniques are recommended
for kids (plus kids-of-all-ages such as hobbyists, scientists, etc.).

Then I use those languages myself. ;-)

------
Choronzon
Im not a computer science major and got functional programming naturally but
when I first encountered OOP i found it immensely confusing.I couldn't
understand WHY you would want to do any of this, thinking about manipulating
data was natural to me,but mapping classes onto so called 'real world ' ideas
seemed like an immensely leaky abstraction. I eventually got a mental map that
while functional programming resembled maths OOP resembled biology,considering
an object as cell which can be a compartmentalised abstraction which could
could change state and provide an interface.Probably not the most useful
mental model for everybody but it helped me.

What i learnt was: Forget about all this dog inherits from Mammal bullshit(it
doesn't work that way,its just wrong!). OOP is good for a few things. 1\.
Sharing state between a collection of functions(call them methods if you want
to use two names for the same thing). 2\. Code reuse (inheritance)

Im rather amused that test driven development forces you to simplify OOP as
much as is humanly possible,thereby going against the advantages of a shared
state,which is one of the reasons you would use an object in the first place.

------
_sh
Python, seriously? How do you explain to 5-year-olds what the following line
does?

    
    
      if __name__ == "__main__":
    

Python is there for when you move beyond beginner and you start to need
libraries.

For everyone else, there's javascript: open up your browser console and you
have a full IDE with breakpoints and inspection, and an interactive REPL.
Object orientation is there if you want it, but what 5-year-old does?
Functional paradigms are there when you're ready for them (map and foreach on
arrays, for example). A smooth learning curve that gives you power when you
reach for it, and a fast, flexible GUI environment. Free source code to study
comes with every web site.

Best of all, its flexibility fosters many differing programming styles:
consider jQuery and Angular. Very few programming ecosystems could give rise
to such unique styles. I _wish_ my first programming language was javascript,
instead of C64 BASIC, with its 38911 basic bytes free.

~~~
pessimizer
Javascript is absurdly complex, awkward, dishonest (in trying to appear to be
OOP), and often a completely unintelligible mass of callbacks. I not only
don't want beginner programmers to learn in javascript, I don't even want them
to see js until they have experience in another functional language (although
that ship has sailed.)

If you honestly think

    
    
      if __name__ == "__main__":
    

is more complicated than js variable scoping rules and closures, I'm intrigued
by your mind.

~~~
Bahamut
JS, as with all languages, has its flaws, but I found JS the most accessible
language for me. It solved the problems I was interested in, and so putting up
with its issues was fine for me.

------
TazeTSchnitzel
I disagree. OOP is not a difficult concept and not hard to teach. For an
example of what happens when "OOP must not be taught to beginners", see PHP.

~~~
TillE
OOP "for beginners" always seems to be taught as some godawful real world
analogy.

It's probably easier to talk about it if you've done a little imperative
programming and can grasp OOP as a solution to actual problems, rather than
just some abstract nonsense.

~~~
gavinpc
> some godawful real world analogy.

Yes, I think this is a real distraction. This Cat/Dog/Animal trope leads to
the view that you should use classes to model your _domain_ objects. In some
cases, you should. But this can cause as many problems as it solves, and
should not (IMO) be the default approach.

In getting away from this view, I've found it helpful to think of most
programming as designing DSL's. To that end, you can use OO to build the
infrastructure necessary to support this. But I worked in OO languages for
many years before grokking that.

------
Tycho
OOP is a bundle of concepts and I find it hard to reconcile them all and
explain them to people. Individual principles like information hiding,
classes, those are good to teach but the monolithic 'OOP' is tough going for
beginners. And non-beginners.

------
PhineasRex
My main problem with OOP is that objects don't bound complexity.

If I call a function with some arguments, that function is composed of smaller
functions which can only ever operate on the arguments I passed the parent
function. As I follow the function down to primitives, each piece of code is
operating on less data.

If I call a method, that method can operate on its arguments, properties of
the object, and properties of the superclass. I often find myself ping-ponging
around the code base as a class' method relies on a method of an abstract
superclass which itself relies on methods of the original class, each step
introducing more properties into the calculation, many of which are objects
themselves!

------
shittyanalogy
There is no right or wrong way to teach programming. You should just do
whatever you can to keep whoever you're teaching motivated.

When you teach it's not about you or what you think would have been best for
you, it's about understanding other people's needs.

If you think bring up OOP should wait for some time in the future then wait to
bring up OOP. If you think that OOP should be the basis from which programming
is taught, then start with OOP. Just be a good teacher and keep them
motivated. The whole goal is to get them past it all anyway.

Also, programming IS messy. Extremely messy, and teaching people as though
it's gonna be all greased tracks the whole way isn't doing them any service.

------
hazz
In the same vein (linked at the bottom of the article):
[http://prog21.dadgum.com/156.html](http://prog21.dadgum.com/156.html)

------
laureny
These days, I think Javascript is a superior beginner language:

\- Nothing to install, you most likely already have a full blown development
environment installed (e.g. Chrome or Firefox).

\- The language is straightforward, functions everywhere, easy control
structures, very little to be distracted by.

\- The reward loop is very high for beginners: load a page, tell them to write
a Javascript one-liner and see their face light up when the HTML page gets
instantly modified

~~~
MichaelGG
Odd scoping, equality, type coercion - those seem rather significant
distractions. Having to explain that == doesn't really work and === is
probably what they want seems beyond bizarre. And "function" as a way to
introduce an anonymous function is just verbosity for verbosity's sake.

Unfortunately, the two other points you mention probably outweigh the actual
language design.

------
pgbovine
yep there was an epic debate about "objects-first" vs. "objects-late" CS1
curricula last decade. the objects-first folks seemed to have lost, though.
here's a paper:

[http://homes.cs.washington.edu/~reges/sigcse/basics.pdf](http://homes.cs.washington.edu/~reges/sigcse/basics.pdf)

------
jrmenon
From the article:

"The shift from procedural to OO brings with it a shift from thinking about
problems and solutions to thinking about architecture"

Couldn't agree more... I have been doing OOP for a while in various prog.
languages, and I had come to similar conclusions...It doesn't really help you
focus on core ways to solve problems: focusing on algorithms.

Another read I would recommend is from the author of C++/STL:

[http://www.stlport.org/resources/StepanovUSA.html](http://www.stlport.org/resources/StepanovUSA.html)

See the answer to the question:

"I think STL and Generic Programming mark a definite departure from the common
C++ programming style, which I find is almost completely derived from
SmallTalk. Do you agree? "

Note: not trying to endorse C++ templates here either...have my own gripes
here but it did bring the attention back on algorithms and data structures.

------
danso
After my brief time in Java, I instinctively agree with the OP...but I wonder
if there's a happy middle ground here, such as just using the out-of-the-box
parts of OOP?

The easiest example I can think of is: using Ruby without getting into how to
define/redefine classes or methods. Just stick to instantiating simple data
types and invoking their methods:

    
    
         my_string = "Hello world"
         puts my_string.upcase
         # => "HELLO WORLD"
         puts my_string
         # => "Hello world"
    

Among the first roadblocks beginners seem to have is grokking that `my_string`
isn't modified...but isn't that an early point of confusion for functional
programming too, to some degree?

------
pointernil
I believe, if you want to teach programming as a commercial (9-5) profession
it is easier get the ideas of imperative programming (OOP or not) across and
it will bring more benefits to the "pupil" ;)

... and teach declarative programming (Functional or not) to the pupils
interested in the background of computer science and targeting some
innovation/invention trajectory in their "career".

In other words (and _very_ exaggerating):

imperative programming : translating more easily "real world" into code

declarative programming : translating more easily "platonic world" into code

ps: no, i don't believe this to be absolute truth, yes it is quite a hyperbole
;)

~~~
marcosdumay
> and teach declarative programming (Functional or not) to the pupils
> interested in the background of computer science and targeting some
> innovation/invention trajectory in their "career".

Ok, but only after you teach them imperative programming. That's because it's
also easier for them to learn the imperative paradigm, and you want to
minimize the amount of "pollution" they have to learn alongside with "what is
a computer and what it does".

That's also why avoiding OOP at this stage is a great advice. Architecture is
"pollution" too.

~~~
pointernil
Yup, I too believe that agent-based imperative thinking is very deeply
anchored in us and for sure helps a lot to explain a computer at conceptual
level

agent: computer

imperative commands: instructions you give it

... but later on once the understanding of the machine/tool is established i
see how much more powerful the declarative resp. transformational "paradigm"
gets for "computers" applied to the "platonic world"

I believe that the transition towards the declarative paradigm and
understanding of it is essential to grasp the idea of how "computers" and
computation differs from other physical machines mankind invented.

------
andyidsinga
re: \--- When you're trying to help someone learn how to go from a problem
statement to working code, the last thing you want is to get them sidetracked
by faux-engineering busywork. \---

I like this for new programmers as they are often trying to solve a problem or
make a game. My step son made a nice chunk of change by building a website for
someone -- the last thing I would have tried to teach him was oop!

OTOH - there is a point where learning OOP and forms of modularization are a
good idea to expand one's knowledge of the art - just like everyone should
read tcp/ip illustrated and hackers and painters (#pandering on the later)

------
blueatlas
Would understanding structures be useful before trying to learn classes in any
OOP language? If you understand how structures are stored in memory, would
that provide the foundation for understanding class instantiation? I feel the
answer is yes, and the optimal language before OOP is C. Other aspects of C
that help prepare for OOP - pointers: how they are stored and referenced,
pointers to functions (so you will understand object references), native data
types and the memory that they consume. A foundation in these aspects prepare
one for any OO language.

~~~
userbinator
Definitely. Structures are data grouped together, classes are that plus you
can define functions to implicitly operate on their contents (also known as
methods), extend them, etc. Then it becomes even easier to move onto C++.

------
ghostdiver
OOP is fun, it makes some sense for beginners, doing something "The OOP Way"
always felt like an achievement for me, when I was a child. It motivated me to
learn more.

------
davedx
Well, no shit sherlock. You also don't start teaching people to drive a manual
car by telling them to use all 5 gears and drive on the highway.

I would have thought this was self-evident.

~~~
Pitarou
Then I guess you haven't suffered through introductory programming texts like
"Objects First With Java".

~~~
DSMan195276
I would agree - I'm current in a college CS program (I have ~6 years of
programming experience already, so the introductory stuff is a breeze). The
_very_ first programming class we took was "Intro to Object-Oriented
programming in Java". The irony is that a good 3/4's of the final projects
people turned in where just a big mess of procedural static methods and global
variables all shoved into the single 'required' class to hold main(). There
were some who after going through the class understood OOP a bit more then
they used to, but those were really just people who already had some
programming experience. Those who came into the program with no experience
were still trying to figure out the basics of procedural stuff ('This is how a
for loop works', 'this is an int, it's not an object', 'i = i + 1 is a valid
statement', while() vs. do while(), etc...) (And are _still_ trying to figure
that stuff out even now, though now a bit more complex issues, a year later,
since it was never really taught that well)

I think the biggest thing that stuck-out to me as being utterly wrong with
teaching Java and OOP is that you're forced to talk about references/pointers
extremely early on, when most of the students don't have enough grasp on the
core language to understand them conceptually (And really, who understands a
reference/pointer the first time they heard about it? let alone 2 months after
starting programming).

I honestly think starting off with C would have been better, and I don't view
C as a good beginners language. But C itself has a pretty simple core
language, and writing small procedural programs in it isn't very hard to
conceptualize, so it requires a minimal amount of hand-waving to get simple
programs running. (Hello 'public static void main(String args[])') The biggest
hurdle would probably be string handling, as it's an array of char's. If
you're not concerned with buffer overflows though, simple stack-allocated
arrays work fine for tons of simple introductory programs, and <string.h>
provides enough to get by without messing with any pointers.

~~~
bluetomcat
Starting with C would be good, but only if the teacher constantly supervises
and reviews the code that gets written by the students. Beginners will
inevitably do mistakes as they are learning, and the leaky abstraction between
C and the underlying architecture would punish these mistakes mercilessly.
Writing correct C code is one thing, asking "why is this language broken"
because you returned a pointer to a local variable is another.

------
ajanuary
As a contrast, Steven Ragnarok has a interesting talk about teaching ruby with
objects [1].

Whether it's appropriate to start with an OO language I guess is another
question, but I think done the right way, starting with OO isn't as hard as
people think.

[1]
[http://www.youtube.com/watch?v=SNbBC2pSiVw](http://www.youtube.com/watch?v=SNbBC2pSiVw)

------
popee
> Python is good for a wide range of simple and interesting problems that
> would be too much effort in C. (Seriously, a basic spellchecker can be
> implemented in a few lines of Python.)

But, but, someone somewhere in galaxy far away already made lib so you can use
it in C with only few lines of code.

------
dnkrtz
I don't think Python is a good first language. It's far too abstracted. I've
always felt that learning lower level languages first then moving up the
ladder is the better approach.

~~~
betterunix
I disagree; abstractions are good, and it is more important for students to
learn to think abstractly than to learn how a computer works "under the hood."
The vast majority of computing tasks involve abstract problems with abstract
solutions -- computing account balances, querying databases, cryptography,
UIs, networking, etc. Even basic things in a CS curriculum like data
structures and algorithms require abstract approaches and gain very little
from knowing low-level details.

There is a place for the low-level details: computer architecture, compilers,
and operating systems. Students should take these courses to be well-rounded
and to see how theory is translated into practice, but elsewhere things should
be done at a high level.

~~~
Goladus
_Even basic things in a CS curriculum like data structures and algorithms
require abstract approaches and gain very little from knowing low-level
details._

I'd disagree somewhat. Data structures, from a CS perspective, often involve
learning about low-level implementation details (why is accessing a hash O(1)?
Why do array elements have to be the same size? What's the difference between
representing a graph as a linked list versus a 2-dimensional matrix?). It's
similar with algorithms.

Even though you CAN use completely abstract computational models to learn
algorithms, many of the most important algorithms are designed around
tradeoffs between real-world resources and being able to map abstract
algorithms to a low-level language like C is a very useful skill to those who
have it.

------
dnm
I agree with the article and think Python is great for a first language.

I asked my daughter's AP comp sci teacher: Why Java? A: because that's what
the test uses.

------
lispm
Don't start with learning how to use a bicycle. Start with Rocket Science.

The Anti-OOP propaganda gets stronger.

Didn't Alan Kay of Smalltalk fame work with and for children?

------
hyp0
tangent: isn't the tricky part of a spellchecker the edit/Levenshtein
distance? i.e. to still recognize a word even when misspelled - else you can
only look up words that are already spelled correctly.

(I checked the comments on the last three times sunmissions of his
spellchecker article, but no one seemed to raise this point...)

------
analog31
How about a more provocative idea (yes, a straw man, but I'm just thinking
aloud):

Don't distract new programmers with computer science. ;-)

~~~
venomsnake
That is not so bad idea. There is one essential skill - being able to get
around and make any technology do your bidding.

People learn stuff well when it is rooted in reality. Make them make few
simple programs that could be done with excel.

And right now with these insanely rich libraries that are on the market you
could spend half your career without knowing what O notation is and have no
problems.

------
dschiptsov
It is good to learn that OO capabilities are almost entirely a set of
conventions and how these could be implemented as a DSL, like it have been
done _many times_ with Common Lisps and Schemes. CLOS is just a DSL.

Another case study is Scala language, which is functional in the first place,
and uses OO as a convenient way to structure the code, which, together with
message passing were Alan Kay's original concepts.

OO should be a nice optional add on, not a forsed the only way to do it all as
it is in case of Java or Ruby.

