This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Composition, delegation and interfaces -- a 20K ft critique of Noop

No replies
Meredith Gregory
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Dear Programmers,
Someone just asked me to give my opinion on Noop's composition proposal. It reminds me a little bit of Self which found its way into JavaScript. It also reminds me a little of Haskell's type classes. In general, movement away from inheritance is good. The proposal, however, feels a bit like looking for the lost quarter where the light is good, rather than where you lost it. Before considering delegation machinery, let's consider the value of an interface. How many interfaces are there? One way to see that is just to consider all the sub interfaces of a single interface with n methods on it. Hmmm... that's 2^n interfaces. That's a lot. Does that give us any confidence that any one way of carving up functionality via interfaces is going to be sane? Further, in practice, do we see random distribution through this very large space?
What we see over and over again in practice is that the answer to these questions is 'no!'. That means that there is something that binds a collection of methods together. What might that something be? One place to look is mathematics. Which maths should we look at? The maths of category has been very fruitful both in explaining existing functional programming techniques and -- perhaps more importantly -- suggesting ways to improve them as well as wholly new techniques. What we find in category theory is that it is natural to collect maps (read functions) together. A good example of such a beast is a monad. A monad -- viewed categorically -- is 
  • a map, T, taking types to new types and functions on those types to new functions. Let's call the universe of types and functions expressible in our model of computation (as proscribed by our programming language), C. Then T : C -> C.
  • a higher order map, unit. Just like T takes C to C, we can understand a "noop" like map that takes C to C, call it Id. Then unit : Id -> T. We intuitively think about it as putting basic types inside the container T, but it's really a higher order map.
  • another higher order map, mult : T^2 -> T. We talk about it as a kind of flattening (and in Scala it's called flatMap), but it's a higher order map.
Now, one is not finished spelling out a monad when giving this collection of maps. One must also show that they satisfy certain constraints.
  • T is functorial, meaning T g f = T(g) T(f)
  • unit and mult are natural transformations, look up the meaning because unpacking it here would take to long
  • mult( mult T ) = mult( T mult )
  • mult( unit T ) = mult( T unit  )
This set of constraints must go with the monad. This example provides a little more detail in terms of what binds a group of maps together, and hence of what might replace the notion of interface and explain what we see in practice. Good programmers invariably pick out just a few factorizations of possible interfaces -- from the giant sea of factorizations (read different ways to carve up the functionality). The reason -- i submit -- is because in their minds there are some constraints they know or at least intuit must hold -- but they have no good way at the language level to express those constraints. A really practical language should help the programmer by providing a way express and check the constraints that hold amongst the maps in an interface.
i submit that this idea is not the same as "design by contract". i am not proposing an Eiffel-like mechanism. Again, taking a functional approach to computation via category theory leads one towards modeling interfaces as categorical "situations" like monads, comonads, distribution laws, etc. This means that a large number of the constraints come down to 
  • functoriality
  • naturality
  • coherence
Language support for this approach might include keywords for these kinds of assertions. It is a gnarly beast to offer automatic and/or compiler support for checking general constraints. Even this limited family of constraints that i'm proposing can generate some very difficult computations, with very bad complexity. However, for those situations where a general purpose solution to check assertions of functoriality, naturality and coherence are infeasible, one can use these hints to generate tests to probe for possible failures. This idea follows the in the same spirit of replacing proof with proof-checking.

Of course, this is not the only way to go. i've yet to be convinced that category theory offers a good account of concurrency. Specifically, categorical composition does not line up well with concurrent composition. So, interfaces organized around types for concurrency is also something to consider. In this case, one might find a natural beginning in interfaces in which -- roughly speaking -- the methods constitute the tokens of a formal language the constructors of which are given by the types for concurrency paradigm.

Best wishes,
--greg

On Thu, Sep 17, 2009 at 11:14 AM, Charles F. Munat <charles [at] munat [dot] com> wrote:
http://code.google.com/p/noop/wiki/ProposalForComposition



--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117

+1 206.650.3740

http://biosimilarity.blogspot.com



--
L.G. Meredith
Managing Partner
Biosimilarity LLC
1219 NW 83rd St
Seattle, WA 98117

+1 206.650.3740

http://biosimilarity.blogspot.com

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland