4 ms·
For the most simple CRUD apps, there is almost zero business logic. So your whole application is basically IO. What's the point of Haskell's IO type when every
by ragnese 6y ago
For the most simple CRUD apps, there is almost zero business logic. So your whole application is basically IO. What's the point of Haskell's IO type when every function will have to be IO?
For the less simple apps, IO can be hidden behind interfaces for complex business logic. Here's an imaginary example:
def getPriceForShoppingCart(product: Product, user: User, getDiscount: (User) -> Percentage): Price {
if (user.isPremium) {
product.price * getDiscount(user)
} else {
product.price
}
}
How do we put the IO on the edges? Does this function just disappear and we have an `if` statement in our impure outer shell? That smells like business logic in the impure shell to me. Do we go ahead and call `getDiscount` in the outer shell and pass in the discount to the function? That also sucks because what if we made that trip to the database when we didn't need to (because the user is not a premium user)?
I feel like every time I try to be religious about IO at the edges and not using impure dependency injection tricks, I end up running into a bunch of cases like this.
On the other hand, if I stand back and look at a function like this objectively... It's easy to understand, it's still quite easily testable. What's the problem?
- marcosdumay 6y agoThis function is receiving a product and a user as arguments. Why would it do any IO? Anyway, CRUD does really not lead to clear "is IO"/"isn't IO" boundaries, and the business logic isn't a good candidate for separating from IO into a pure core. Instead, it is a great candidate for separating into a "with business data" context that is neither simple IO nor pure. On the implementation of that "with business data" context you will find plenty of opportunities to push IO to the boundaries of complex code that will become pure. But your intuition is correct, what you are missing is that the code can be broken on more dimensions than the ones you are assuming.
- dragonwriter 6y ago> For the most simple CRUD apps, there is almost zero business logic. Sure, which is why there is no reason to code them specifically at all as unique applications. Instead, the domain isn't the business domain of a particular application but far more general, and then you code something like PostgREST in Haskell where the domain is mapping between database and API calls, and solve the problem generally, and define specific applications just with database schemas. “Domain logic” is only “business logic” when you've decided you need a bespoke app built for a specific business problem, which makes sense when you have a complex business problem, but is simply wasteful when you have a problem for which a general solution already exists. It's like asking who is the best designer go go to for a one-off custom car for perfectly average daily commuting use: you've chosen from the outset an inefficient solution to your problem.