4 ms·
Maybe I'm just missing something, but I'm not on board with the definitions they take in the introduction. > the essence of object-oriented programming is prog
by abeppu 2y ago
Maybe I'm just missing something, but I'm not on board with the definitions they take in the introduction.
> the essence of object-oriented programming is programming against interfaces, which correspond to the type theoretic concept of codata and copattern matching
They then use the classic codata example of a Stream, with a head and a tail. The Stream they declare looks a lot more like the version of that concept in functional languages than the version of it in an OO one, but clearly it exists in both paradigms.
https://www.cs.cmu.edu/~15150/resources/libraries/stream.pdf https://www.cs.cmu.edu/~15150/resources/libraries/stream.pdf
https://hackage.haskell.org/package/Stream-0.4.7.2/docs/Data-Stream.html https://hackage.haskell.org/package/Stream-0.4.7.2/docs/Data...
https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/stream/Stream.html https://docs.oracle.com/en/java/javase/21/docs/api/java.base...
- Tainnor 2y agoTheir definitions of OOP and FP are rather restrictive - it's basically FP = ADTs (data) and OOP = interfaces (codata). Many modern languages support both (e.g. Haskell has typeclasses, Java has records and sealed interfaces).
- Twisol 2y agoI think the key ingredient you're looking for is mutability. If you take advantage of the ability to implicitly modify state, your declared interfaces reduce in size because you don't need to model the threading of state through the interface. Since mutability means that your method signatures are less restrictive then they appear to be, it makes sense that this research (focusing on dependent types, and especially on dependently-typed proofs) would prefer a setting without implicit mutability. (Mutation is orthogonal to OOP vs. FP, anyway -- you can have pure OOP interfaces and also mutable FP interfaces.) The Java stream interface also has a lot of methods that can technically be implemented in terms of other methods on the interface, but are present so that implementers can provide more efficient implementations depending on the capabilities of their model of streams. It makes sense that the present research would only consider the bare essentials of streams, and not things that could be layered on top at the cost of some optimization opportunities. As a Java programmer, the essence of an OOP stream seems to be captured by the following interface: interface Stream<T> { T next(); } If we make mutation explicit, this evolves into: interface Stream<T> { Pair<T, Stream<T>> next(); } And then we can split this into two methods, providing each of the two components of the original `Pair`: interface Stream<T> { T head(); Stream<T> tail(); } This is exactly what the paper shows on page 2, up to syntactic differences (like explicit type parameters to the methods).