Prescriptivism and Descriptivism

A long time ago I was watching another version of Romeu Moura's Prescriptivism vs Descriptivism.

The idea is illustrated by the point of view you can have on a "list":

  • Prescriptive: as things should be (as in a specification)
  • Descriptive: as things are (or at least, how things are observed)

Sometimes, in Haskell tutorials you have many references to Category Theory, they are often compared to Design Patterns and beginners report that they are way harder to grasp.

The thing is, whenever your define some types, you start by defining the datatype then you define the type class to characterize its property:

data AvlTree a = Node (AvlTree a) a (AvlTree a) | Leaf

instance Ord a => Semigroup (AvlTree a) where
  (<>) = mergeAndBalance

instance Monoid (AvlTree a) where
  mempty = Leaf

We can say that Category Theory is descriptive.

On another hand, when it comes to object-oriented programming, Design Patterns are the way to go.

The thing is, most of the time, they are implemented to solve a technical issue, they are implemented to be implemented.

Usually, they are named in order to reflect that:

interface IOrderFactory {
    Order startOrder(Item firstItem);
}

or tagged:

@Factory
interface IOrderCreator {
    Order startOrder(Item firstItem);
}

Design Patterns in (OOP at least) are prescriptive.

Design Patterns exist in OOP to solve a lack of Higher-order constructions.

Another form of descriptive constructions are duck typing (at runtime) and structural typing (at compile time).

The duck typing in ruby:

class Glass
    def refill
      # ...
    end
end

class Car
    def refill
      # ...
    end
end

def gas_station(x)
  x.refill
end

You can refill your Glass in a gas station, but petrol is only good for some cars.

The structural typing in go:

type Glass struct {}
type Car struct {}

type Refillable interface {
    Refill()
}
func (g Glass) Refill() {}
func (c Car) Refill() {}

func GasStation(x Refillable) {
  x.Refill()
}