Hacker News new | ask | show | jobs
by gelisam 3651 days ago
> Does this mean I’m a static typing zealot now ?

That part made me chuckle, because it made me realize that a typing zealot is exactly what I've become! I used to be a huge fan of Ruby and I was using it for everything, and now 10 years later I'm a huge fan of Haskell instead, I give talks about how JavaScript is horribly error-prone and how Elm is so much better because not only is it statically-typed, it's also purely-functional, and yadi-yadi-ya.

The transition occurred so smoothly that I didn't notice it. Beware! You might not be a zealot now, but if you continue on this path, you might unintentionally become one too :)

2 comments

Whatever Scala devotees may believe, I think FP and OOP are irreconcilable opposites which means if you really get into FP you're going to hate doing what the industry demands of you in your day job, ie. OOP. Maybe FP will one day become the dominant paradigm but until then treat it like alcohol - too much and you cease to function in the "real" world. I exposed myself to Rich Hickey's Sermons From The Hammock a few years ago and Clojure just blew my mind. Since then I get a churning feeling in the stomach when I have to dealt with OOP, ie. Ruby, PHP, Python. The effects are irreversible so beware - immutable data mixed with pure functions is a potent drug.
> Whatever Scala devotees may believe [...]

It's not just Scala devotees. You should read [this post][1] by Alan Kay (Turing Award winner, designer of Smalltalk). He arrives at a conclusion that might surprise you:

> I think of "objects" and "functions" as being complementary ideas and not at odds at all.

Largely what you may be referring to is the idea of purity and mutation being at odds, but these are orthogonal from the ideas of OOP and FP.

A very interesting read.

[1]: https://news.ycombinator.com/item?id=11808551

It might be the particular OOP languages you're used to. Ruby, PHP and Python all have pretty strong cultures of relying on mutation and side effects. Part of this might be that the languages are so focused on dynamicism that you really have to go out of your way to even suggest that a type should be immutable. And even then it's only a matter of time until someone mucks it up by applying a mutable mixin to the type.

In other languages, though, it's perfectly possible to create immutable classes that can only be interacted with using pure functions. You could argue that it's questionable that these do anything you can't do better with records and algebraic data types, and there's something to that. But there's also something to taking the pragmatic approach and not letting the (presumably) remote odds of your employer adopting a niche language prevent you from writing better code.

FP and OOP are totally not irreconcilable. Most modern languages offer both, including the most highly used dynamic languages. Javascript really cracked this nut with its function expressions. Scala's main contribution here is applying static typing to that mixture in a largely coherent way.
As soon as you create a class you're binding data and methods inside a black box. It's the very antithesis of FP. Of course you can freeze and fiddle with your class to make it "more functional" but it doesn't wash because in FP functions are supposed to be "free", ie. unboxed.
I wouldn't necessarily agree with this. Many functional programmers actually prefer some of the advantages of black boxes. Even methods as a calling interface vs functions are more a stylistic difference (when you aren't factoring in subtype polymorphism). OO languages tend to have the convention of not keeping effectful operations in methods referentially transparent (with effectful values), but there's nothing inherent to the idea of OO that says this must be the case. Scala could just as easily have something like haskell's IORefs instead of vars and make use of an IO monad to achieve a similar effect.

I'd argue the bigger difference between the two styles is with methods of polymorphism, but even functional programmers in different camps probably don't agree on the reasons for why they prefer not to have subtype polymorphism.

Your opinions about encapsulation probably have more to do with your preferences wrt typing discipline. Functional programmers who prefer static types often view black boxes as an asset. In fact black boxes form the basis of the free theorems, which can provide some nice assurances about the behavior of code that has few assumptions about the data it receives: https://bartoszmilewski.com/2014/09/22/parametricity-money-f...

Similarly, data without exposed constructors can be used to enforce strong invariants about code using techniques like smart constructors: https://wiki.haskell.org/Smart_constructors

Black boxed data also conveys advantages for library maintainers. It makes it much easier to change implementation details, because you're only required to preserve the semantics of functions operating over data rather than its exact innards. Not doing this for the String data type in haskell is arguably the largest reason why it won't be phased out to the superior Text type: http://dev.stephendiehl.com/hask/#string

As you said, this is slowly happening to me. I love being able to prototype systems in languages like python and matlab, but at the same time it feels like building on sand, especially when other developers get involved.

Recently while writing some matlab found a great example of the sort of trouble a decent type checking system will save you. The predict method takes a machine learning model, and applies it to some data. The output however, is up to the model, and not all models return the same data type (e.g. column vector of doubles, or cell array of strings), making it a pain in the butt to do any abstraction over models.

I am excited for languages like lbstanza that let you have your cake and eat it too.