4 ms·
Even better: don't use objects at all. Use a functional programming language.
by Kototama 15y ago
Even better: don't use objects at all. Use a functional programming language.
- cousin_it 15y agoObject oriented programming is the sweet spot solution to many problems. For example, if you have a UI with several text fields, it's natural to think of them as objects that have methods like setText(), setEnabled() and such. These methods often have side effects and that's their whole point. Of course functional programming also has use cases for which it is the sweet spot solution, e.g. writing compilers.
- Kototama 15y agoI'm overreacting mainly because these last days I saw code with some Java classes just acting as data holders. It's verbose and obscures the intend. Data deserves much more than being encapsulated in objects, data deserves the right to be put in front of the programmer so that he better sees how ill-designed his data model is :-)
- danieldk 15y agoThese methods often have side effects and that's their whole point. You don't need state and mutations, GUIs can also be programmed nicely using functional reactive programming (FRP). A nice description of FRP: http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming http://stackoverflow.com/questions/1028250/what-is-functiona... Some examples of FRP in GUIs: http://www.haskell.org/haskellwiki/Reactive-banana/Examples http://www.haskell.org/haskellwiki/Reactive-banana/Examples
- cousin_it 15y agoA simple counter that can be manipulated with two buttons "Up" or "Down": https://github.com/HeinrichApfelmus/reactive-banana/blob/master/reactive-banana-wx/src/Counter.hs https://github.com/HeinrichApfelmus/reactive-banana/blob/mas... main = start $ do f <- frame [text := "Counter"] bup <- button f [text := "Up"] bdown <- button f [text := "Down"] output <- staticText f [] set f [layout := margin 10 $ column 5 [widget bup, widget bdown, widget output]] network <- compile $ do eup <- event0 bup command edown <- event0 bdown command let counter :: Discrete Int counter = accumD 0 $ ((+1) <$ eup) `union` (subtract 1 <$ edown) sink output [text :== show <$> counter] actuate network This doesn't look like good UI code to me. It seems to use too many advanced FP concepts that have nothing to do with the task at hand. Are you sure this is better than the OO approach? Why?
- danieldk 15y agoThis doesn't look like good UI code to me. It replaces a mutable counter (that could potentially be changed anywhere in the program) by a definition of the counter that describes all possible changes it can have during its lifetime: counter = accumD 0 $ ((+1) <$ eup) `union` (subtract 1 <$ edown) So, we have a counter that has an initial value of one. Over time, 1 can be added and 1 can be subtracted, namely when repsectively an eup or edown event occurs. Being able to capture all possible 'state mutations' of a value in one assignment is good. It seems to use too many advanced FP concepts that have nothing to do with the task at hand. Which is a bit ironic, since the widgets are created in the IO monad with the 'do'-notation, which simulates imperative programming in Haskell :). A user interface should be designed with a WYSIWYG interface (Glade, Qt Designer) anyway, but that's besides the point.
- deleted 15y ago[deleted]
- cousin_it 15y ago> Being able to capture all possible 'state mutations' of a value in one assignment is good. I think there's a duality here. If there are 20 buttons, each of which can affect some of 30 counters, then the Haskell code would say "this counter is affected by these buttons", while imperative/OO code would say "this button affects these counters". It's not obvious to me that the former way of organizing code is better.
- danieldk 15y agoYou are still missing the point. In imperative programming there is no guarantee that the counter isn't modified in some place else or wrongly. In the end it's just an integer that allows all kinds of mutations. The possible value changes in the Haskell FRP example, on the other hand, are completely described. There is no other manner in which the value can change.
- cousin_it 15y ago
- ubernostrum 15y agoI see, your bullet is apparently more silver than mine? :)
- Kototama 15y agoOf course, it's a bullet designed with maths :-)
- j2labs 15y agoFunctional programming and objects are not orthogonal as you suggest.
- thesz 15y agoYes, they pretty opposite. Objects should have identity and can be distinguished by identity alone. They are not referentially transparent because of that. In "x = new O(); f(x,x)" you cannot substitute "new O()" into both occurrences of x. Functional values do not have identity and you cannot tell apart 2 and 1+1. Functional values are referentially transparent. In "x = 1; y = x+x" you can change x to 1 in the definition of y.
- j2labs 15y agoAgain, they're not opposite. You can create most of the properties of an object with a closure and versa vice. http://c2.com/cgi/wiki?ClosuresAndObjectsAreEquivalent http://c2.com/cgi/wiki?ClosuresAndObjectsAreEquivalent
- morsch 15y agoWell, he briefly touches on that: As long as you haven't joined in the Functional Monks in their Monasteries of Statelessness, programs are made of behavior and data. I thought this was the best part of the essay (at least it made me smile).