Hacker News new | ask | show | jobs
by michaelochurch 4034 days ago
I don't consider Java to be statically typed. Sure, there's some compile-time type checking, but OOP is naturally dynamically typed. This is why you end up subverting the type system (I believe it's called "POJO") all over the place when you write Java.

To be pedantic about it, Java has two type systems. It has a bottom-up, mostly static, ALGOL-inspired type system with primitives and arrays (e.g. int, char[], double[][]) and a top-down, semi-dynamic type system for object types.

Maybe, but then the objective isn't so much 'use a static type system' as 'make Haskell palatable to a decent percentage of programmers'. I'm not saying it's impossible to do that, just that it's a different challenge and needs to be understood for what it is.

I agree. What would you suggest?

The issue, I think, that Haskell has is not that the language is hard to use, but that the type signatures can be anywhere from obvious to counterintuitive and, to a beginner, horrifying. The issue is that the "best" (most general, most mathematically accurate) type signature isn't always the one that gels with what we want from it.

An example would be the Lens type signature. It takes some on-paper, figure-it-out work to understand why this is the right type signature. It's this Rank-2 beast:

    type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
When most people would find it more intuitive to have something like this:

    type Lensish s t a b = L {get :: s -> a, set :: s -> b -> t}
Sometimes in Haskell we go for full generality and mathematical correctness, which is great, but also makes the language harder to understand.

Then there are the names. Personally, I don't find "monad" or "functor" to be that bad. They're new concepts that must be learned, but they're a lot easier (and more useful!) than OOP's 23 design patterns, most of which are horrible.

2 comments

"Personally, I don't find "monad" or "functor" to be that bad."

I actually think there are two big wins there, one of which is somewhat overlooked.

First, it's great to be able to be able to read math papers and see how it touches your programming with less translation.

Second, and I think less noticed, it changes the form of some arguments. If we called Monoid "Appendable", then we would have to consider whether a new and different thing jived with our notion of "append". These arguments still happen in Haskell ("is container a good way to think of functors?") but it's recognized that what you're talking about is pedagogical. The question of whether something is a valid instance of Monoid or Functor or Monad is simple: does it abide by the laws? And since those laws are clear, we know what we can rely on, and if someone uses our code with an invalid instance that's their own fault.

POJO just means a class that doesn't extend a framework class or have framework annotations. The opposite of a POJO would be something like an Enterprise Java Bean or a Persistence Entity--which are configured via XML to subvert the type system as you put it.

I'm fairly new to Haskell and the type system is still a little scary to me, but learning it feels like a much better use of my time than memorizing the GoF patterns of Java.