Hacker News new | past | comments | ask | show | jobs | submit login

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.




They also struggle with functions, parameters, pointers, scope and so on.

You don't need to pass parameters to your car to start it. You don't need to force yourself to only focus on the recipe (scope) when making dinner.

None of these things map very well with the real world and could also be considered additional mental overhead when learning. You don't need to know how to code to learn best known practices in building software.


Functions, parameters, and pointers are also optional concepts in python. None of them are needed in a hello world program, nor for a few weeks into an introductory course. Variables, expressions, conditionals, lists, strings, and loops can all exist on their own without any "extra stuff".

Learn things one at a time; "best practices" can wait til you can demonstrate why it is a best practice. Why should I make a function? Until you actually face the problems that abstractions are used to solve, learning them is confusing and difficult.


Optimizing for hello world is probably the least important thing when you have a 10+ year journey of learning ahead of you. In the end, what do you learn from python's hello world anyways?

This also happens in math quite a bit. There is a knowledge gap when teaching concepts like derivatives for the first time. So we are told to initially ignore details while learning.


That's probably why I didn't understand derivatives until Calc 3. I barely passed Calc 1 and 2 because my professors just told us to ignore the details. My Calc 3 professor actually showed us how everything worked, from intuition to theorem to proof.

In my experience, it's best not to delay learning the details. You don't have a real understanding of something until you understand the details.


You are right, it is quite bad to ignore the details in the long run (it requires patience of course).

However that makes even less of a case for Python.


It's far easier to understand the concepts piecemeal. Methods are easier to understand if you already grok functions. Integrals are easier to understand if you already grok derivatives. When learning these things, you're often fed an over-simplified explanation so that the instructor can go on to cover something more advanced. The problem is that now you're trying to learn something more advanced before you've got a solid understanding of the primitives.


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.


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.)


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.


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.


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.


Your point is, well, beside the point. You're saying that "OOP does not imply static methods," which is correct, but irrelevant, because the converse is true: "Static methods (in the Java sense) imply OOP." Assuming they're learning Java, it's the latter that matters to beginners, not the former.

You say it's about "Java's flavor of OOP." That's 100% true. So, how do you explain Java's flavor of OOP — which is necessary to explain why Java does certain things that would otherwise seem like arbitrary invocations — without explaining OOP at least in part? As soon as the beginner sees the word "class" or "public" they'll be forced to either contextualize those concepts or take them as arbitrary strings one puts into their program because Magic™.

The OC's point was that Java forces people to grapple with certain OOP concepts, even if those concepts are particular to Java's flavor of OOP.

You're both just talking past each other.


Nonetheless, beginners will still have to be introduced to the concepts from the start.


Only a few of them. I'd say:

    1.  Instantiate Object.
    2.  Invoke Method.
    3.  Get or modify attribute.
    4.  Do some introspection (even if the term is not used)
Most importantly, learning how to define their own classes isn't really important for beginners.


Those are the concepts starting the beginner in the face, sure. Here some of the questions a beginner will have, phrased ~10x more clearly than a beginner would ever be able to phrase them:

    1. What is an object?
    2. What does it mean to "instantiate" an object?
    3. What is a method?
    4. What does it mean to "invoke" a method?
    5. What is an attribute?
    6. What does it mean to "get" an attribute?
    7. What does it mean to "modify" an attribute?
    8. What is introspection?
And so on, until we run into a concept through which we can explain something. The idea of an "object" is a big hurdle for beginners, especially if they don't have experience writing code — it seems like weird boilerplate. Likewise, "introspection" and other meta-concepts are incredibly challenging for beginners because they have a hard time stepping "out of the code," so to speak.


The thing is, students don't need to be able to ask those questions to learn the concepts. It can be done as an interactive exercise and in the process, a student will actually see what objects are used for and gain intuitive understanding. You do not need to go into all the cumbersome detail about how they are defined in the language. Critically, you do not need to introduce concepts that require them to decide whether they should define their own classes or use built-in data types.

Here is an example that instantiates an object, introspects, gets an attribute, introspects again, and invokes a method. It's 11 commands.

    >>> import requests
    >>> def introspect(obj):
    ...     for x in dir(obj):
    ...         print x
    ...
    >>> request_object = requests.get('https://news.ycombinator.com/item?id=6919275')
    >>> introspect(request_object)
    __bool__
    __class__
    __delattr__
    __dict__
    [...]
    request
    status_code
    text
    url
    >>> request_object.status_code
    200
    >>> request_object.url
    u'https://news.ycombinator.com/item?id=6919275'
    >>> introspect(request_object.url)
    __add__
    __class__
    __contains__
    __delattr__
    [...]
    title
    translate
    upper
    zfill
    >>> request_object.url.upper
    <built-in method upper of unicode object at 0x29a3330>
    >>> request_object.url.upper()
    u'HTTPS://NEWS.YCOMBINATOR.COM/ITEM?ID=6919275'
After enough practice using objects from various python libraries, in the course of doing functional or imperative programming, they will have an intuitive understanding of objects and what they are for.

Some interested students might ask "What's an object, under the hood?" and "how can I create my own classes?" That's when you can introduce them to classes (http://docs.python.org/2/tutorial/classes.html). If they're fine with the intuitive understanding that comes with performing examples like the one above, leave them be. Don't inflict OOP principles they don't need to know yet.


Whether those questions come out of a student's mouth, those questions will be rattling around their head — most likely much fuzzier, more confused version of those questions. If you thought I was proposing that a teacher, say, give a lecture about those answers before one can even begin programming in an OOP language, I wasn't. Nor was I proposing that one go into the details of how these things are implemented in whatever language. I was only making explicit what was going through a student's head when you hand them a chunk of code which does the four things you outlined.

I think the example code you gave is fine, but does not actually answer those questions. The mind of a beginner is like a map of a country with unmarked or incorrectly-marked territories. They don't know where the relevant boundaries between concepts/territories are or even how to begin drawing them. They can't differentiate between important and unimportant details. Like a child who is just learning how to speak, they see the differences in everything and every difference matters. That is, to a beginner, if there's a difference it's important.

Here's a Ruby example. I've given many students this code:

    my_name = "Jesse"
    my_age  = 30

    puts "Hello!  My name is #{my_name} and I am #{my_age} years old."
and had them conclude without prompting, "Oh, you can name variables anything you want as long as they start with my_." They will not know they're forming this belief and will carry it with them until something — a teacher, another bit of code, etc. — contradicts that belief, except that when the contradiction arrives they may not realize consciously they had formed this particular incorrect belief.

When I look at your code, I see a few dozen opportunities for students to form exactly these kinds of beliefs, which is one of the challenges of writing effective curriculum. This is doubly difficult when there isn't a teacher nearby to catch these mistaken beliefs as they're formed or shortly thereafter. In most online or "single player" learning experiences students will form a web of incoherent, confusing beliefs, not even know they're doing it, and carry on for much longer than they would otherwise.

For example, I'm assuming the "u" prefix on those strings in Python is a way to indicate that they are unicode strings. If a student already knows that strings exist and sees that output, it's likely that a large minority of students will assume that u'HTTPS://NEWS.YCOMBINATOR.COM/ITEM?ID=6919275' does NOT represent a string but something else entirely. They will then carve out a hole in their schema of the world where "u-things" go and it will never occur to them that doing something like

    request_object.url == 'https://news.ycombinator.com/item?id=6919275'
is even possible.

Maybe we're saying the same thing, but I hope you get my point. This has to do with the particular way most beginners in any subject interact with new information.


> Maybe we're saying the same thing, but I hope you get my point. This has to do with the particular way most beginners in any subject interact with new information.

Probably, my example was off-the-cuff, and I think I may have misinterpreted the original intent of your post a bit. I'm still not sure which "side" of the discussion you're on, though. (Teach classes and OOP sooner vs. later). For my part I definitely favor "leave it for later"

In Zed Shaw's "Learn Python The Hard Way" book, after raving about dictionaries in section 39, he barely uses them for the remainder of the book, while spending a lot of time on classes and class heirarchies. It's a succinct (and very successful, I believe) introduction to OOP and Python's features so I can't vehemently criticize it, but I do wonder what the last few chapters would have looked like with a more flat function + dictionary approach.

I understand the issue of little details stuff, for sure. I've never taught python but I have taught bash. Gave you an upvode for for the second paragraph, I found it to be an unusually eloquent way to describe the learning experience. I've never been able to express that idea so well.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: