[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: "static" declaration

Anton van Straaten writes:
> The design of a properly interface-oriented set of Java classes can
> be a significant improvement over similar classes in a
> dynamically-typed OO language.  Support for multiple explicit
> interfaces on a class allows for decoupling and factoring of designs
> in ways that make a great deal of sense, but often aren't practical
> to maintain in dynamically typed languages.

The big limitation with Java interfaces, in my experience, is that you
have to declare them up-front: there's no way of adding new interfaces
to existing classes. The reason this hurts so much is that library
users have their own interfaces, and it's reasonable for them to want
your classes to play nicely with them. So to retrofit your classes,
they either need to write lots of boilerplate adaptor classes, or need
to subclass them to add the new methods for the interface. Neither is
really all that clean a solution. (Note that you and they can be the
same person, if he extends a program he wrote!)

Haskell has a solution to this problem that feels really clean. There,
they call interfaces "typeclasses". You declare them like this

  class Eq a where
    (==) :: a -> a -> Bool
    (/=) :: a -> a -> Bool

This says that any type 'a' that wants to support the Eq typeclass,
has to have two methods (==) and (/=), each of which has the signature
'a -> a -> Bool'. (Don't get confused by the keyword 'class': this
doesn't define a new type, but rather an interface that types can
choose to support.)

Then, you can add particular types to the type class with instance

  instance Eq Integer where
    x == y   = integerEq x y       
    x /= y   = not (integerEq x y)  
  instance Eq Float where
    x == y   = floatEq x y
    x /= y   = not (floatEq x y)

This declaration adds Integer to the Eq typeclass, and describes how
it implements the methods in the interface. The neat thing is that you
declare instances *after* both the typeclass and the types were
defined. So there's no need to proliferate types just to satisfy
interface requirements. So your program can grow in a much more
organic fashion, since it makes refactoring much easier to do.

Neel Krishnaswami