(no title)
creativeCak3 | 4 years ago
Again, please correct me if I'm wrong since I've been industry for barely 2 years: back in school functional programming looked cool, but when I entered industry(and even in my exploration through personal/OSS projects), I have found it to be nothing more for the most part than a cool toy to play with. I can somewhat see the benefit when it comes to parallelizing Big Data, but that seems to be a very special case.
Again if I'm just being ignorant, please educate me :)
lhorie|4 years ago
Promises and the async/await syntax sugar on top of them are another JS construct that borrow quite a bit from functional literature.
creativeCak3|4 years ago
bojo|4 years ago
Purity helps quite a bit with narrowing down bugs; you simply check that your inputs and outputs are correct without having to ever worry about state. We use effects to narrow the types of functions that can be legally called inside specific domain logic, which also narrows down a large class of bugs that we've seen creep into other code bases.
However, it's not a magic bullet. Time to getting someone unfamiliar with Haskell up to speed can be costly. Discovering time-saving idioms in a sea of bad documentation is frustrating. Smaller ecosystem than other popular languages means less blogs, and in Haskell's particular case the information seems either too low or high level with no in between.
Still, with 250k of production lines running as stable as can be, we have no complaints.
chriswarbo|4 years ago
Unfortunately it's very tempting to intorduce side-effects 'just this once', which can make those techniques less useful, and takes some discipline to avoid. For example, in Scala it's easier to just throw an exception instead of wrapping results in a 'Try' type; or likewise for null/'Option'; etc. mostly since those results then require map/mapN/flatMap/traverse/etc. to handle, rather than giving us values directly.
However, I think it's usually worth the effort. For example, those map/mapN/flatMap/traverse functions are essentially 'setting policies' for how effects should interact; whilst the 'core logic' can remain completely agnostic.
As a very simple example, if we have 'l: List[A]' and 'f: A => Option[B]', we can combine these in multiple ways, e.g.
We can replace 'Option' with 'Future' to talk about concurrency rather than emptiness. We can replace 'Option' with 'Try' to talk about exceptions rather than emptiness. All of those expressions remain identical.More esoterically, we can replace 'Option[T]' with 'Reader[X, T]' for dependency injection of an 'X'; etc.
I've used these techniques commercially in PHP, Python, Javascript, Haskell and Scala (and academically in Racket, StandardML, Coq, Idris, and Agda too)
exdsq|4 years ago
yakshaving_jgt|4 years ago