I've been reading and playing with Functional Programming (FP) and I really like it's concepts, but I'm not sure how to apply them for most of my applications.
I'll be more specific, let's talk about iOS apps. I do see how to use some of the concept like immutable data structures and higher order functions, but not how to work with only/mostly pure functions - avoiding side effects - which seems to be the main part of FP.
I feel like most of the app is about coordinating input calls, displaying data, saving data, making network requests, navigating from one screen to another, animations.
All those would be impure functions on FP:
There are very few places in which I have to process data and those consist almost always of retrieving some Struct's from the database and concatenating the multiple information into another Struct that will be used by the View Controller (that's like 5 lines... assuming you need 5 properties to be displayed in the view). Sure, you might need to do some processing like converting money: Int = 20 to moneyString: String = "US$\(money).00"
, but that's it.
I feel like I'm failing to implement FP in my app development cycle. Can anyone clarify how I can achieve that? Maybe with examples.
Thank you.
EDIT: right now, following the Clean Architecture idea, I have something like this as my architecture:
Inputs can come from the View
, as a button click, they go to the ViewController
who decides which Interactor
to call. That Interactor
will access the necessary Gateway
s to get some data and transform it into presentable data that will be passed to the Presenter
(in the form of a delegate). Finally the Presenter
will update the View
to display the new data.
Additionally, the input can come from External
sources, like the server telling you some data was updated and you have to refresh the View
. That goes to the Interactor
(in the form of observer) which will follow the rest of the chain as in the previous example.
The only FP part is transformaing the Gateway
's data into presentable data. All the rest has side effects. I feel like I'm doing something wrong and maybe some of that code should be organized differently so that more code can be moved to pure functions.
Functional programming has historically been less popular than imperative programming, but many functional languages are seeing use today in industry and education, including Common Lisp, Scheme, Clojure, Wolfram Language, Racket, Erlang, Elixir, OCaml, Haskell, and F#.
Functional Programming is used in situations where we have to perform lots of different operations on the same set of data. Lisp is used for artificial intelligence applications like Machine learning, language processing, Modeling of speech and vision, etc.
Still, "functional programming is unmistakably the future," says Felix. "It can help make a large proportion of the current problems we have in software development disappear.” And it can even be used within established Java ecosystems.
Putting aside FP for a moment, the challenge with multi-user or time dependent models is that the end-user in front of the program is not the only source of control events.
To keep the dependencies clean, we should view external triggers as an form of user input (unsolicited as it may be) and process them through the same paths.
If the end user had somehow been telepathically informed that new data was available, he could have pressed a button to have the program get it. Then no backward control flow would ever be needed (such as push notifications).
In that perfect world, the user's action to get the data would have first been captured at the View level and then carried down the layers.
This tells us that the notifications should be handled by the view controller or, better yet by a view component designed to receive them. Such notifications however would not contain any data except perhaps some indication of which part of the model have been invalidated.
Back to FP, this is of course a gigantic side effect if you consider that all function calls thereafter will return potentially different results. BUT...
In mathematics, if you define a function that gives you distance traveled at a given speed but don't supply the time parameter, you're not victim of a side effect, you merely forgot to provide an input value.
So, if we consider that all software layers are pure functions but that time is an implicit parameter given with the initial input, you can validate that your program conforms to FP by checking that repeated calls, in any order, to functions of the system when time is frozen should always return the same results.
If databases could keep a 100% complete set of snapshots of their states at any given time it would be possible to validate pure FP conformance of applications by freezing time or making it a parameter.
Back in the real world now, such a design is often impractical for performance reasons. It would pretty much preclude any form of caching.
Still, I would suggest you try to categorize notifications as unsolicited user input in your design. I believe it may help solve some of the conundrums.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With