Hacker News new | ask | show | jobs
by ZenPsycho 5126 days ago
That's a weird thing to think. If you can simulate classes with prototypes, but you can't simulate prototypes with classes, what is the natural conclusion you can come to about which is more expressive or primitive?
6 comments

That prototypes are overly complex.

You can't simulate most imperative programs with functional ones because writing in a functional language eliminates a vast majority of bugs due to incomplete reasoning about memory barriers and other really hard to duplicate issues like race conditions.

CHESS is an amazing piece of software precisely because it CAN simulate race conditions and reproduce them, however, if these things didn't exist no one would ever bother trying to reproduce them.

I'm quite fine not being able simulate these issues.

I'm not saying you're wrong, but isn't this a bit like saying that files are overly complex because they can be used to simulate sockets?
It is, but on the other hand if you write code to work with sockets then you get a performance boost on spinning disks because your IO is sequential. And many other benefits like trivial cache prediction, buffering, etc.

I do think that prototypes have useful properties, but I'm not sure that a prototype isn't a form of an open class. I tend to think that the biggest problem with prototypes in js is the interface.

Prototypes in JS are problematic due to false cognates- it tried to look like Java (due to marketing department fuckery), and use the same keywords as java, but it doesn't act at all like Java which leads to some nasty surprises. This has been fixed in ES5- the correct way to inherit from a prototype is no longer via constructor functions and their prototype property, but via Object.create()
When talking about programming languages, "primitive" usually means low level. For example, primitive data types (http://en.wikipedia.org/wiki/Primitive_data_type).
So given that, how do you come to the conclusion that prototypes are more primitive than classes?
Just as you said yourself: classes can be simulated with prototypes and are therefore higher level than prototypes. In other words, prototypes are lower level (more primitive) than classes.
The Gameboy color hardware can be simulated on a desktop computer in a browser, in javascript. Does that make desktop computers more primitive than Gameboys?
It's a difference of power and size, not level of complexity. In theory you could simulate a desktop computer with a browser and javascript on a gameboy color given enough processing power and memory. (without increasing instruction set complexity / requiring more abstraction levels than on a desktop / sneakily inserting more complexity in some other way)

Actually it's a rule of hacks, isn't it? If it can exist... https://www.youtube.com/watch?v=QsZrD622qf0

@viraptor and so we can see that we must take into account more than just whether one can be simulated on another, we must take into account /expressiveness/, or level of complexity as well! In theory, you could simulate prototypes with classes too. You have to be able to, or else it wouldn't be possible to write an interpreter for a language which supports prototypes. The question of "can" and "can't" then, in the context of my original question has to do with the level of difficulty in doing one or the other. Now that we've got this far, what is more difficult- simulating classes with prototypes, or simulating prototypes with classes? Which requires more code, and more complexity? And from that, what do we conclude about primitiveness?
I'd still stand by the opinion that the browser in GBA is the same level of complexity as GBA in browser. They're interpreters of some code essentially (one of GBA roms, the other of html/js). There is of course a different human complexity of "how hard would it be to implement"... but if we're adding JS engine to the mix, the browser may be actually harder.

With classes / prototypes (sorry for wibbly wobbly explanation, my CS is not good enough to use the proper terms, which probably exist out there), you can pretend there's a "behaves like" relationship. To simulate a prototype using a class you have to build the freely accessible dictionary and initialisation/cloning semantics level inside of the class.

To simulate classes using a prototype... that depends on your definition of a class. Dynamic dispatch is already there, encapsulation too, subtypes just need a field specifying the name and cloning the right prototype, inheritance is on by default. Self-referencing is usually in there too.

So in my opinion classes can be substituted by prototypes in a large number of cases. Classes however need another layer on top to act like prototypes. So prototypes look like more primitive than classes and classes look like a special-cased version of prototypes. Then again, it's late here, so maybe I missed something obvious...

Anything I can do with a string, I could also do with an array. However, it would take extra work to make an array behave like a string, in the form of helper functions, etc.

If I really wanted to prove a point, I could make a string behave like an array. But that would take even more work because an array is a very flexible tool used for a variety of low level purposes.

Therefor, according to your argument, a string is a more primitive data type because it takes more work to make a string act like an array than it does to make an array act like a string. This goes in direct contradiction to the actual definition of a programming primitive.

Back to the original poster's quote, "JSX offers a solid class system much like the Java programming language, freeing the developers from working with the too-primitive prototype-based inheritance system provided by JavaScript."

He is quite clearly addressing a specific case here, which is programmers who want to use Java-like classes when developing in Javascript. A lot of extra work is required if you want to make a Javascript prototype behave like a Java class, with inheritance, etc. So in this context, it is obvious that Javascript prototypes are "too primitive" for the task at hand.

Similar to the way that strings are, in fact, arrays with lots of extra functions for frequently repeated, string-related tasks, JSX classes are JS prototypes with a lot of the oft-repeated boilerplate code done for you. I'm not sure how to make it more clear how the chain of "primitiveness" flows in this case.

It seems you are confusing a number of things. I suggest you read this Wikipedia article, it should answer most of your questions: http://en.wikipedia.org/wiki/High-level_programming_language
@olalonde that's a bit of a cop out, of course I've read that article. That is why I'm baffled by the assertion that prototypes are more primitive than classes. It doesn't add up with the definitions of what amounts to being high level and low level. If you have something more specific to say I suggest you say it, but it's pretty lame to just wave your hands at a wikipedia article and tell me to figure out something that you've obviously got wrong, from my point of view.
@viraptor (i can't reply directly to messages sometimes for some reason. is it a karma thing?) , So, what you are saying is that if you want to simulate A in B, but B needs an abstraction layer to simulate A, while A can simulate B more directly and naturally, that makes A more primative? So then does that mean that C is more Primitive than Assembler?
Here is an example of doing prototypes with classes in python: http://kashif.razzaqui.com/30414548

I presume similar is available in just about any language with decent reflection and/or generics.

@j_baker I do not agree that prototypes are primitive and I decided to express this in the form of socratic irony.

@fleitz Whether prototypes are overly complex is neither here nor there. the question is whether they are primitive. More primitive than classes- something which is historically and demonstrably untrue, in my opinion.

It would seem as though prototypes are the more expressive option if you can use them to simulate classes. In fact, one could argue that this is essentially what Python does.

...but the OP seemed to indicate that prototypes were "primitive", and it sounds like you agree with him. Are you trying to say something that I'm missing?

That's not what expressiveness means. Classes can be simulated in assembly but assembly isn't very expressive.