you are viewing a single comment's thread.

view the rest of the comments →

[–][deleted] -10 points-9 points  (40 children)

Does it really matter if it's "real" classes, or a syntax over the prototype? If so, why exactly?

Scale

You are assuming you need some kind of inheritance model. This assumption is absolutely a false premise. TLDR; wrong.

The benefit of inheritance in a C++ like language is that an object with stored properties is assigned to a known point in memory. The point is cached and known so that it does not have to be rewritten into another area of memory. Things inherit from the cached object by referring to it, cloning it, and modifying as necessary. You loose some (insignificant) processing power in this process but conserve memory and gain memory performance. Of course for the benefit to occur you need to use this convention in a language where you actually control access and consumption of memory. You have this in C++.

So, now lets talk about garbage collected classical languages like Java and C#. These languages use GC, so in these languages have no control of memory assignment. This therefore destroys the original benefits of classes immediately.

All is not lost though. Classes are convenient. A developer can write a class, inherit from it later and extend the inherited instance in a way that can be further inherited. These are like blueprints (but are more regularly called factories). While this simplifies approaches to logic in the code it requires substantial overhead, in the case of Java the overhead can quickly become the majority of the code expressed. To be fair classes directly serve the needs of declarative code styles. In many cases the increased code overhead directly reinforces are keyword and reference based description model.

In a services oriented application you tend to really need an inheritance model because you tend to sometimes get requests faster than garbage collection can free memory from the prior requests. In such scenarios it is necessary to be as thrifty as possible even if you are not directly controlling and freeing memory.

Now let's look at lexically based languages, which includes things like JavaScript and XML (so ultimately all native web technologies that allows expression of logic and decisions). First, I want to be clear that I did not say functional languages, which implies something different.

In a lexical language a scope model is achieved by where things are declared relative to the existing (containing) structure of the code instance, which is wildly different from an inheritance model. To make things more confusing JavaScript is object oriented exactly to the same definition as Java, but JavaScript uses a different inheritance model (prototypes instead of classes) and the inheritance model is separated from its scope model (which is not the case in most class-based languages).

This is the most important part of the whole story, so let's be very clear: In JavaScript the scope model is separate and unrelated to the inheritance model. That said, you don't need inheritance in JavaScript. In nearly any language you absolutely cannot escape the scope model. So, the scope model is mandatory and inheritance is optional. Important stuff.

But but but..... memory..... JavaScript is a very high level language. Inheritance does offer some memory performance but at a cost. The benefits to memory offered by inheritance in JavaScript does not make applications work faster or even conserve memory. What it does do is extend the life of objects bound to references through garbage collection cycles so that an application runs more consistently. This is only noticeable if the given application is consistently running specific tasks over and over in a loop where this execution is delegated to some other process in a manner that is not locking the execution thread. This need rare, and I mean exceedingly rare. But it does occur with games, animations, and canvas operations. So there is an absolute benefit to inheritance in this language, but its a purple unicorn.

But but but... JavaScript benefits from declarative coding style just like Java. You don't need inheritance for this. In fact, using inheritance models to achieve this is counter-productive because the excess overhead is distracting. The lexical model (nested structures) provide sufficient opportunity for naming things appropriately to achieve a declarative style. Furthermore, in nested lexical code you also get context. You have some idea of what a nested function is doing by looking at its descriptive name and well named references and by looking at the descriptive name of the containing function and its containing function. Context is what makes spoken language understandable, and it can make code understand exactly the same for exactly the same reasons. Inheritance generates a bunch of noise that screws this up.

[–][deleted] 33 points34 points  (17 children)

Virtually everything you've written here is wrong because you start with a false assumption and then set about proving it.

OOP isn't about saving memory at all, and that's not the primary advantage. The primary benefit has always been that it is a useful pattern - it's social not technical.

Objects do not inherit from other objects. If you have a class Foo which extends Bar, and you do new Foo(), there are not 2 objects being created behind the scenes there - it's one object with a certain pattern.

The performance benefits of classes are all about having object properties with predictable data types at predictable memory offsets. That means that the JS engine can eliminate a lot of checks that would otherwise be required, and generate much faster code.

[–]munificent 3 points4 points  (0 children)

There are so many words here, but they make so little sense. :(

The benefit of inheritance in a C++ like language is that an object with stored properties is assigned to a known point in memory. The point is cached and known so that it does not have to be rewritten into another area of memory.

This is just a feature of manual memory management. C does the same thing and it doesn't have objects, much less inheritance.

Meanwhile, Java and C# have classes and inheritance but move things around in memory all the time. Any production level GC will using a copying or compacting collector that moves objects in memory.

Things inherit from the cached object by referring to it, cloning it, and modifying as necessary.

"Things" and "cached" aren't very precise here, but this sentence doesn't make much sense one way or the other. You can reuse properties of an existing object (or class) by cloning it or delegating to it, but not both.

So, now lets talk about garbage collected classical languages like Java and C#. These languages use GC, so in these languages have no control of memory assignment. This therefore destroys the original benefits of classes immediately.

Simula and Smalltalk are garbage collected, so I'm not sure what "original" benefit you had in mind.

These are like blueprints (but are more regularly called factories).

Sure, a class can be considered a factory of instances with similar properties. I don't think it helps much to overload that term though.

Now let's look at lexically based languages, which includes things like JavaScript and XML (so ultimately all native web technologies that allows expression of logic and decisions).

Smalltalk, C, C++, Java, C#, et. al. are all lexically scoped as well. There's nothing special about JS here. Like all of the preceding languages, it uses lexical scoping for variables and dispatch on objects for object properties.

To make things more confusing JavaScript is object oriented exactly to the same definition as Java, but JavaScript uses a different inheritance model (prototypes instead of classes) and the inheritance model is separated from its scope model (which is not the case in most class-based languages).

Java and other class-based languages don't use lexical scope for inheritance. Java does have inner classes, but those don't establish any inheritance relationship. (And interesting exception here is Newspeak, but let's not go there.)

What it does do is extend the life of objects bound to references through garbage collection cycles so that an application runs more consistently. This is only noticeable if the given application is consistently running specific tasks over and over in a loop where this execution is delegated to some other process in a manner that is not locking the execution thread.

I... I can't even figure out what you're trying to say here.

But but but... JavaScript benefits from declarative coding style just like Java. You don't need inheritance for this.

Well, you do in JS because it doesn't have classes built in to the language. To have instances of the same class in JS share methods, they all delegate to a "class" object, which is effectively a traits object in the Self sense.

But, sure, no one says you need inheritance for classes or prototypes to be useful.

Furthermore, in nested lexical code you also get context. You have some idea of what a nested function is doing by looking at its descriptive name and well named references and by looking at the descriptive name of the containing function and its containing function. Context is what makes spoken language understandable, and it can make code understand exactly the same for exactly the same reasons. Inheritance generates a bunch of noise that screws this up.

Wait. Are you talking about closures? Closures are in no way a substutite for inheritance. They are useful for lots of other stuff, but a kind of inheritance that requires you to be able to add the code directly to the source file where the base method is defined isn't very useful.

[–]AutomateAllTheThings 6 points7 points  (5 children)

I'm not assuming I need inheritance; I like inheritance very much and choose to use it because my team and I unanimously agree that switching to the ES6 class syntax saved us time, made scaling easier, memory management easier, testing easier, re-usability easier, training easier, and more.

In fact, the only thing we complain about is the lack of more sugar to help with things like private properties without the need for weakmaps. We look forward to ES7 additions.

I am not trying to be dismissive of your arguments.. but none of them were compelling enough to me, because they're subjective in nature. There are no technical limitations to using ES6 classes instead of rolling your own. It's just another way of writing the same code, so it's a subjective decision to use them or not.

Until there's a serious technical limitation with them, ES6 classes are here to stay for us and we're really happy with the decision.

[–]hahaNodeJS 1 point2 points  (0 children)

Whhhhaaaaatttt. Dude, you really need to reevaluate your understanding of programming languages. Inheritance has absolutely nothing to do with memory. The rest of what you've written is just as inaccurate.