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()
}