Skip to content

Instantly share code, notes, and snippets.

@timoxley
Last active August 29, 2015 14:20
Show Gist options
  • Save timoxley/ae19556a33dd3867a697 to your computer and use it in GitHub Desktop.
Save timoxley/ae19556a33dd3867a697 to your computer and use it in GitHub Desktop.
tl;dr. 2.5 Dynamic Behavior Changes: Changing An Instance’s Class and Dynamic Inheritance

Organizing Programs Without Classes

Source: https://cs.au.dk/~hosc/local/LaSC-4-3-pp223-242.pdf

Section 2.5 Dynamic Behavior Changes: Changing An Instance’s Class and Dynamic Inheritance

tl;dr

Sometimes the behavior of an instance of a data type can be divided into several different “modes” of behavior or implementation…

A self-reorganizing collection might use radically different representations depending on recent access patterns, such as whether insertion has been more or less frequent than indexing, even though the external interface to the collection remains unchanged…

One common way of capturing different behavioral modes is to include a flag instance variable defining the behavior mode, and testing the flag at the beginning of each method that depends on the behavior mode. This obscures the code for each behavior mode, merging all behavior modes into shared methods that are sprinkled with if-tests and case-statements…

This code is analogous to programs simulating object-oriented method dispatching: if-tests and case-statements are used to determine the type of the receiver of a “message.” Not surprisingly, flag tests for behavior modes suffer from the same problems as flag tests for receiver types: it is hard to add new behavior modes without modifying lots of code, it is error-prone to write, and it is difficult to understand a particular mode since its code is intermixed with code for other behavior modes…

A better way of implementing behavior modes is to define each mode as its own special subtype of the general data type, and use method dispatching and inheritance to eliminate the flag tests.:

For example, the collection data type could be refined into an empty collection data type and a non-empty collection data type, using inheritance to relate the three types... However, the behavior mode of an instance may change as its state changes: an empty collection becomes non-empty if an element is added to it.… Most class-based languages do not allow an object to change its class, and those that do face hard problems.… Classless languages, on the other hand, can be naturally extended to handle dynamically-changing behavior modes by allowing an object’s parents to change at run-time;…

Behavior modes are naturally implemented in classless languages by using dynamic inheritance to choose from a small set of parents. This style of programming does not compromise the structure of the system; on the contrary, it can make the structure and organization of the system clearer by separating out the various modes of behavior. In contrast, the close coupling between a class and its representation prevent class-based languages from being extended naturally to handle behavior modes.

@timoxley
Copy link
Author

Note: I've purposely left out the sections that promote changing the representation dynamically, i.e. totally changing the interface at runtime, as having methods appearing and disappearing certainly does seem horribly pain-inducing, but so long as the underlying structures have compatible interfaces, this seems to me to be a very powerful pattern that we can almost harness in JavaScript, were it not for the gratuitous performance costs and disgust from our peers.

@timoxley
Copy link
Author

A real-world example akin to the "self-reorganising collection" example above can be seen in the way v8 swaps datatype implementations at runtime, e.g. switching between Number/Integer types depending on the range of numbers in use or Arrays/Objects going into hash-table/slow mode if you don't treat them with enough respect.

Efficient swapping of prototypes in userland code would enable developers to be able to easily implement similar dynamic optimisations in their own datatypes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment