3 ms·
But one actor can always read the state of the other actor, and modify their actions accordingly. The state of each actor is immutable, so each action taken bas
by ece 9y ago
But one actor can always read the state of the other actor, and modify their actions accordingly. The state of each actor is immutable, so each action taken based on the state is sure to be conflict free. As opposed to imperative programming, were each actors position might not get updated correctly or in time until too late. Deadlock and starvation don't happen when you have pure functions with no side effects and immutable state like they do in non-FP languages.
Timing is harder to get right when everything is async, but if your game design is good, you just need to better implement it to get it right frame by frame. He also talks about having monads to handle things like this.
- crimsonalucard 9y agoIf two actors moved to one spot at the same time which actor occupies that spot? How can an actor act accordingly if they moved at the same time? In functional programming this can happen... in imperative programming it NEVER happens, because the actors move imperatively, aka step by step or one at a time. This is the problem he is talking about.
- deleted 9y ago[deleted]
- ece 9y agoIt can only never happen if you use a lock correctly. In separate threads, this can absolutely happen in imperative programming. As a reader-writer or dining philosopher problem will show, two actors can try to do the same thing at the same time unless you EXPLICITLY stop them by using locks. In FP, you will have an immutable variable for state instead of a mutable variable wrapped in a lock. You will be passing a whole new immutable state variable to a pure side effect free function every time, and won't have to worry about getting a lock and releasing it explicitly (these would be side effects). As long as the state is immutable and synced across threads, actors in any thread can just plot their next actions using that state. In imperative programming, like I said, you'll have to explicitly get and release locks to make sure two actors don't occupy the same spot. So, if you use atomic immutable variables with pure functions, and the logic in your actors can be conflict free, you can have horizontal scalability across as many cores as you want pretty easily. If your actors cannot be conflict free, you will need to wrap a lock of your choice in a monad and use that, but you will still have gained better debugging, testing and maintainability by using FP. Now if only every zero-cost OO abstraction had a straight forward FP alternative that was also zero-cost, we'd all be doing FP as of yesterday.
- ves 9y agoI don't think the latter point is true. FP requires a lot of thinking up front, which is not how most engineers like to work. That's not to say that FP is at odds with iterative programming, but it means that you have to work out a "specification" of your code pretty completely from the beginning. Although, even then it's not so bad because the excellent type systems and compilers mean you can develop the specification interactively (see Idris' typed holes).
- ece 9y agoWhich part? I think even John Carmack in the video talked about the upfront thinking required for FP. If every CS student learned category and type theory like they learn complexity theory; and FP compilers could optimize type classes and all the object creation, FP would definitely be more widely used. But, yes, there is definitely a cost to picking up FP today in almost any domain, but it's getting lower.
- crimsonalucard 9y agoMan. You are arguing with me as if I disagree. When did I bring up threads and locks? I'm just elucidating the problem Carmack brought up. Jesus.
- ves 9y agoFP is not gonna wall you off from doing stuff like this. For example, and this is just off the top of my head, you could: * provide an explicit sequencing of when actors take their turns, passing updated resources to each in turn. This is your "step by step" imperative approach, and you're basically writing a main game loop. * don't sequence the actors, but implement a lock on the resource using a TVar. This is the simplest async approach. * many more approaches I haven't thought of The point of FP is to be provide as much information about the logic of the program as possible. If two actors can move to the same point at the same time, then you need to write down logic to handle that case, whether actors move in sequence or independently. Not writing down that logic because "I have an imperative language" is how you get bugs, especially race conditions.
- crimsonalucard 9y agoI'm not arguing about which paradigm is better. I'm not saying theres no way around it. I'm just describing a single pitfall in the functional paradigm. That's all.
- ece 9y agoBeing able to write asynchronous (multi-threaded or not) code so easily using FP is most definitely not a pitfall. Even in the most simple multi-threaded imperative programs, no compiler or hardware will give you almost any sort ordering guarantees by default. You have to use atomics or volatile or something else to get specific ordering guarantees. It's the same in FP compilers too.
- crimsonalucard 9y ago>Being able to write asynchronous (multi-threaded or not) code so easily using FP is most definitely not a pitfall. Your point? You're saying this as if I disagreed with you. What are you trying to argue here? That FP is the better than imperative? Did I ever dispute that claim? Where are you going with this?