Functional programming with clojure, avoiding mutable state

So, my question is about whether I can avoid mutable state in a particular action my program needs to do.

Some context: About a week ago I decided to learn to program in Clojure, to teach myself functional programming. (By day I work as a web developer using mainly C#.

So in my experience the best way to learn a language is to start with a project. I chose to create something that I needed anyway, a small tool to read text snippets out of an XML file and then do some find-and-replacing in other text files (and detecting inconsistencies.

So I'm up to the part where I've parsed the file into a list of maps that I need, and here's the problem: the way I see it, I can pass around my data between functions as much as I want, at some point there's nothing to do for my program. And then when the user clicks a (javax.swing-button, my program will have forgotten everything.

How would a functional programmer solve this?

Possible solutions I came up with:

-Monads. (Great for building complexity but still disappear when the functions stop executing.

-Read the file from disk again everytime the user clicks a button: seems silly.

-Store the contents of my file within my form controls. Seems like cheating (and also just wrong.

-When a file is parsed, create a closure with references to the resulting datastructure, and install this a the new event handler(s) : seems like cheating and just generally a strange (but interesting) thing to try.

Who can tell me if I've identified this correctly as a situation where I can't do without a ^dynamic var?

Any pointers will be greatly appreciated.)))))

Edit : I'm not asking for for code examples, just a yes or no answer would do, and maybe a hint on what to look up next, to the question: is there a way for a clojure program to remember some data it computed, in idle state (until next java event handler gets fired), without using a global variable, atom, ref, or agent?

And the reason I'm asking is that I want to learn to program in a functional style the proper way, and I'm basically checking if I'm not going off track.

Thanks for all the useful responses so far, definitely got tips on books to read, that's always nice.


The Clojure-specific answer to your question is almost certainly not to use ^dynamic , but to use an agent, an atom, or refs.

But I believe that your question is more of a philosophical one than practical? This interview with Simon Peyton Jones is my favourite explanation for this question. A pure (for the purest sense of pure) functional program has no side-effects and is therefore useless. As Simon says in the interview, however, functional languages all provide ways to introduce limited, controlled side-effects in such a way as to avoid polluting the purely functional aspects of a program. Haskell does that through its type system (monads, monoids, and category theory). Clojure does it through agents, atoms and refs. Elm does it through signals. Erlang does it through processes and message queues. And so on...


So in my experience the best way to learn a language is to start with a project.

That may be true when you are staying within the same paradigm - eg imperative programming. No matter how many "functional programming techniques" you already use, the imperative mindset tends to remain. Moving from the imperative mindset to the functional mindset can be quite jarring.

To start changing that mindset start with the basics like Clojure the Brave or Living Clojure; start practicing on 4clojure and Clojure Koans.

Clojure doesn't eliminate mutability but mutability by default - ie it forces you to consider whether or not it is absolutely necessary to mutate something to accomplish your objective. Once you determined that mutability is required you have the choice of Vars, Refs, Agents and Atoms - each with its own advantages and drawbacks.

From RxJS is great. So why have I moved on? — Medium in reference to ClojureScript:

To be fair it's really hard compared to learning another OO language. The learning curve is steep. For the first month I constantly felt like I was on a trip to Japan where I couldn't read or write or speak and had to rely on grunting and pointing.

See also: Teaching Clojure at IBM - Steve Shogren

链接地址: http://www.djcxy.com/p/80850.html

上一篇: 共享数据而不使用可变变量

下一篇: 用clojure进行函数式编程,避免可变状态