5 ms·
Everyone talks about functional programming as if its this great new thing. I'm coming from a strong C# background, and to me this reads exactly like OOP. > t
by SamuelAdams 8y ago
Everyone talks about functional programming as if its this great new thing. I'm coming from a strong C# background, and to me this reads exactly like OOP.
> the output value of a function depends only on the arguments that are passed to the function, so calling a function f twice with the same value for an argument x produces the same result f(x) each time.
OK, that's basically a static method in C#. Is that wrong?
The piece goes on to say
> Functional programming, therefore, is programming so as to avoid these side effects wherever possible.
So functional programming should never handle state? Do you just move that logic into another framework (Angular, React, etc)?
Maybe there's some obvious stuff I am missing. Why should I use a functional language (like F#) over an existing OOP language?
- i_s 8y ago> OK, that's basically a static method in C#. Is that wrong? It it can be true of a static method, but a static method can also make an HTTP request, read the current time, etc, so that the answer doesn't just depend on the arguments.
- frabert 8y ago> that's basically a static method in C# No, `Console.WriteLine` definitely has side-effects > functional programming should never handle state No, quoting the same quote as you did: "avoid these side effects wherever possible", emphasis on "wherever possible". Of course, a program which never has any side effects or state would be useless, as it would not accomplish anything.
- lolive 8y agoIs Haskell the only FP language where chaining instructions one after the other in not available by default ?
- weavie 8y agoAny purely functional language will : https://en.wikipedia.org/wiki/List_of_programming_languages_by_type#Pure https://en.wikipedia.org/wiki/List_of_programming_languages_... If a language is pure then there is no point running an instruction other than to return a result since the only point in ignoring a result would be if the instruction had a side efffect, which a purely functional language disallows. Haskell does simulate this chaining instruction via the do notation.. do a <- getLine b <- getLine putStrLn ( a ++ b ) It looks like it is chaining instructions, but really this gets rewritten by the compiler to something like this (in pseudo js) : bind(getLine, function(a) { bind(getLine, function (b) { putStrLn a + b; }) })
- lolive 8y agoI have spent ages understanding this. And I am super happy that what you summarize is the mental model I have made up.
- estomagordo 8y agoYou can still have side effects in a static method. A more functional style, say like that of the one in F#, strongly encourages you to avoid many occasions where side effects may otherwise appear. Look at this fiddle for instance: https://dotnetfiddle.net/68jAIw https://dotnetfiddle.net/68jAIw
- ealhad 8y agoOOP and FP are not orthogonal per se.
- kgwxd 8y ago"OK, that's basically a static method in C#. Is that wrong?" A static method can have side effects and/or return different results even when given the same arguments. e.g. returning DateTime.Now would never yield the same results. "So functional programming should never handle state?" Any useful application will have state and side effects, the idea is to push as much of it as possible to the outer edges of your application and keep the core as pure as possible/practical. You can do that with any language, but a functional languages will be designed to make that easy and idiomatic.
- mrkeen 8y agoNon-functional languages seem to pay lip service to FP, confusing people into thinking they're already using it. Example: It is well known that "Java Strings are immutable", which is a good idea. Yet you can absolutely write: > String str = "hello,"; > str += "world!"; So it's "immutable" for some lawyerish definition which does me no good. If I write a method that depends on s, it will produce different results each time. > So functional programming should never handle state Not at all. You should know (and be able to enforce) when your code does mutations.
- kbp 8y ago> Yet you can absolutely write: > String str = "hello,"; > str += "world!"; So it's "immutable" for some lawyerish definition which does me no good. `str` is a mutable reference to an immutable object. You can make the reference point to something else, but the object being pointed to is immutable, so eg if you pass it to a function, that function cannot change it under you. If you want to make the reference immutable, declare it as final. I don't think understanding the difference between a pointer and the value it points to is lawyerish.
- mrkeen 8y agoThank you. ^ that's the lawyerish definition I was referring to ^
- deleted 8y ago[deleted]
- deleted 8y ago[deleted]
- deleted 8y ago[deleted]
- deleted 8y ago[deleted]
- deleted 8y ago[deleted]
- Folcon 8y agoIt's more about controlling state. I like to think of ring[0] as a really nice example of this that's pretty easy to reason about. It abstracts http handling into a series of key/value data structures. The request that's pulled in looks like this: {:remote-addr "localhost" :headers {"host" "localhost" "content-type" "application/json" "accept" "application/json"} :server-port 80 :content-type "application/json" :uri "/" :server-name "localhost" :query-string nil :body "" :scheme :http :request-method :get} The response like this: {:status 200 :headers {"Content-Type" "text/plain"} :body "Hello World"} Functions manipulate these structures, but their input and outputs are primarily those data structures. (defn handler [request] {:status 200 :headers {"Content-Type" "text/plain"} :body "Hello World"}) Your app is now just a function stack that get's called in this order: (def app (-> handler (wrap-content-type "text/html"))) Request => wrap-content-type => handler (generate response) => wrap-content-type => Returned Want to add middleware? Define a function that handles it, here's an example[1]: (defn middleware [handler] (fn [request] ;; Do something to the request before sending it down the chain. (let [response (handler request)] ;; Do something to the response that's coming back up the chain. response))) Then add the function to your app: (def app (-> handler (wrap-content-type "text/html") (wrap-keyword-params) (wrap-params))) You want to handle session data? Ring provides wrap session[2], add it and then use your own middleware or handler to manipulate the session by just changing the value at :session. Example [3]: (defn handler [{session :session}] (let [count (:count session 0) session (assoc session :count (inc count))] (-> (response (str "You accessed this page " count " times.")) (assoc :session session)))) Much of your world is now reduced down to: * Does this data structure look correct? * How can I fix it? * Do I need some resource like a db connection? Ok how do I add it to my data structure? It all composes, and you end up worrying a lot less. Finally I find that doing things this way ends up creating programs that just have much less explicit state, as opposed to temporary state that's derived from other values and so only changes when those things change. You can program in other languages like this, it's just a bit harder, and you have to hope that no one else you're working with breaks one of the assumptions that a system like this is built on, as opposed to having the language enforce those for you. Sorry if I've been unclear =)... [0] - https://github.com/ring-clojure/ring/wiki https://github.com/ring-clojure/ring/wiki (Examples taken from ring). [1] - https://stackoverflow.com/a/19459508 https://stackoverflow.com/a/19459508 [2] - https://github.com/ring-clojure/ring/blob/95e4ca25d5b98c45f927b32b5c3c85c21c999d96/ring-core/src/ring/middleware/session.clj#L77 https://github.com/ring-clojure/ring/blob/95e4ca25d5b98c45f9... [3] - https://github.com/ring-clojure/ring/wiki/Sessions https://github.com/ring-clojure/ring/wiki/Sessions
- dragonwriter 8y ago> OK, that's basically a static method in C#. Is that wrong? Yes, that is wrong. Static methods don't have access to object state, but they can still access mutable state (e.g., static data members) and invoke other side effects, so its results can depend on things other than the arguments. > > Functional programming, therefore, is programming so as to avoid these side effects wherever possible. > So functional programming should never handle state? “Wherever possible” is not the same as “everywhere”. > Do you just move that logic into another framework (Angular, React, etc)? No, though pure languages generally do something loosely similar; Haskell programs, can be viewed (in one interpretation of values in the IO monad) as having a main function that produces an imperative program as the output, which by convention the runtime executes.