3

Okay I'm trying to understand how to do programming without variables.

I've managed a simple tic-tac-toe game but it depended on a tail recursive state and as far as I can tell would only work in a single thread. Example can be seen at https://codereview.stackexchange.com/questions/187339/scala-tic-tac-toe-no-mutable-state

Now if I was to convert the same code to be either a webapp or even a gui program I can't see how the state could be shared across threads without having a mutable reference at the top level.

Even ScalaFX uses a variable for its PrimaryStage which I suspect is to provide such a top level reference.

How would one go about using shared state between two or more consumers without using variables? For instance tic tac toe as above or a web application that accepted posts of text and had an endpoint stating how many times an individual word was posted.

related: Java: state sharing between threads in functional programming

Functional way to implement a thread safe shared counter

However the solutions to this all seem to require some mutable variable an atomic integer in one and STM in the other.

Is there a standard pattern for this type of work?

After reading How can you do anything useful without mutable state? and How Functional Programming addresses concurrent increment/decrement operations invoked by different users I am pretty sure that this is not possible. There does need to be a reference to mutable state.

If this is the case how can the mutable state be minimised?

What patterns do people use for scala in web applications with internal state?

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Wes
  • 6,697
  • 6
  • 34
  • 59
  • I can copy the code from the code review question here if its required for this site – Wes Feb 16 '18 at 18:43
  • it has been suggested to me that this may be a better fit for softwareengineering.stackexchange.com I tried asking in their chat room but no answer. – Wes Feb 16 '18 at 20:02
  • 1
    Odd that you came to this conclusion. [How can you do anything useful without mutable state](https://stackoverflow.com/questions/1020653) does, in fact, show you how it can be done. How? By storing state on the stack via recursive function calls, that''s how. Whether it's practical or not is another story, but you state that it is impossible, not that it is impractical, and it might not even be that. For a more rigorous treatment, look up Okasaki's Functional Data Structures. – Robert Harvey Feb 17 '18 at 06:16
  • @RobertHarvey But Wes' question is specifically about communication between multiple threads. At least on JVM, different threads have (conceptually) separate stacks, so the stack can't be the carrier for the messages passed between threads. Or can it? – Andrey Tyukin Feb 17 '18 at 11:39
  • @RobertHarvey Yes thats the scope of the question. Those answers say on the stack (which I did in the first linked question from CR). Some say its not possible and others use the IoMonad. – Wes Feb 17 '18 at 12:57
  • @AndreyTyukin weren't you the person who said this question was leading and more or less out of scope. Something like "who says individual threads are involved." I tried to answer that comment but it was gone by the time I typed the answer – Wes Feb 17 '18 at 12:58
  • @Wes I've posted a comment along the lines: "there is no reason why a functional program must use threads and shared mutable state instead of e.g. actors and message-passing". While this is true (you can go a long way writing large distributed apps on top of actor systems in mostly functional style), I've quickly realized that this wasn't very helpful for the question, because you are asking *specifically* about threads and mutable shared state. So I deleted my comment. – Andrey Tyukin Feb 17 '18 at 13:05
  • @Wes Otherwise: Functional programs are just *plans*, composed from tiny atomic parts and pure functions. These plans don't *do* anything, they just *are*. A pure function in haskell that represents the plan to read in two numbers and print their sum doesn't *do* anything by itself, it is completely inert until it is connected with Haskel's runtime system which does all the IO-stuff with stdin and stdout. Same with threads: a bunch of plans that specify what multiple threads should do *don't do anything* until they are passed to an interpreter that can execute those plans in multi-threaded way – Andrey Tyukin Feb 17 '18 at 13:32
  • @Wes Functional programming is not about eliminating state alltogether (you can't do this, because in the end of the day, the software has to run on the hardware, with all it's stateful wires and voltages). The idea is just that the interaction with the state and all other side-effects is pushed to the boundary of the system as much as possible. In Haskell, it's pushed completely to the runtime system. In Scala, it is pushed at least away from the core logic, the interpreters are implemented separately. In imperative programs, all the states and effects are often intertwined with core logic. – Andrey Tyukin Feb 17 '18 at 13:38
  • @Wes Can you write a purely functional program that *does stuff with threads*? By definition, no. You can only write down pure functions that *just are*. Can you write some kind of runtime system that can take a pure function and *interpret* it as a plan for execution of multiple threads? Yes, of course. The point is just that the plan is separated from the runtime system, whereas in imperative program, the interpreting runtime system is intermingled with the otherwise purely functional plan. It's like having some weird hardware-driver code mixed with your core application logic. – Andrey Tyukin Feb 17 '18 at 13:44
  • @Wes I don't know, I could write it up as an answer, if you wish... It's just that the question feels so broad that I don't feel like it's answerable within a lifetime at all. – Andrey Tyukin Feb 17 '18 at 13:45
  • Yeah I think there is value in what you wrote so its a shame in a way if it just stays a comment. However its difficult on SE to have these discussion threads. I know IO is impure. I wasn't sure if threading had to be impure though it appears so. Given that caveat it should still be possible to write an answer stating that it is impure but there are patterns for dealing with it. Particularly intrested (even though the question didn't ask) in how servlets that depend on previous http calls are done minimising the impurity. – Wes Feb 17 '18 at 15:19
  • 1
    I really recommend that you read [this](https://wiki.haskell.org/IO_inside). Try to understand a little bit of Haskell grammar, and then understand how do they manage to have referential transparency even in functions that, for the common understanding, always return a different value, such as currentTime. Spoiler Alert: You return programs. At some point there are some mutability, so jus try to keep your pure functional programming logic as far away from your mutable part as possible. At the end, you need side effects (variables). – caeus Feb 21 '18 at 15:04

0 Answers0