10
$\begingroup$

If I use a class-based system, I know what shape an object will be at the time I construct it, and I know exactly which fields and methods it has. They can be put in fixed locations that remain stable, and the object has a single identity its whole lifetime.

In a prototype-based model, an already-constructed object can be used as the parent (prototype) of another object, which inherits from it. Because of this, the object being used as a prototype can become part of a new object, with a new identity and new shape, during its lifetime. It can also be inherited from multiple times by different children.

Understandably, the typical approaches to representing class instances where all these things are fixed at construction time don't work as well here, so what should I do instead? Do I have to use string lookup and/or just chain manually from the deepest descendant, or is there a better representation or implementation strategy? Will these implementation details "leak through" to become visible to the programmer?


Here I'm envisaging a language where objects can be created directly with something like an object literal, and you can use an object you made that way as a prototype for others (as well as objects themselves made from prototypes). I'm open to typed or untyped approaches or varied semantic models for how that's all accomplished if needed — that's what might be leaking through from the required implementation.

$\endgroup$
7
  • $\begingroup$ JavaScript is an important language with prototype-based inheritance. That article also has examples of what this means in practice. $\endgroup$
    – l0b0
    Commented May 20, 2023 at 22:55
  • $\begingroup$ This seems to be comparing apples to oranges ─ you're assuming the class-based system is statically typed so you always know the shape of an object when you instantiate it, and presumably always know the shape of a superclass when you extend it ─ but then comparing it to a prototype-based system where you don't necessarily know the shape of an object you use as a prototype for another object. Creating objects with dynamic prototypes is akin to instantiating dynamic classes, both are possible in a dynamic type system but generally not possible in a static type system. $\endgroup$
    – kaya3
    Commented May 21, 2023 at 6:10
  • $\begingroup$ @kaya3 I don't think so. Even in a dynamically-typed system the class doesn't instantiate the object without knowing what its superclass was (or at least, that's not common). The resulting shape is known at construction even if not earlier. Even in a statically-typed prototype-based system the parent object can become (part of) a new object with unanticipated structure, and the parent has no opportunity to anticipate that. It can also be the prototype of multiple objects of different types. If there's an obvious path around that please do post the answer, it's not obvious enough to me. $\endgroup$
    – Michael Homer
    Commented May 21, 2023 at 6:16
  • $\begingroup$ I recognise that in E-style "delegation" (forwarding) prototyping it doesn't come up and nor does identity change, so I suppose that in principle that's an answer. $\endgroup$
    – Michael Homer
    Commented May 21, 2023 at 6:20
  • $\begingroup$ I'm not sure I understand what the problem you're describing is, so I'll leave it to someone else to answer, but it does seem to me that static knowledge of the prototype's shape is the key to this. $\endgroup$
    – kaya3
    Commented May 21, 2023 at 7:34

2 Answers 2

2
$\begingroup$

I think a chain of hash-maps works fairly well.

You can optimise a little bit by pre-resolving the string lookups to indexes in the map. The Wren language's VM does this. Every object gets allocated a hashmap of the same size, allowing any object to receive the same message, although if it's not supported, it's obviously a runtime error.

Wren is class-based, but there's no reason you couldn't use the same approach for prototypes, just copy the contents of an object rather than freshly initialising.

$\endgroup$
1
$\begingroup$

I think you conflate two distinct notions in your question: prototype-based inheritance and dynamic objects that can change their shape during program execution.

Prototype-based inheritance itself can be rather easily implemented even in a static class-based language for instance as it was shown by Gang-of-Four as a Prototype pattern (and/or a couple of related patterns).

As for (more) efficient implementation of dynamic objects (which has nothing to do with inheritance whatsoever) there's a list of options in another question.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .