The diamond problem
- is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If there is a method in A that B and C have overridden, and D does not override it, then which version of the method does D inherit: that of B, or that of C?
For example, in the context of GUI software development, a class Button may inherit from both classes Rectangle (for appearance) and Clickable (for functionality/input handling), and classes Rectangle and Clickable both inherit from the Object class. Now if the equals method is called for a Button object and there is no such method in the Button class but there is an overridden equals method in Rectangle or Clickable (or both), which method should be eventually called?
How different languages deal with it:
• Common #Lisp: by order "...in the order in which parent classes are named in the subclass definition"
• Curl: "and the secondary constructor will be invoked for all other subclasses."
• Eiffel: "Eiffel will automatically join features together, if they have the same name and implementation."
• Go: compile-time error
• #Java: compile-time error
• #OCaml: by order "...are inherited in the same order, with each newly inherited method overriding any existing methods."
• #Perl: by order "...from as an ordered list. The compiler uses the first method it finds..."
• #Python: by order
• #Ruby: by order "...as rightmost depth first resolution."
• #Scala: by order "allows multiple instantiation of traits, which allows for multiple inheritance by adding a distinction between the class hierarchy and the trait hierarchy. A class can only inherit from a single class, but can mix-in as many traits as desired." This approach is the most similar to #Nile's; traits being qualifications.
• Tcl: by order "the order of specification in the class declaration affects the name resolution for members..."
Languages that allow only single inheritance, where a class can only derive from one base class, do not have the diamond problem.
Moreover, languages such as #Ada, Objective-C, #CSharp, #Delphi/Free #Pascal, Java, #Swift and PHP allow multiple-inheritance of interfaces (called protocols in Objective-C and Swift). Interfaces are like abstract base classes that specify method signatures without implementing any behavior.
When several interfaces declare the same method signature, as soon as that method is implemented (defined) anywhere in the inheritance chain, it overrides any implementation of that method in the chain above it (in its superclasses). Hence, at any given level in the inheritance chain, there can be at most one implementation of any method. Thus, single-inheritance method implementation does not exhibit the Diamond Problem even with multiple-inheritance of interfaces.
- is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If there is a method in A that B and C have overridden, and D does not override it, then which version of the method does D inherit: that of B, or that of C?
For example, in the context of GUI software development, a class Button may inherit from both classes Rectangle (for appearance) and Clickable (for functionality/input handling), and classes Rectangle and Clickable both inherit from the Object class. Now if the equals method is called for a Button object and there is no such method in the Button class but there is an overridden equals method in Rectangle or Clickable (or both), which method should be eventually called?
How different languages deal with it:
• Common #Lisp: by order "...in the order in which parent classes are named in the subclass definition"
• Curl: "and the secondary constructor will be invoked for all other subclasses."
• Eiffel: "Eiffel will automatically join features together, if they have the same name and implementation."
• Go: compile-time error
• #Java: compile-time error
• #OCaml: by order "...are inherited in the same order, with each newly inherited method overriding any existing methods."
• #Perl: by order "...from as an ordered list. The compiler uses the first method it finds..."
• #Python: by order
• #Ruby: by order "...as rightmost depth first resolution."
• #Scala: by order "allows multiple instantiation of traits, which allows for multiple inheritance by adding a distinction between the class hierarchy and the trait hierarchy. A class can only inherit from a single class, but can mix-in as many traits as desired." This approach is the most similar to #Nile's; traits being qualifications.
• Tcl: by order "the order of specification in the class declaration affects the name resolution for members..."
Languages that allow only single inheritance, where a class can only derive from one base class, do not have the diamond problem.
Moreover, languages such as #Ada, Objective-C, #CSharp, #Delphi/Free #Pascal, Java, #Swift and PHP allow multiple-inheritance of interfaces (called protocols in Objective-C and Swift). Interfaces are like abstract base classes that specify method signatures without implementing any behavior.
When several interfaces declare the same method signature, as soon as that method is implemented (defined) anywhere in the inheritance chain, it overrides any implementation of that method in the chain above it (in its superclasses). Hence, at any given level in the inheritance chain, there can be at most one implementation of any method. Thus, single-inheritance method implementation does not exhibit the Diamond Problem even with multiple-inheritance of interfaces.
Data layout
- is how multidimensional arrays are stored in a linear storage such as RAM. It is critical for:
• correctly passing arrays between programs written in different programming languages
• performance when traversing an array because modern CPUs, due to caching, process sequential data more efficiently than non-sequential data
• contiguous access makes it possible to use SIMD instructions that operate on vectors of data
Row-major versus column-major order
The difference between the orders lies in which elements of an array are contiguous in memory. In a row-major order, the consecutive elements of a row reside next to each other, whereas the same holds true for consecutive elements of a column in a column-major order. While the terms allude to the rows and columns of a two-dimensional array, the orders can be generalized to arrays of any dimension.
Transposition
As exchanging the indices of an array is the essence of array transposition, an array stored as row-major but read as column-major (or vice versa) will appear transposed. As actually performing this rearrangement in memory is typically an expensive operation, some systems provide options to specify individual matrices as being stored transposed.
Languages support
• Row-major: #C/C++/Objective-C (for C-style arrays), PL/I, #Pascal, Speakeasy, SAS, and Rasdaman
• Column-major: #Fortran, #MATLAB, GNU Octave, S-Plus, #R, #Julia, and Scilab.
• Neither (for less dense arrays):
• Iliffe vectors: #Java, #Scala, #Swift. #Ruby, #Perl, #PHP, #JavaScript, Visual Basic .NET
• Lists of lists: #Python, Wolfram Language of Wolfram Mathematica
• Tables of tables: #Lua
- is how multidimensional arrays are stored in a linear storage such as RAM. It is critical for:
• correctly passing arrays between programs written in different programming languages
• performance when traversing an array because modern CPUs, due to caching, process sequential data more efficiently than non-sequential data
• contiguous access makes it possible to use SIMD instructions that operate on vectors of data
Row-major versus column-major order
The difference between the orders lies in which elements of an array are contiguous in memory. In a row-major order, the consecutive elements of a row reside next to each other, whereas the same holds true for consecutive elements of a column in a column-major order. While the terms allude to the rows and columns of a two-dimensional array, the orders can be generalized to arrays of any dimension.
Transposition
As exchanging the indices of an array is the essence of array transposition, an array stored as row-major but read as column-major (or vice versa) will appear transposed. As actually performing this rearrangement in memory is typically an expensive operation, some systems provide options to specify individual matrices as being stored transposed.
Languages support
• Row-major: #C/C++/Objective-C (for C-style arrays), PL/I, #Pascal, Speakeasy, SAS, and Rasdaman
• Column-major: #Fortran, #MATLAB, GNU Octave, S-Plus, #R, #Julia, and Scilab.
• Neither (for less dense arrays):
• Iliffe vectors: #Java, #Scala, #Swift. #Ruby, #Perl, #PHP, #JavaScript, Visual Basic .NET
• Lists of lists: #Python, Wolfram Language of Wolfram Mathematica
• Tables of tables: #Lua
#Java
The JVM
- is the detailed, formal specification for a 32-bit abstract machine. Abstract implies hardware and OS-independent and thus is interoperable across platform-dependent implementations. It operates on abstracte data types rather the native data types of any ISA:
• 32-bits types: integers, floats, and references are called primitives
• 64-bits types: long and double are supported but consume two units of storage
• smaller types: boolean, byte, short and char are extended to 32-bit ints
It loads code, verifies it, and executes it. It has instructions for:
• Load and store
• Arithmetic
• Type conversion
• Object creation and manipulation
• Operand stack management (push & pop)
• Control transfer (branching)
• Method invocation and return
• Throwing exceptions
• Monitor-based concurrency
The specification includes various dynamic features such as GC and thread management.
JDK
- is an software development kit for Java and consists of:
• a private stand-alone implementation of the JVM such as JRE's HotSpot
• the Java standard library, JCL
• an interpreter/loader (
• a compiler (
• an archiver (
• a documentation generator (Javadoc)
HotSpot
- relies on JIT; and divides the memory into generations:
• young generation: heap for short-lived objects
• old generation: heap for long-lived objects
• permanent generation: used for class definitions and associated metadata
JVM languages
Any language that can express a valid class file. The existing languages includes ports from other languages:
• JRuby (#Ruby)
• Jython (#Python)
And entirely new languages that compile to Java bytecode:
• Clojure
• Apache Groovy
• #Scala
• #Kotlin
JVM languages are compatible with each other i.e. libraries of one can be used with programs of another. A new feature will supports dynamically typed languages in the JVM, and is developed within the Da Vinci Machine project whose mission is to extend the JVM so that it supports languages other than Java.
The JVM
- is the detailed, formal specification for a 32-bit abstract machine. Abstract implies hardware and OS-independent and thus is interoperable across platform-dependent implementations. It operates on abstracte data types rather the native data types of any ISA:
• 32-bits types: integers, floats, and references are called primitives
• 64-bits types: long and double are supported but consume two units of storage
• smaller types: boolean, byte, short and char are extended to 32-bit ints
It loads code, verifies it, and executes it. It has instructions for:
• Load and store
• Arithmetic
• Type conversion
• Object creation and manipulation
• Operand stack management (push & pop)
• Control transfer (branching)
• Method invocation and return
• Throwing exceptions
• Monitor-based concurrency
The specification includes various dynamic features such as GC and thread management.
JDK
- is an software development kit for Java and consists of:
• a private stand-alone implementation of the JVM such as JRE's HotSpot
• the Java standard library, JCL
• an interpreter/loader (
java)• a compiler (
javac)• an archiver (
jar)• a documentation generator (Javadoc)
HotSpot
- relies on JIT; and divides the memory into generations:
• young generation: heap for short-lived objects
• old generation: heap for long-lived objects
• permanent generation: used for class definitions and associated metadata
JVM languages
Any language that can express a valid class file. The existing languages includes ports from other languages:
• JRuby (#Ruby)
• Jython (#Python)
And entirely new languages that compile to Java bytecode:
• Clojure
• Apache Groovy
• #Scala
• #Kotlin
JVM languages are compatible with each other i.e. libraries of one can be used with programs of another. A new feature will supports dynamically typed languages in the JVM, and is developed within the Da Vinci Machine project whose mission is to extend the JVM so that it supports languages other than Java.
The === operator
#Ruby
(1..5) === 3 # => true
(1..5) === 6 # => false
Integer === 42 # => true
Integer === 'fourtytwo' # => false
/ell/ === 'Hello' # => true
/ell/ === 'Foobar' # => false
#Ruby