4 ms·
Because side effects cause bugs and make code harder to reason about. The ways we avoid side effects can be inefficient. Tools such as immutable data types. In
by xupybd 4y ago
Because side effects cause bugs and make code harder to reason about.
The ways we avoid side effects can be inefficient. Tools such as immutable data types. In the past it wasn't really worth the performance trade off. Now days we're often running in environments where raw speed is not achieved on single core performance but over distributed systems. All of a sudden immutability seems to make more sense. Not only does it help with removing side effects but it also helps parallelize workflows.
I think that's why its happening now.
I've recently switched to using F# where I can and it's been a huge win. The bug count is way down, I can refactor with confidence, and My code is more readable.
The learning curve was hard. I still am not sure I truly understand what a Monad is but I can see the pattern and use it as a tool. It feels more constrained at first but it brings order to chaos.
- bboygravity 4y agoCan it be summarized with: multi-threading in non-functional languages is the most confusing and most time consuming thing?
- ActorNightly 4y agoIts neither time consuming or confusing if you understand the concept of mutex, which is only one thread can access a resource at any given time. Anything beyond that is irrelevant for 99% of the use cases for multiple threading. And furthermore, its highly likely that your project is better suited to async programming instead.
- xupybd 4y agoNot exactly. I wasn't just talking about multi threaded systems but multi machine systems too. Where there is no shared memory. If you need to serialize your data to send out to a cluster for processing you've already constrained yourself to immutable data.
- badpun 4y agoMost webapps are actually embarassingly parallel (https://en.wikipedia.org/wiki/Embarrassingly_parallel https://en.wikipedia.org/wiki/Embarrassingly_parallel) and require little synchronisation. Most of the hard synchronisation problems are solved for you in the DB (at least if you've chosen a good one).
- ActorNightly 4y ago>Because side effects cause bugs and make code harder to reason about. Not really. All functional programming does is basically force you to shoehorn your computation into defined pipelines. For some cases this works, for others, you are doing a lot more work than necessary compared to imperative programming, and the cycle of you developing said code is usually longer than writing the code imperatively, and then debugging. In general if you look at the history of tooling, there has been a certain pattern within languages/tools where some description alludes to programmers being incompetent. For example, in the case of functional programming, your statement above essentially means "As an incompetent programmer, you may write code that sets a variables value unexpectedly, which is turn used by some other thread, which will create a bug. So you need functional programming to avoid making this mistake" History has shown that this doesn't work in practice, because you create arbitrary boundaries, friction, and inefficiencies that slows down development by a large amount. There is a reason why Python is top language (only second to Javascript, because of web stuff) on github, and as far as it goes, its a free-for-all in terms of how you code.
- xupybd 4y ago> "As an incompetent programmer, you may write code that sets a variables value unexpectedly, which is turn used by some other thread, which will create a bug. So you need functional programming to avoid making this mistake" Ouch, don't hold back tell us what you really think. But that is not the entire meaning. If I have a function that has side effects such as a typical OO setter function it may change the state of the object in ways that are encapsulated from the consumer of the function. If someone has to come in years later and change that function it's not always obvious what state changes the function is required to make in order for the other functions in the class to operate. So we have regression tests to ensure any misunderstandings are caught. Pure functions take in state as data. So we lose the encapsulation but gain clarity. You are correct however, if we programmers could only do our jobs competently we'd have no need of such things. Personally I like to setup tools that catch my mistakes, because I make lots of them.
- sweezyjeezy 4y ago> You are correct however, if we programmers could only do our jobs competently we'd have no need of such things. That's the thing though - comparing "good FP" vs "good OO" is a false equivalence, in reality you will need to deal with other people's code, or yourself when you didn't know better. Bad OO << bad FP, that's basically all I need to make my mind up!
- YourDadVPN 4y ago> I still am not sure I truly understand what a Monad is but I can see the pattern and use it as a tool. It feels more constrained at first but it brings order to chaos. Ha, I learned Haskell over 6 years ago and I still can't explain what a monad is other than in programming terms. It's a container which defines two operations: put something inside the container (Haskell's "return" keyword), and chain two operations on the container together (Haskell's >>= operator).
- noloblo 4y agoPls watch haskell monad https://youtu.be/_Gk_lwhJMzk https://youtu.be/_Gk_lwhJMzk And then >>= https://youtu.be/ZhuHCtR3xq8 https://youtu.be/ZhuHCtR3xq8 And then >>= https://youtu.be/t1e8gqXLbsU https://youtu.be/t1e8gqXLbsU
- Laaas 4y agoThat's because there's not much more to it. The Monad tutorial problem is entirely due to academically oriented people attempting to explain monads through category theory etc.
- noloblo 4y agoAs far as haskell Declarative by nature and get parallelism and concurrency from the world class ghc runtime ; avoid call back style js, locks mutex, semaphores Type classes Type inference Io capturing the messy real world of state, side effects, io, async concurrency, parallelism Pure functions or expressions as opposed to imperative Statements Pattern matching Monads >>= Monadic transformers Maybe Monad equivalent to option type in rust ocaml to avoid null (f# might still have nulls) Hackage cabal stack and world class libraries Green threads like erlang Otp elixir Cloud haskell is haskell's answer to erlang Lazy default evaluation with strict constraints if needed Perform unsafeio but explicitly Immutable by default Stm software transactional memory when need mutations that compose well Heavily optimized ghc compiler with fast gc Type safety Compilers giving errors on type mismatches : trusting the compiler and refactoring with abandon - if it compiles it works Haskell native compiled code can be Very fast as in golang / ocaml Tldr haskell makes easy things hard with a steep learning curve and hard things easy as composing is way more useful than Oops. Theoretically, functional programs should: have fewer bugs, be easier to optimize for performance, allow you to add features more quickly, achieve the same outcome with less effort, require less time to get familiarized with a new codebase, etc. As venerable prof Joe armstrong says you need haskell erlang for fp ; you need c for high performance ; you really don't need cpp Java python c# Most of these points apply to varying degrees to common lisp racket erlang elixir rust
- badpun 4y ago> Most of these points apply to varying degrees to common lisp racket erlang elixir rust ... and Scala, with libraries explicitly apeing Haskel, such as Cats.