Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Functional Programming on App development [closed]

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:

  • Coordinating input: a button tap, a notification, a server socket push, for all those I have to decide what to call, where to observe them, etc.
  • Displaying data: reads from a local database or from a server (side effect).
  • Saving data: same as above (but writing).
  • Making network requests: obvious, so I'll just give an example here - retrieving list images from Instagram.
  • Navigating: that's basically presenting View Controllers, which is a side effect.
  • Animations: changing something on the screen, side effect.

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:

enter image description here

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 Gateways 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.

like image 554
Rodrigo Ruiz Avatar asked Jul 21 '16 06:07

Rodrigo Ruiz


People also ask

Is functional programming still used?

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#.

What can you do with functional programming?

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.

Is functional programming the future?

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.


1 Answers

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.

like image 155
Alain T. Avatar answered Oct 21 '22 02:10

Alain T.