I think I am still using OOP way in haskell

Now I hate myself.
So basically, I am creating some widget which should not be complicated. It just involves some concurrency, and quite a bit of mutability.
In the end, I found myself looking into message passing. Through MVar, Chan, etc.
Then, I realized… I am working out where to put ownership of certain data, channel, and behavior.

Now this comes to the classic notion of OOP - message passing with some ownership involved.
It even seems like I am grouping data and behavior together!
Could you help me out from this?

1 Like

Don’t hate yourself!

It’s very common to approach “widgets” in an OOP way. There’s a few “functional” ways too but they all have pro and cons.

Can you give us more details about what you are trying to do? What have you tried? Why you didn’t like it?

2 Likes

I don’t think there is anything wrong with grouping data and behaviour together - I do this all the time it’s just inside modules instead of classes :wink:

For the mutation part: it’s often ok to write functions that mutate the state by returning a new state instead - this way you can be pure for a long time and probably push the mutation part out of your modules.

For the parts where you need it (at some point you have to take care of keeping the state) I tend to start with the Handle pattern

1 Like

Thank you for reassuring me! I guess widget case is more admissable to OOP approach.
I am working on a widget which actively updates and displays opened windows.
Turns out managing those variables is quite harder than expected.

Whew, so it is fine to group data and behavior (inside a module).
The Handle pattern sounds pretty OOP to me. Is it fine to use the pattern?
(In my case, state is often unavoidable because states are constantly in need for rendering)

FP / Haskell is not anti-OOP or something of this sort - as far as I am concerned there is no style-police yet.

Sure using some free-monad, effect-system, mtl-approach, etc. might be cooler (you can adjust your cool-factor to your liking - probably Polysemy or fused-effects is the coolest(?) right now? Who knows :man_shrugging:

But really just writing IO a, simple stuff like this handle-pattern etc. are fine - I mean really: it’s fine - you don’t need to get familiar with all this advanced stuff in order to have some productive fun with Haskell

2 Likes

Oh, I was mistaken - I thought FP is hard antithesis of OOP!
Thank you, now I would not get guilty even though my code looks quite OOP-ish!

It’s hard to give specific advice without first reviewing the code and problem domain you are working with, but with that said, are you using STM? It also sounds like maybe a database (or some durable/shared state storage) would be reasonable, depending on where you draw the lines in your system.

As I mentioned above, I am creating UI for showing which windows are currently open in the system. It operates in local machine, and the states are simply UI states, so I doubt redirecting to DB would help.
STM is simply used for state in TVar to achieve access without having to worry about deadlock.

OOP or not, everything is fair until you start having issues with composition. Then you’ll have to think.

If using stateful objects/actors bothers you, try some FRP formulations for your widgets. But it isn’t a panacea either, so don’t rush it, try before you buy lock yourself in.

3 Likes

Thanks for insightful comments!

By the way, while I overcame the fear of OOP-ization, I am having problem with potential deadlock issue.
Also, how do I draw a graphical diagram of the components so that I can spot most things at a glance?

DOT/graphiz might help?

There is stack dot - Dependency visualization - The Haskell Tool Stack - but that’s more for packages than your internals.

Sounds like a neat feature to be added though…

1 Like

Thank you for suggestions! I’ll look them up.

I recommend having a look at registry (disclaimer: author here) if you start having lots of “handles” (I just call them “components”) depending on each other: GitHub - etorreborre/registry: Components as records of functions for Haskell. That library gives you a type-driven way to assemble components, a bit like type classes, but more flexible since it is easy to override a dependency when writing tests with just one line of code.

I’m happy to help if you have difficulties getting started.

3 Likes

Perhaps you’ll be happier with using Ocaml - functional and OO programming in the one language!

I was just pondering if any effect handling is best done in OOP way.

Things you want to express as hierarchies instead of composition? Exceptions come to mind.

1 Like