4 ms·
I belive database operations are considered a side-effect, so how would you propose I do away with those?
by edvinbesic 11y ago
I belive database operations are considered a side-effect, so how would you propose I do away with those?
- Retra 11y agoDatabase operations are just state transformers, which are pure functions. It is the state you have to worry about, and you can wrap that state in a number of FP constructs.
- edvinbesic 11y agoNot trying to be snarky, but what is the difference between a state-transformer and a general side-effect. The book in question gives the following explanation for what a side-effect is: "We'll be referring to effect as anything that occurs in our computation besides the calculation of a result." This is in chapter 3, and they provide the following list for what is a possible side-effect: - changing the file system - inserting a record into a database - making an http call - mutations - printing to the screen / logging - obtaining user input - querying the DOM - accessing system state With that in mind, there is not much I can do in my code and have a functional app without side-effects.
- codygman 11y ago> With that in mind, there is not much I can do in my code and have a functional app without side-effects. Not quite. Let's take one of those side effects as an example... say accessing system state. You probably aren't just accessing system state. You probably want to update it in some way right? Your function to update it could easily be pure. Take obtaining user input for example. Getting the user input is usually the most boring part of the program isn't it? The majority of what you do with that user input could very likely be pure functions.
- Lazare 11y agoYou're sort of coming at this backwards. What you want to avoid is side-effects. One class of side-effect would be database operations. So let's imagine you have this code: let products = [{id: 1, price: 10.12, desc: 'foo'}, {id: 2, price: 5, desc: 'bar'}]; for (i = 0; i < products.length; i++) { products[i] = formatPrice(products[i]); } console.log(products); Looks good, right? I mean, presumably formatPrice just, I dunno, turns prices from numbers into strings like "$5.00", or whatever. But what if formatPrice looked like this? function formatPrice(product) { product.desc = ''; saveToDatabase(product); product.price = '$' + product.price.toString(); return product; } There might be some reason why that's the exact functionality you want, but it's terrible practice to write; your price formatting code is performing database operations, which are side effects. Don't do that. :) What you want is to chain together a number of simple functions. And sure, one of them could even be "saveToDatabase". That's fine. What's not fine is having some random function, somewhere, randomly mutating your database. If you think FP requires you not to use a database, you've badly misunderstood FP. What it's asking is for you to be explicit about what you're doing. Pure functions are easy to reason about; global variables are hard. Database operations are especially hard to reason about, which is why you want them locked away safely at the start and end of your processing chain, and not just as random side effects of otherwise unrelated code.
- codygman 11y agoYou don't do away with them, you differentiate between side effectful functions and pure functions. One way to do this is tag them with the type IO. This would be a great pain if there weren't helpful ways (see Monad, Functor, and Applicative) to apply pure functions to them. You also get the benefit that those side effects have a set of laws to govern their behavior in failure cases.