Object model in functional style?
Asked Answered
A

1

6

Is it at all practical to implement an object model in functional style?

One problem that OOP seems to excel at is describing object models.

For instance, an HTML DOM is a complicated, stateful beast which interfaces directly with the UI and requires programmability from dynamic languages. OOP features tend to come in useful in a lot of ways:

  • Member access constraints make interfacing with untrusted code (e.g. javascript) safe
  • Accessor functions and properties make binding to the UI much more convenient
  • Not having to pass around the object model all the time makes methods a lot simpler.

The UI side of the story might be a bit moot if you're projecting the model via MVVM, but you're still constantly wrestling with state internally.

I'm working in F# for this project so I could easily resort to OOP, but I'm curious as to how far I can push it before it becomes impractical. Are there maybe design patterns or anything?

Autolysin answered 28/4, 2011 at 8:33 Comment(11)
OCaml, F#, CLOS, Clojure, Haskell, and Scala -- plus all of the objected oriented idioms in other languages like Erlang... Yeah, I'd say it works pretty well for them. OOP doesn't have to manipulate state, it's primarily (in my mind) for organization and DRY.Obedient
I've seen it done with Leskah, and I looked at the code but unfortunately it's sort of beyond me right now. I also don't really have a feel for how functional you can get without giving up DRY, ending up with hard-to-maintain code and/or driving third-party plugin/script authors mad.Autolysin
DRY is easier in functional languages than OO since in FP it’s trivial to refactor any repeated code into a function that takes a parameter. In OO (or rather procedure programming) repeated code is preamble and postamble that are the same with a bit in the middle that’s different you have start thinking in about base class or interfaces, in FP you don’t the bit in the middle just becomes a function as a parameter. Tomas's book has great examples of this: manning.com/petricekSelfgoverned
I get that in most problems it's easier to minimize code in FP than in OOP, but I think when one says DRY they don't mean things like type annotations (if that's what you mean by preamble/postamble) -- which of course type inference does make certain types of code much shorter, but generally when you try to do something that doesn't fit the idioms of a language or paradigm, you start having to repeat yourself a lot more in what would seem not to be boilerplate code.Autolysin
@Rei: "HTML DOM is a..." I fear you are describing a solution rather than the problem you are trying to solve. Or are you literally trying to retrofit new F# code onto existing DOM code?Churlish
@Jon I don't understand, describing a solution?? And no, I'm writing something from scratch in F#. I'm trying to see how far I can get writing idiomatic F# without resorting to its OOP features.Autolysin
I tend to fall back on OOP at the point where I find I'm passing so much state information that I'm passing around what amount to objects anyway. And sometimes, when the problem is obviously and naturally modeled with a hierarchy, I'll just start with OOP. But I find the FP code generally more succinct and maintainable.Blastosphere
@Blastosphere -- Yeah, that's the thing. The more I can stick with FP, the easier my code will be to wrestle. But things like making sure all the references to immutable records are up to date is really quite baffling.Autolysin
@Rei: "I'm trying to see how far I can get writing idiomatic F# without resorting to its OOP features". Just for fun? My concern is that I cannot tell what problem you are trying to solve from the question you have given. Perhaps you could give a concrete example of something you are trying to express in both FP- and OOP-style code?Churlish
@Jon I'm honestly not too sure if I'm stuck at yet or where I'm stuck exactly if I am. I may have to get back to you on that, thanks. And yep, just for fun.Autolysin
@Rei: As long as you're doing this just for fun, you might try morphing between FP and OOP by simulating objects in FP as records of functions and seeing how far you can take that idea.Churlish
S
5

This is a bit philosophical to have a "correct" answer but okay I'll bite.

In my opinion the problem comes because you consider FP and OO to be juxtapose, they are not. FP and imperative programming are juxtaposed, i.e. using expressions versus using statements.

Part of the problem is that OO lacks a clear definition, well in my opinion anyway. To support this I'd point to Alan Kay who said “Actually I made up the term "object-oriented", and I can tell you I did not have C++ in mind.”, yet most language we consider OO i.e. java/C# take more after C++ than smalltalk.

What OO C++/java/C# style does give us is a nice way to organize our code into models, create data contains add properties to them etc. Non of this is practically un-functional and can be used nice with functional programming.

As you point out a lot of C++/java/C# tend to be stateful, but they don’t have to be, both java and C# have fundamental types such as their string classes that are immutable. It’s true java and C# don’t make it easy to create immutable class but with a bit of effort you can do it.

Which brings us to where is immutable appropriates? In my designs usually start of by making everything immutable, since this makes getting things correct easier, and if I see this causing performance problems I start adding some mutability on the critical paths. The one place immutability is never going to work is GUI controls, which generally contain far too much state to be immutable. Having said that you can get quite a long way building GUI using a immutable “combinator” approach then is then interpreted by mutable gui controls. This is more or less what the WebSharper guy’s do: http://www.intellifactory.com/products/wsp/Home.aspx

Another great resource for the FP/OO debate is Brain’s “How does functional programming affect the structure of your code?” (which greatly influenced my thinking about FP/OO): http://lorgonblog.wordpress.com/2008/09/22/how-does-functional-programming-affect-the-structure-of-your-code/

Selfgoverned answered 28/4, 2011 at 11:47 Comment(7)
Thanks, the combinator approach might be what I'm looking for. The reason I put FP on the other end of OOP is because as Rafe pointed out, OOP offers a lot of organizational features that aren't as straightforward in FP (to me, anyway -- which is why I ask). Also, when I expose the object model to plugin authors, I want to make sure the consumer doesn't put the model in an invalid state -- which I'm not sure is as easy to ensure in non-OO styles, including FP. I've read Brian's post in the past too, but the reason I ask again is because Brian is still encouraging OO "in the large".Autolysin
Yes, I agree that OO in the large is a good thing, but then most FP languages also have a good set of OO features, including features that help you organise your code. I spend quite a bit of time programming with both C# and F#, I find that C# is missing features that I find useful in F#, pattern matching, union types to have just a couple, but the reverse doesn't seem to be true. I think debat would be more useful if you could come up with more specific examples of things that are easy in OO but aren't available in an FP langaue.Selfgoverned
Hmm well I never intended it to be a debate, but yeah -- for instance, I can't think of an obvious way to do data binding to immutable objects.Autolysin
It's turning into a debate because the original question was open ended :) It's possible to databinding with immutable objects, in WCF databinding you lose the ability to do two-way binding. You could imagine a databinding framework that was more immutable object friendly, when a user update a value you'd create a modified copy of the object and use that in the update notification. Such a framework would need to use mutability under the hood, but you'd be getting towards a UI framework were all "user code" was immutable. I don't think such a framework exists yet.Selfgoverned
I'm not sure which part of my question is open-ended, or why that would make it into a debate, but I apologize as that really wasn't my intent; I'm just really curious as to whether or not I should consider writing an object model in functional style. I'm guessing that when an update happens, every item in the object would have to be checked for a changed state, since it's going to be referring to a new item? Is that as inefficient/tedious as it sounds?Autolysin
Okay to go back to the general question: yes, you should consider writing a object model in functional style. It won't be appropriate in every situation, but there are many places where it works well. The only real way to know is to try and see. If you do hit problems don't assume they're insurmountably, ask stackoverflow what they'd do.Selfgoverned
Yep, Imma try it out. Thanks!Autolysin

© 2022 - 2024 — McMap. All rights reserved.