4 ms·
It's true. The aforementioned languages not only boil down Smalltalk's object system into a basic "code sharing" scheme, they also perpetuate the unnecessary cl
by trashburger 4y ago
It's true. The aforementioned languages not only boil down Smalltalk's object system into a basic "code sharing" scheme, they also perpetuate the unnecessary class and instance dichotomy. There is no reason an "instance" cannot be a "class" by itself. Self (a successor to Smalltalk) gets rid of this dichotomy by assuming a prototype-based object system instead of Smalltalk's classes. In Self, a prototype can be copied and that copy can then be used as its own prototype (this is used heavily in its UI toolkit Morphic).
- skissane 4y agoI think, even in prototype systems, the class-vs-instance dichotomy still exists at a conceptual level, even if the language/runtime doesn't make it explicit. My "window" prototype might be the same sort of thing as an individual window, but it would be a big mistake to try to actually display the prototype on the screen. Being explicit about the class-vs-instance dichotomy is a kind of strong typing – the language and runtime is aware of the conceptual distinction; whereas prototype-based languages are comparatively weak typing – the conceptual distinction still exists in the mind of the developer, but the language/runtime doesn't know about it. Class-based languages catch the "trying to use the prototype as if it was an actual instance" bug at compile-time, prototype-based languages leave it to blow up in bizarre ways at runtime (accidentally treating the prototype as an instance can lead to modifying the prototype, which can then cause unpredictable consequences for all the other objects having that prototype.) One big problem with Java, is the lack of meta-classes. Why can't I subclass Class? There are cases where doing so might be a sensible solution, but Java won't let you. In Java, for my instance methods, I can inherit them from a superclass, or have them implement an interface; but, static class methods cannot be inherited, nor can the static methods of a class implement an interface. This forces people into workarounds such as the factory pattern (which many Java applications/libraries massively overuse), when having a static method implement an interface might be a simpler solution – but that would require us to be able to (effectively) subclass Class. It also produces weird things like 'Class<T>' to mean a class extending class (or implementing interface) T, where meta-classes would offer a much more elegant solution. I don't think the real problem with Java is that it is class-based rather than prototype-based, I think the problem is that its class system is half-baked (no metaclasses, no reified generics, etc) A point this article raises, which is very true – in Smalltalk, reflection is read-write – modifying classes at runtime is as easy as querying them. Java reflection is essentially read-only. It is possible to do read-write reflection in Java, but it involves immense complexity with source code or byte code generation libraries, custom class loaders, etc – to do something which Smalltalk supports trivially. The argument on the Java side, is that read-write makes optimisations (JIT/etc) a lot harder. No doubt true, but there are alternatives which Java has not pursued – for example, support multiple versions of a class, code is JITted to work with the latest version at JIT time, but other versions are detected and cause a fallback to interpreter mode (possibly followed by re-JITting to add support for that other version.)
- bitwize 4y ago> My "window" prototype might be the same sort of thing as an individual window, but it would be a big mistake to try to actually display the prototype on the screen. This is not how Self works. In Self, it is legitimate to take an existing window, clone it, and change properties and methods to taste. The first window serves as prototype for the second, despite also being a regular window. It's also possible to use what I call the Master Mold pattern (after the Sentinel from Marvel Comics whose only purpose is to make more Sentinels). That is, to construct an object that isn't actually used except as a prototype for other objects. In that case, the prototype will indeed function like a class. But this isn't necessary or even encouraged in Self.
- skissane 4y ago> In Self, it is legitimate to take an existing window, clone it, and change properties and methods to taste. The first window serves as prototype for the second, despite also being a regular window. But doesn't this have the risk, that I change some property on the first window, without realising the second window is using the first as its prototype – and while that property change is beneficial for the first window, it is detrimental to the second? I suppose the same thing can happen in class-based OO – I might make some change to a superclass which is beneficial for one subclass but breaks another. However, I think the class-vs-instance dichotomy helps here – if I'm trying to evaluate whether a change to the superclass might break a subclass, I can focus on the subclasses, and often I can get away with not studying every piece of code which instantiates or uses the class and its subclasses. I can't use that heuristic in prototype-based languages, since the language syntax and semantics don't distinguish unextended uses from extensions. > It's also possible to use what I call the Master Mold pattern (after the Sentinel from Marvel Comics whose only purpose is to make more Sentinels). That is, to construct an object that isn't actually used except as a prototype for other objects. Oh sure, but here we are back to "weak-typing" vs "strong-typing". A class-based language enforces the "Master Mold" pattern, and if you try to violate it, your code won't even compile. A prototype-based language doesn't enforce the pattern, it is just in the programmer's head. Being able to break it in an exceptional case might be helpful; on the other hand, there is the risk the programmer might break it by accident rather than intention, producing bugs which would never happen in a more strongly-typed language.
- igouy 4y agoLike some other incredibly widely used programming language? https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object_prototypes https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Ob...
- skissane 4y agoWhich it is worth pointing out has (relatively recently, in 2015's ES6) added classes too – which are mostly just syntactic sugar for prototypes (but not entirely, since they also add some new semantics for which there is no equivalent in pure prototype-based code.) Looking to the future, they are likely to add more new semantics and syntax to classes, which will have no direct equivalent in pure prototypes, causing JavaScript/ECMAScript to evolve from a purely prototype-based language into more of a hybrid between prototype-based and class-based OO.
- dkarl 4y ago> The aforementioned languages not only boil down Smalltalk's object system into a basic "code sharing" scheme This is wrong. C++ wasn't based on Smalltalk. It was inspired by ideas in Simula, which predated Smalltalk. Alan Kay tried to convince people (and succeeded with many) that he owned the term object-oriented, because he was the first person to use it. He wanted it mean only his ideas, but from very early on people were applying it to a variety of ideas that were developing concurrently in the sixties and seventies, his being only one flavor among others. He never gave up trying to convince people that all the other competing ideas were a distorted, mistaken version of his own, but the truth is that those other ideas had their own history and earned their success on their own merits.
- discreteevent 4y agoI think Smalltalk was inspired by Simula and Kay has given it credit. For me the big insight of Simula was making the object first class. Once you make something like that first class you get a lot of benefits and the distinction between the styles of doing that (e.g. Lisp Vs Smalltalk or Simula) are important but not near as important as that first insight. > In Simula I, Dahl made two changes to the Algol 60 block: small changes, but changes with far-reaching consequences. First, “a block instance is permitted to outlive its calling statement, and to remain in existence for as long as the program needs to refer to it” [11]. Second, references to those block instances are treated as data, which gives the program a way to refer to them as independent objects. https://www.sciencedirect.com/science/article/pii/S0890540113000795 https://www.sciencedirect.com/science/article/pii/S089054011...
- infinite8s 4y ago> Alan Kay tried to convince people (and succeeded with many) that he owned the term object-oriented, because he was the first person to use it. He wanted it mean only his ideas, but from very early on people were applying it to a variety of ideas that were developing concurrently in the sixties and seventies, his being only one flavor among others. Do you have any citations for this? From the quotes I've seen, it sounds like he regrets using the term 'object-oriented' for the approaches he was thinking of: http://lists.squeakfoundation.org/pipermail/squeak-dev//2002-April/038745.html http://lists.squeakfoundation.org/pipermail/squeak-dev//2002...
- Tabular-Iceberg 4y agoSpeaking of prototypal object systems, is there still an application for JavaScript prototypes today? I can't remember interacting with them even once in the last five years unless it was some legacy code from long before that. That said, I don't think classes was much of an improvement. I've seen a lot of profoundly stupid code come out of it, like singletons with a static getInstance(), just because that's what you do in Java, never mind that JavaScript has object literals. Then again before that I saw the same stupid singletons, but implemented with prototypes instead.