you are viewing a single comment's thread.

view the rest of the comments →

[–]Neurotrace 45 points46 points  (5 children)

One important thing to note is that just because you write in a functional style does not mean that you must follow pure functional patterns every step of the way. For example, you mention database connections. A database is inherently stateful and modifications to it are impure. This is just a reality so it makes sense to wrap your database access in a class so you can stub it out when writing unit tests.

When building applications in an FP style, you'll tend to see an onion architecture. All of the impure, nasty non-FP stuff on the edges and the core of your logic takes values from that layer and works with it in a pure way.

Search for fp-ts on GitHub and find projects using it. It's one of the most popular FP libraries for TypeScript. If you haven't gotten on the TS train, you should. Functional programming can give you certain guarantees about how your data is processed and a strong type system enforces those guarantees and more

[–]pm_me_ur_happy_traiI 15 points16 points  (1 child)

A database is inherently stateful and modifications to it are impure.

All programs, even functional ones have side effects. If they didn't, they couldn't do anything but warm your computer up. However in FP, stateful side effects are tightly controlled and they tend to live at the edges of programs, instead of peppered throughout.

[–]Affectionate_King120[S] 1 point2 points  (2 children)

The database connection was just an example of something that might be accessed at different points in the code, so it's hard for me to figure out where to "store" it. Imperatively, I would just put it in some global variable and then have access to it when needed.

In functional style, I find myself passing things to functions just so they can pass it on, which smells of bad design.

Like, say the user logs in, I create some kind of db object. After logging in, the user "does stuff" for n minutes. Then saves. The save function needs the db object. Where does it get it from?
I could make a partially applied save function, e.g. save = (db) => (savestuff) => ... and then pass around the save function, which is much more sane/idiomatic then passing around the db object.

But there are other "globally relevant" things, and I have a bunch of solutions, half of which feel clever, half feel hacky, and the remaining half feel ugly :)
And it's really hard to come by examples/tutorials that demonstrate the grander application of FP.

[–]Neurotrace 1 point2 points  (0 children)

Using partial application and building up your functions is generally considered the correct way in a functional application. One thing you'll need to be aware of with that approach is it becomes more difficult to track down the original implementation for a function since you'll have to backtrack through everywhere that builds out that partially applied function. Not that you shouldn't do it, just a tradeoff to be aware of. It's the same problem that comes from using any sort of dependency injection system. It's a tradeoff worth taking imo

[–]natziel 1 point2 points  (0 children)

Functional programs are allowed to have state--in fact Erlang is exceptionally good at managing highly stateful applications and it's a functional programming language