Hacker News new | ask | show | jobs
by kenbot 4602 days ago
You ran with this "three complete type systems" line in the last thread, and it's still totally wrong.

ADTs/pattern matching are not "a complete type system". Structural types are not "a complete type system". Scala unifies the different concepts by expressing them through Java-style classes and inheritance.

Even if they were incompatible non-orthogonal type systems sitting side by side (they aren't), it is immensely useful to have both dynamic dispatch and ADTs/pattern matching in the toolset; they are often useful for different problems.

2 comments

> ADTs/pattern matching are not "a complete type system". Structural types are not "a complete type system"

Why not? Can you not write any program using either? Haskell uses just the former, and JS the latter (though without type safety).

> Scala unifies the different concepts by expressing them through Java-style classes and inheritance.

I think it "unifies" them only in the sense that the (single) compiler can compile all three. But case classes cannot be part of an inheritance hierarchy nor structural types (or inheritance types) be used as ADTs. The three certainly intersect, but they're not really unified.

> It is immensely useful to have both dynamic dispatch and ADTs/pattern matching in the toolset; they are often useful for different problems.

Obviously, and that is why some languages employ the one or the other. The question is, how useful is it (from a cost/benefit perspective) to have all three (plus macros!) in the same language? After all, while each has its benefits sometimes, they also overlap a lot, as most programs are about as easily implemented in all three. As I've said elsewhere, in language design, as in most things, one must choose. A pizza, a steak and ice-cream all have their place, but may lose much of their flavor if mixed into the same dish. In the JVM ecosystem we are lucky enough to have easy interoperability between languages. The JVM is a restaurant with a varied menu, and you can have a meal of several courses. The best way to go, IMO, is to pick one simple language you're comfortable with and use it for most tasks, and for those tasks that require specialized skills outside your chosen language's strengths – use another.

> Can you not write any program using either?

While you can make do with either, they have complementary strengths and weaknesses, which are useful in different situations. See "Expression Problem", and "Visitor Pattern".

> Why not?

"Single Dispatch Polymorphism" is a language feature. ADTs/pattern matching are a language feature. Subtyping is a type-system feature. "Structural Typing" is a type-system feature. Guaranteeing exhaustive pattern matching is a type-system feature. They are not "type systems", and different languages pick them and combine them a la carte.

> But case classes cannot be part of an inheritance hierarchy nor structural types (or inheritance types) be used as ADTs

Yes they can, and they do. You just can't extend case classes from other case classes. You can use any class as an ADT-like structure if you want, leaving the hierarchy open or closed, and defining pattern matching extractors as you please. It's all part of the same system; whether you call it an "ADT" or a "class hierarchy" is a design pattern thing more than a rigid systemic property.

> Obviously, and that is why some languages employ the one or the other

Er... that doesn't follow. What I said is that it's very useful having both together. If you don't think that's valuable, that's fine; Scala's not for you.

Can you write any program with only case classes and sealed traits? Yes; Haskell does it. Can you write any program with just structural types? Yes, JS does it. Can you write any program with just inheritance types? Yes, Java, C++ and C# do it. Ergo, Scala has three type systems, and it doesn't matter whether you make them appear as one.

> It's all part of the same system; whether you call it an "ADT" or a "class hierarchy" is a design pattern thing more than a rigid systemic property.

Obviously it's part of the same system, which just happens to be a superset of three type systems. A type system is not how its implemented but what it does.

You can write any program with a Turing machine. That's a silly definition of a type system. I've never heard this usage anywhere else.
> You ran with this "three complete type systems" line in the last thread,

Verbatim even.. a copy paste :p

Better: I have a script that reposts previous comments where relevant.
Ah, intelligent spam.