Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The prospect of teaching the JavaScript language as a first language is actually really exciting. Teaching prototypal inheritance to experienced classical-inheritance-using developers is normally rather frustrating (and results in many libraries springing up attempting to replicate the classical style of inheritance in JavaScript, which is a whole realm of weirdness in-and-of itself). Teaching prototypal inheritance to someone who has never seen any form of inheritance before will decidedly be an easier task.

But does this result in a better outcome for the student?

How many other commonly used programming languages use prototypal inheritance?



In answer to your first question. Prototypes are a much much simpler concept than classes and instances. In prototypes, you create an object X which is "just like object Y but with the following differences". No class declarations, no instantiation, no constructors -- just factory functions. Prototypes are also easily understood by people who have grasped the concept of dictionaries. No need to explain why you have dictionaries and also have classes.

Prototypes also have some niceties. They are very memory compact, unlike classes and instances. They are elegantly dynamic -- you can add and delete methods and variables, and even change who your prototype is at runtime. Methods in prototypes are very similar to functions, so you don't have to explain the distinctions there.

I think the main problem is that Javascript is such a screwed up language that it has soured people forever on prototype OO and no amount of semantic elegance will fix that.

In answer to your second question, here's the list of languages I know of. Only two are "mainstream", but in a field (CS) where quality is all too often inversely related to popularity, I'm not sure if that's a helpful metric.

1. Self

2. NewtonScript

3. Lua (via metamethods)

4. io

5. IIRC Python implements OO with something approximating prototypes internally but covers them with a class-based sheen when presented to the developer.


IIRC Python implements OO with something approximating prototypes internally but covers them with a class-based sheen when presented to the developer.

One notable difference is that `foo.method` is bound to `foo` in python, but unbound in JavaScript. This leads to lots of `foo.method.bind(foo)` because the former didn't DWIM.


I've been writing Python for maybe 3 months now and as I started digging into the OO stuff, I commented to a few developers about how it 'felt' a lot like javascript and they nearly took my head off. Is there any material you (or anyone for that matter) can point me to that might help solidify my argument?


Ian Bicking gave a talk on the similarities and differences between Python and Javascript that might be helpful, but it's pretty high level: http://blip.tv/pycon-us-videos-2009-2010-2011/pycon-2011-jav...

The key similarities in my mind are:

1) In both python and javascript, the class and prototype are exposed and can be called explicitly if desired:

  MyClass.method(my_instance, arg1, arg2)

  MyClass.prototype.method.call(my_instance, arg1, arg2);
2) Python will automatically bind methods when you retrive them from an instance. Unless you explicitly bind a function in JS, the "this" parameter is specified at call time: whatever comes before the dot is used as "this". Ultimately they're both first class objects and the difference to the developer is notation:

  bound_method = my_instance.method

  bound_method = my_instance.method.bind(my_instance);
3) Attribute lookups in Python behave very similarly to property lookups in Javascript. Python has a modified resolution order for searching for an attribute through its list of parent classes. Javascript will look for an attribute in a series of prototypes (since in JS, an instance's prototype is just an object, so it too can have a prototype). Python is superior here because it supports multiple inheritance, but overall the resolution behaviour is essentially the same.

Can anyone think of any other common ground?


Can you elaborate? Honestly I think the differences far outweigh the similarities.

One case that comes to mind is how each language implements (what I call) the continuation pattern. Suppose you want to iterate over the vertices of a binary tree. In JavaScript, you would accept a callback parameter which you call with each vertex. In Python, you would yield each vertex to the caller. These are very different styles and lead you in different directions.


For you first answer, I am not saying you are wrong, but I'd like to see some evidence (e.g. pointer to researches) that prototypes are "much _much_ simpler" than classes and instances.

The usual counter example in this discussion goes like: "..but people are already familiar with the concept of categories of objects...".

I do argue with the following paragraph: I don't see why prototypes-based languages should be more memory compact than class-based, and class based languages can have dynamic addition of methods and variables (see ruby), and change of an instance' class (at least since Smalltalk 80 AFAICT).


> I do argue with the following paragraph: I don't see why prototypes-based languages should be more memory compact than class-based

In most class-based languages, when you create an instance, you allocate memory sufficient for all instance variables defined by its class and superclasses. But in a prototype language, when you create an object, you only allocate memory for the instance variables in which it is different from its parents. That often results in enormous savings, particularly in GUI widgets where you have zillions of instance variables, nearly all of which are left on default settings.

Most class-based languages do this because it allows O(1) lookup of instance variables. Whereas lookup in a prototype language may require wandering up the parent chain until you find the object which defined a given instance variable. That's the tradeoff: lookup speed for memory compactness.

There exist a few class-based languages which don't do this tradeoff. But I have yet to see one of this kind which _doesn't_ basically just implement prototypes underneath. Python is notable here: it doesn't have O(1) lookup to the best of my knowledge, yet doesn't allow the simplicity of prototypes either, so it's sort of the worst of both worlds IMHO.

> and class based languages can have dynamic addition of methods and variables (see ruby), and change of an instance' class (at least since Smalltalk 80 AFAICT).

And CLOS. Sure. But these are exceptions, and don't kid yourself, bolting them into class mechanisms comes at a cost of significant increases in complexity and speed (and loss of the O(1) advantage that classes provide). But in proto languages, you're just adding or changing a dictionary entry. It can't get simpler than that.

> For you first answer, I am not saying you are wrong, but I'd like to see some evidence (e.g. pointer to researches) that prototypes are "much _much_ simpler" than classes and instances.

I'm not sure if simplicity is of interest to academic research. But let me try with an example. In NewtonScript, to make a button which has a different x and y location, text, and override some function (say setText()), I'd say something like this:

    myButton := { 
        _proto: Button, 
        x: 14, 
        y: 15, 
        text: "Hello, World",
        setText() begin here's the code blah blah end
        }
Done and done. In Java, I'd do:

    public class MyButton extends JButton
        {
        public void setText() { here's the code blah blah }
        }

    MyButton foo = new MyButton();
    foo.setText("Hello, World");
    foo.setLocation(x,y);
If Java had done anonymous classes right I could have used that to just set the x and y and get a little closer to the NewtonScript example. But the point is: in the proto language I didn't need to declare a class just to override a method. You have to admit there's some elegance and simplicity there. Indeed, my Newtonscript code tended to be very short and simple, whereas my Lisp/CLOS, Python, and Java OO code tends not to be.


I think we may be having a terminology issue here: you seem to define "prototype based" languages as those that have dictionaries for instance variables and methods, whereas class based languages have structs for instance variables and compile-time generated vtables for dispatch.

But this looks like an implementation detail that does not seem related to prototypes vs classes, but more to dynamic vs static ones (e.g. Cecil does prototypes without storing a dictionary in the object, while ruby does classes with dictionaries)

So we may be in agreement, but referring to different things.





Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

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

Search: