Re: [Haskell-cafe] Observer pattern in haskell FRP
On 12/18/2012 10:52 PM, Heinrich Apfelmus wrote: Nathan Hüsken wrote: On 12/08/2012 10:32 AM, Heinrich Apfelmus wrote: Fair enough, but I don't see how this can be fitted into a general pattern. If the animation state is coupled tightly to the game logic state, then the question whether the animation is part of the game logic or not does not have a clear answer anymore. Hm. I see it like this: The logic state may not depend on the rendering state. If for example the animation of an asteroid changes how or when objects collide with it, than the animation is part of the logic. If however the physics of the game treat the asteroid as a object whose shape does not change depending in the animation, than the animation is part of the rendering state. So the coupling may only be logic-rendering. Maybe discussing a concrete example could be very helpful. Could you give a minimal example that still contains the key difficulties? I put a pseudo C++ example below the mail. I use the terms model and view for the game logic and rendering respectively. The example is a little different. Asteroids explode when they collide. The moment asteroids explode, they are removed from the model (the game logic) while in the view (rendering) they still exist until the explosion animation is over. (Sorry for the late reply.) I see, that's a nice example. Indeed, if you try to model this situation with dynamic collections galaxyModel :: Behavior [AsteroidModel] galaxyView :: Behavior [AsteroidView] then you have to keep track of IDs in some way, because a change in the collection of asteroid models needs to be reflected in a corresponding change in the collection of asteroid views. identifier :: AsteroidModel - ID eCollisions :: Event [ID] eCollisions = collisions $ galaxyModel @ eTick where collisions asteroids = [identifier a | a - asteroids, b - asteroids, a `collides` b] galaxyModel = accumB initialAsteroidModels $ removeFromList $ eCollisions galaxyView = accumB initialAsteroidViews $ startExplosions $ eCollisions That said, do note that any significant use of pointers in an imperative program translates to the use of identifiers in the purely functional variant. This is very much *independent* of FRP! In other words, if you find that giving certain game objects an identity is a good way to structure your code, then you need to use identifiers, regardless of whether you use FRP or not. Well, direct translation of imperative structures are probably often not a smart way to go. Instead a functional approach with the same benefits is more desirable. I just find it very hard to think in new directions for a problem I already know a solution in an imperative style :). Of course, as you note in another message, there are other ways to structure this code. For instance, the second idea would be to use a data type type Asteroid = (Maybe AsteroidModel, AsteroidView) which represents live asteroids as (Just positionEtc, view) and dead asteroids as (Nothing, explosionView) . Then again, one unsatisfactory point about this approach is that an exploding asteroid is now represented explicitly in the game logic as a Nothing value. A third approach would be to keep an explicit list of explosions. data AsteroidModel = AsteroidModel { view :: AsteroidView, pos :: Position } data AsteroidView = AsteroidView { rotation :: Angle } data Explosion = Explosion { posExp :: Position } galaxyView :: Behavior ([AsteroidView], [Explosion]) galaxyView = (,) $ (map view $ galaxyModel) $ explosions explosions = accumB [] $ startExplosions $ eCollisions You do need an event to communicate which asteroids have exploded, but an exploding asteroid will not appear in galaxyModel anymore. Instead, it will be added as an anonymous explosion to the rendering logic. (In a sense, the asteroid views with the state variables dead = false and dead = true have been split into different types.) I find the third approach to be quite satisfactory. What is your opinion? I agree, I like it! The more I think about this example, the more I think that the underlying difficulty is not FRP, but the use of pointers / identities. I think the original question where I was asking for replacement pattern for observers in FRP is the wrong way to go. The goal was to separate game logic and rendering logic, and the solutions you mention provide this. Other Problems that are solved with the Observer Pattern probably should have a completely different approach in function programming or FRP. I am very happy with all he replies I got in this thread and I will see where it gets me. Thanks! Nathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
hey all, i've been lurking in this thread for a bit i just found this interesting article from chris granger (yeah, the light table guy). he just completed the node knockout they had recently decided to make a game. he did it all in clojurescript he discusses some aspects of programming a game in a functional language. so maybe this will give you some ideas on how to write games in haskell. anyway, linkage: http://www.chris-granger.com/2012/12/11/anatomy-of-a-knockout/ serialhex -- * If God had a beard, he'd be a UNIX programmer. * Some people pray for more than they are willing to work for. * This is Linux. Distro is a proper subset of Settings. --TwilightXaos on slashdot --- CFO: “What happens if we train people and they leave?” CTO: “What if we don’t and they stay?” ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
Nathan Hüsken wrote: On 12/08/2012 10:32 AM, Heinrich Apfelmus wrote: Fair enough, but I don't see how this can be fitted into a general pattern. If the animation state is coupled tightly to the game logic state, then the question whether the animation is part of the game logic or not does not have a clear answer anymore. Hm. I see it like this: The logic state may not depend on the rendering state. If for example the animation of an asteroid changes how or when objects collide with it, than the animation is part of the logic. If however the physics of the game treat the asteroid as a object whose shape does not change depending in the animation, than the animation is part of the rendering state. So the coupling may only be logic-rendering. Maybe discussing a concrete example could be very helpful. Could you give a minimal example that still contains the key difficulties? I put a pseudo C++ example below the mail. I use the terms model and view for the game logic and rendering respectively. The example is a little different. Asteroids explode when they collide. The moment asteroids explode, they are removed from the model (the game logic) while in the view (rendering) they still exist until the explosion animation is over. (Sorry for the late reply.) I see, that's a nice example. Indeed, if you try to model this situation with dynamic collections galaxyModel :: Behavior [AsteroidModel] galaxyView :: Behavior [AsteroidView] then you have to keep track of IDs in some way, because a change in the collection of asteroid models needs to be reflected in a corresponding change in the collection of asteroid views. identifier :: AsteroidModel - ID eCollisions :: Event [ID] eCollisions = collisions $ galaxyModel @ eTick where collisions asteroids = [identifier a | a - asteroids, b - asteroids, a `collides` b] galaxyModel = accumB initialAsteroidModels $ removeFromList $ eCollisions galaxyView = accumB initialAsteroidViews $ startExplosions $ eCollisions That said, do note that any significant use of pointers in an imperative program translates to the use of identifiers in the purely functional variant. This is very much *independent* of FRP! In other words, if you find that giving certain game objects an identity is a good way to structure your code, then you need to use identifiers, regardless of whether you use FRP or not. Of course, as you note in another message, there are other ways to structure this code. For instance, the second idea would be to use a data type type Asteroid = (Maybe AsteroidModel, AsteroidView) which represents live asteroids as (Just positionEtc, view) and dead asteroids as (Nothing, explosionView) . Then again, one unsatisfactory point about this approach is that an exploding asteroid is now represented explicitly in the game logic as a Nothing value. A third approach would be to keep an explicit list of explosions. data AsteroidModel = AsteroidModel { view :: AsteroidView, pos :: Position } data AsteroidView = AsteroidView { rotation :: Angle } data Explosion = Explosion { posExp :: Position } galaxyView :: Behavior ([AsteroidView], [Explosion]) galaxyView = (,) $ (map view $ galaxyModel) $ explosions explosions = accumB [] $ startExplosions $ eCollisions You do need an event to communicate which asteroids have exploded, but an exploding asteroid will not appear in galaxyModel anymore. Instead, it will be added as an anonymous explosion to the rendering logic. (In a sense, the asteroid views with the state variables dead = false and dead = true have been split into different types.) I find the third approach to be quite satisfactory. What is your opinion? The more I think about this example, the more I think that the underlying difficulty is not FRP, but the use of pointers / identities. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
On 12/12/2012 01:26 AM, Ertugrul Söylemez wrote: Nathan Hüsken nathan.hues...@posteo.de wrote: Actually it is very scalable, as the same map is passed to every object. It can even live in the underlying monad, which means that you could even use a mutable vector, if you wish; however, I don't recommend that. Remember that a map is immutable and shared, so passing the same map to multiple objects is in fact the same as passing a pointer in C++. Lookups in and updates to the map are of logarithmic complexity, so this scales well. Only doubling the number of nodes actually adds one full step to lookups and updates. If you're dealing with millions of objects you may want to use the vector solution mentioned earlier. This requires an imperative underlying monad, but you would get about the same speed as in C++. I might just not be used enough to functional data structures, Purely functional data structures is on my reading list :). I was thinking, in the asteroids example the only reason why the view needs more input than the models output, is that it needs to be informed of creation and destruction of asteroids. Why would the view need to be informed? So that the coresponding view objects can be removed (imidiatly or at some later point). So, in the model one could habe a signal asteroidsModel :: Signal Input [Just AsteroidModel] which outputs Nothing for asteroids that have been destroyed. Then, in the view this would be taken for as input for asteroidsView :: Signal [Just AsteroidModel] [Picture] asteroidsView would have to do the following: * route the input list to a list of asteroidView signals. * When there is a Nothing in the input list, the corresponding (now exploding) view is moved to a list of zombie asteroids where it remains until its explosion animation is over. * When the input list is longer than the list of current astroidView signals, the list is extended. This would avoid the need for bookkeeping ids. This is a very complicated way to do it. I would simply regard the zombie asteroids as regular objects. That way you don't need a special case in the view. I was thinking by doing it this way I could completely avoid the need for ids by this the bookkeeping of ids. On the other hand, I might need the ids anyway for other things and than my approach would just add complexity, as you said. Regards, Nathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
Am 10.12.2012 16:56, schrieb Ertugrul Söylemez: Nathan Hüsken nathan.hues...@posteo.de wrote: I put a pseudo C++ example below the mail. I use the terms model and view for the game logic and rendering respectively. The example is a little different. Asteroids explode when they collide. The moment asteroids explode, they are removed from the model (the game logic) while in the view (rendering) they still exist until the explosion animation is over. As you said, this basically is sending messages from the Model (in the observer pattern called Observable) to the view (Observer). The main difficulty I have is how to send the messages from the correct model to the correct view. In C++ this is done by keeping pointers. Simply assigning IDs would work, but than I would have to always pass a map from the model to the view, and I feel like (also I have little experience with this), that this approach is not very scalable. Actually it is very scalable, as the same map is passed to every object. It can even live in the underlying monad, which means that you could even use a mutable vector, if you wish; however, I don't recommend that. Remember that a map is immutable and shared, so passing the same map to multiple objects is in fact the same as passing a pointer in C++. Lookups in and updates to the map are of logarithmic complexity, so this scales well. Only doubling the number of nodes actually adds one full step to lookups and updates. If you're dealing with millions of objects you may want to use the vector solution mentioned earlier. This requires an imperative underlying monad, but you would get about the same speed as in C++. I might just not be used enough to functional data structures, Purely functional data structures is on my reading list :). I was thinking, in the asteroids example the only reason why the view needs more input than the models output, is that it needs to be informed of creation and destruction of asteroids. So, in the model one could habe a signal asteroidsModel :: Signal Input [Just AsteroidModel] which outputs Nothing for asteroids that have been destroyed. Then, in the view this would be taken for as input for asteroidsView :: Signal [Just AsteroidModel] [Picture] asteroidsView would have to do the following: * route the input list to a list of asteroidView signals. * When there is a Nothing in the input list, the corresponding (now exploding) view is moved to a list of zombie asteroids where it remains until its explosion animation is over. * When the input list is longer than the list of current astroidView signals, the list is extended. This would avoid the need for bookkeeping ids. Regards, Nathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
Nathan Hüsken nathan.hues...@posteo.de wrote: Actually it is very scalable, as the same map is passed to every object. It can even live in the underlying monad, which means that you could even use a mutable vector, if you wish; however, I don't recommend that. Remember that a map is immutable and shared, so passing the same map to multiple objects is in fact the same as passing a pointer in C++. Lookups in and updates to the map are of logarithmic complexity, so this scales well. Only doubling the number of nodes actually adds one full step to lookups and updates. If you're dealing with millions of objects you may want to use the vector solution mentioned earlier. This requires an imperative underlying monad, but you would get about the same speed as in C++. I might just not be used enough to functional data structures, Purely functional data structures is on my reading list :). I was thinking, in the asteroids example the only reason why the view needs more input than the models output, is that it needs to be informed of creation and destruction of asteroids. Why would the view need to be informed? So, in the model one could habe a signal asteroidsModel :: Signal Input [Just AsteroidModel] which outputs Nothing for asteroids that have been destroyed. Then, in the view this would be taken for as input for asteroidsView :: Signal [Just AsteroidModel] [Picture] asteroidsView would have to do the following: * route the input list to a list of asteroidView signals. * When there is a Nothing in the input list, the corresponding (now exploding) view is moved to a list of zombie asteroids where it remains until its explosion animation is over. * When the input list is longer than the list of current astroidView signals, the list is extended. This would avoid the need for bookkeeping ids. This is a very complicated way to do it. I would simply regard the zombie asteroids as regular objects. That way you don't need a special case in the view. Greets, Ertugrul -- Not to be or to be and (not to be or to be and (not to be or to be and (not to be or to be and ... that is the list monad. signature.asc Description: PGP signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
On 12/08/2012 10:32 AM, Heinrich Apfelmus wrote: Nathan Hüsken wrote: Heinrich Apfelmus wrote: In that light, the separation seems straightforward to me. Given the time-varying values that represent game objects, bSpaceShipPosition :: Behavior Position bAsteroidPositions :: Behavior [Position] bTime :: Behavior Time you can transform and combine them into a graphic, for instance like this bSpaceShipPicture :: Behavior Graphic bSpaceShipPicture = blinkenLights $ bTime * bSpaceShipPosition bAsteroidPictures = map drawAsteroid $ bAsteroidPositions bPicture = overlay $ ((:) $ bSpaceShipPicture * bAsteroidPictures) In other words, you just combine old time-varying values into new ones, much like you would combine combine graphical plots. Also note that you can add animation a posteriori; it doesn't have to be part of the values representing a space ship. Yes, but these examples are extremely simple. The animation has no internal state. What if every Asteroid also has a animation state (which I would want to add a posteriori) and can be destroyed. Than the connection between the asteroids game logic value, and rendering value needs some kind of bookkeeping to be maintained. Fair enough, but I don't see how this can be fitted into a general pattern. If the animation state is coupled tightly to the game logic state, then the question whether the animation is part of the game logic or not does not have a clear answer anymore. Hm. I see it like this: The logic state may not depend on the rendering state. If for example the animation of an asteroid changes how or when objects collide with it, than the animation is part of the logic. If however the physics of the game treat the asteroid as a object whose shape does not change depending in the animation, than the animation is part of the rendering state. So the coupling may only be logic-rendering. You mentioned that in an imperative setting, you would use something similar to the observer pattern. Judging from the wikipedia page http://en.wikipedia.org/wiki/Observer_pattern, it seems to me that this is just the Event type, though, so I don't understand how this helps with the problem at hand. Yes, you are right. The problem at hand is something one has to deal with when using the observer pattern. Only in C++ I do not find it hard to do. Maybe discussing a concrete example could be very helpful. Could you give a minimal example that still contains the key difficulties? Maybe a collection of asteroids that float in space, can be added or removed with a button click and who are animated as rotating rocks, all starting in a certain position when they are created? How would you use the observer pattern in this case? I put a pseudo C++ example below the mail. I use the terms model and view for the game logic and rendering respectively. The example is a little different. Asteroids explode when they collide. The moment asteroids explode, they are removed from the model (the game logic) while in the view (rendering) they still exist until the explosion animation is over. As you said, this basically is sending messages from the Model (in the observer pattern called Observable) to the view (Observer). The main difficulty I have is how to send the messages from the correct model to the correct view. In C++ this is done by keeping pointers. Simply assigning IDs would work, but than I would have to always pass a map from the model to the view, and I feel like (also I have little experience with this), that this approach is not very scalable. Best Regards, Nathan === The C++ example, its not complete, but I believe it captures the idea. class GalaxyModel { GalaxyView* view; listAsteroidModel asteroids; void addAsteroid(Position pos) { asteroids.push(AsteroidModel(pos)); view-onNewAsteroid(asteroids.back()); } void update() { for (a in asteroids) { a.update(); } for(a in asteroids) { for (b in asteroids) { if (collide(a,b)) { a.explode(); b.explode(); asteroids.remove(a); asteroids.remove(b); } } } } }; class AsteroidModel { AsteroidView* view; Position pos; update() { updatePosition(); view-onNewPos(pos); } explode() { view-onExplode(); } }; class GalaxyView { listAstroidView asteroids; void onNewAsteroid(AsteroidModel* model) { asteroids.push(AsteroidView(model)); } void update() { for (a in asteroids) { a.update(); if (a.dead) asteroids.remove(a); } } } class AsteroidView { float rotation; bool dead = false; void onExplode() { setExplodeAnimation(); } void onNewPos() { //Store position} void update() { rotation += 1.0; if (explodeAnimationOver()) { m_dead = true; } } } ___ Haskell-Cafe mailing list
Re: [Haskell-cafe] Observer pattern in haskell FRP
Nathan Hüsken nathan.hues...@posteo.de wrote: I put a pseudo C++ example below the mail. I use the terms model and view for the game logic and rendering respectively. The example is a little different. Asteroids explode when they collide. The moment asteroids explode, they are removed from the model (the game logic) while in the view (rendering) they still exist until the explosion animation is over. As you said, this basically is sending messages from the Model (in the observer pattern called Observable) to the view (Observer). The main difficulty I have is how to send the messages from the correct model to the correct view. In C++ this is done by keeping pointers. Simply assigning IDs would work, but than I would have to always pass a map from the model to the view, and I feel like (also I have little experience with this), that this approach is not very scalable. Actually it is very scalable, as the same map is passed to every object. It can even live in the underlying monad, which means that you could even use a mutable vector, if you wish; however, I don't recommend that. Remember that a map is immutable and shared, so passing the same map to multiple objects is in fact the same as passing a pointer in C++. Lookups in and updates to the map are of logarithmic complexity, so this scales well. Only doubling the number of nodes actually adds one full step to lookups and updates. If you're dealing with millions of objects you may want to use the vector solution mentioned earlier. This requires an imperative underlying monad, but you would get about the same speed as in C++. Greets, Ertugrul -- Not to be or to be and (not to be or to be and (not to be or to be and (not to be or to be and ... that is the list monad. signature.asc Description: PGP signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
Nathan Hüsken wrote: Heinrich Apfelmus wrote: In that light, the separation seems straightforward to me. Given the time-varying values that represent game objects, bSpaceShipPosition :: Behavior Position bAsteroidPositions :: Behavior [Position] bTime :: Behavior Time you can transform and combine them into a graphic, for instance like this bSpaceShipPicture :: Behavior Graphic bSpaceShipPicture = blinkenLights $ bTime * bSpaceShipPosition bAsteroidPictures = map drawAsteroid $ bAsteroidPositions bPicture = overlay $ ((:) $ bSpaceShipPicture * bAsteroidPictures) In other words, you just combine old time-varying values into new ones, much like you would combine combine graphical plots. Also note that you can add animation a posteriori; it doesn't have to be part of the values representing a space ship. Yes, but these examples are extremely simple. The animation has no internal state. What if every Asteroid also has a animation state (which I would want to add a posteriori) and can be destroyed. Than the connection between the asteroids game logic value, and rendering value needs some kind of bookkeeping to be maintained. Fair enough, but I don't see how this can be fitted into a general pattern. If the animation state is coupled tightly to the game logic state, then the question whether the animation is part of the game logic or not does not have a clear answer anymore. Hm. You mentioned that in an imperative setting, you would use something similar to the observer pattern. Judging from the wikipedia page http://en.wikipedia.org/wiki/Observer_pattern, it seems to me that this is just the Event type, though, so I don't understand how this helps with the problem at hand. Maybe discussing a concrete example could be very helpful. Could you give a minimal example that still contains the key difficulties? Maybe a collection of asteroids that float in space, can be added or removed with a button click and who are animated as rotating rocks, all starting in a certain position when they are created? How would you use the observer pattern in this case? Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
Sorry for the late reply, I somehow missed this eMail ... On 11/29/2012 06:28 PM, Heinrich Apfelmus wrote: If I take for example the breakout game from here [1]. It outputs an object scene of type Picture. But this picture is calculated from the objects ballPos and paddlePos. So first a game state (ballPos, paddlePos) is created and than transformed to something renderable. I believe all examples I have seen for games with FRP follow this pattern, and I would I want to do is seperate the steps of calculating the game state and calculating the renderable from it. In that light, the separation seems straightforward to me. Given the time-varying values that represent game objects, bSpaceShipPosition :: Behavior Position bAsteroidPositions :: Behavior [Position] bTime :: Behavior Time you can transform and combine them into a graphic, for instance like this bSpaceShipPicture :: Behavior Graphic bSpaceShipPicture = blinkenLights $ bTime * bSpaceShipPosition bAsteroidPictures = map drawAsteroid $ bAsteroidPositions bPicture = overlay $ ((:) $ bSpaceShipPicture * bAsteroidPictures) In other words, you just combine old time-varying values into new ones, much like you would combine combine graphical plots. Also note that you can add animation a posteriori; it doesn't have to be part of the values representing a space ship. Yes, but these examples are extremely simple. The animation has no internal state. What if every Asteroid also has a animation state (which I would want to add a posteriori) and can be destroyed. Than the connection between the asteroids game logic value, and rendering value needs some kind of bookkeeping to be maintained. Of course, one important question is whether to represent asteroid positions as a time-varying collection Behavior [Position] or as a collection of time-varying values [Behavior Position] . The latter form tends to require dynamic event switching, while the former form tends towards a monolithic GameState value, which would forgo many of the advantages of FRP. I don't have enough practical experience to give a useful recommendation here, but at the moment, I tend towards breaking it up as much as possible, but trying to avoid dynamic event switching. My rule of thumb is to model similar objects (asteroids) as a time-varying collection, while modeling distinct objects (player space ship) as individual behaviors. Thank you for your input! Regards, Nathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
Nathan Hüsken wrote: Heinrich Apfelmus wrote: Personally, I would recommend is a complete change in perspective. The main idea of FRP is that it is a method to describe the evolution of values in time. What is a game? It's just a picture that evolves in time. The user can exert influence on the evolution by clicking certain buttons on a mechanical device, but in the end, all he sees is a picture that moves. [..] That perspective certainly make sense. But couldn't one also describe a game as a set of entities (spaceships) that react to the clicking of buttons? Of course, generally speaking, you can describe it any way you like, FRP is just a perspective, not a dictatorial doctrine. But you probably mean that you want to describe spaceships within the FRP perspective, though independent of how they are displayed. That's a good point, which I missed. (The guideline of working backwards from the very final result has served me very well when developing in FRP style, though, hence my insistence on it.) In the FRP perspective, I would use a slightly different language, though. Namely, I would not say that spaceships are entities that react to button clicks, but rather that they are represented by time-varying positions that depend on past button clicks. The change is subtle but important: you invert the direction of control. Instead of having a button click do something to the spaceship (push), you have a spaceship whose present position depends on past button clicks (pull). The FRP perspective is also more holistic: you can think of a spaceship and other time-varying values as if you knew their values for all points in time, as if you were given graphical plots. (I have drawn a few pretty pictures in the slides linked to here http://apfelmus.nfshost.com/blog/2012/07/15-frp-tutorial-slides.html) If I take for example the breakout game from here [1]. It outputs an object scene of type Picture. But this picture is calculated from the objects ballPos and paddlePos. So first a game state (ballPos, paddlePos) is created and than transformed to something renderable. I believe all examples I have seen for games with FRP follow this pattern, and I would I want to do is seperate the steps of calculating the game state and calculating the renderable from it. In that light, the separation seems straightforward to me. Given the time-varying values that represent game objects, bSpaceShipPosition :: Behavior Position bAsteroidPositions :: Behavior [Position] bTime :: Behavior Time you can transform and combine them into a graphic, for instance like this bSpaceShipPicture :: Behavior Graphic bSpaceShipPicture = blinkenLights $ bTime * bSpaceShipPosition bAsteroidPictures = map drawAsteroid $ bAsteroidPositions bPicture = overlay $ ((:) $ bSpaceShipPicture * bAsteroidPictures) In other words, you just combine old time-varying values into new ones, much like you would combine combine graphical plots. Also note that you can add animation a posteriori; it doesn't have to be part of the values representing a space ship. Of course, one important question is whether to represent asteroid positions as a time-varying collection Behavior [Position] or as a collection of time-varying values [Behavior Position] . The latter form tends to require dynamic event switching, while the former form tends towards a monolithic GameState value, which would forgo many of the advantages of FRP. I don't have enough practical experience to give a useful recommendation here, but at the moment, I tend towards breaking it up as much as possible, but trying to avoid dynamic event switching. My rule of thumb is to model similar objects (asteroids) as a time-varying collection, while modeling distinct objects (player space ship) as individual behaviors. Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
On 11/27/2012 07:12 AM, Ertugrul Söylemez wrote: Nathan Hüsken nathan.hues...@posteo.de wrote: When writing games in other (imperative) languages, I like to separate the game logic from the rendering. For this I use something similar to the observer pattern. [...] So I am wondering: Is there (or can someone think of) a different pattern by which this could be archived? Or asked different: How would you do it? [...] As far as possible you should use a stateless monad, ideally simply Identity or a reader: type MyWire = WireM ((-) AppConfig) myApp :: MyWire a GameFrame This is only the first part of the story. The second part is the rendering itself. You certainly want a way to make use of various OpenGL extensions like vertex buffers, which are inherently stateful. One sensible way I see is not to output the game's state, but rather a state delta: myApp :: MyWire a GameDelta That way you can do the imperative stateful plumbing outside of the application's wire and get the full power of FRP without giving up efficient rendering. GameDelta itself would essentially be a type for game state commands. In fact it could be a (free) monad: myApp :: MyWire a (GameDelta ()) someDelta :: GameDelta () someDelta = do randomPos - liftA2 (,) getRandom getRandom replicateM_ 4 (addCreature randomPos) getPlayerPos = centerCamOver Then you could perform that monadic action as part of the rendering process. That sound like a good Idea. But I still have the problem of connection game logic objects with rendering objects, or am I missing something? Implementing addCreature is fine, but when I want a removeCreature, it has to remove the correct creature from a potentially very large list/set of creatures. How can I efficiently build this connections (which corresponds to a pointer in other languages, I guess)? Thanks! Nathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
Nathan Hüsken nathan.hues...@posteo.de wrote: In fact it could be a (free) monad: myApp :: MyWire a (GameDelta ()) someDelta :: GameDelta () someDelta = do randomPos - liftA2 (,) getRandom getRandom replicateM_ 4 (addCreature randomPos) getPlayerPos = centerCamOver Then you could perform that monadic action as part of the rendering process. That sound like a good Idea. But I still have the problem of connection game logic objects with rendering objects, or am I missing something? Implementing addCreature is fine, but when I want a removeCreature, it has to remove the correct creature from a potentially very large list/set of creatures. How can I efficiently build this connections (which corresponds to a pointer in other languages, I guess)? That was a simplified example. In the real world it depends on what generates your creatures. If they can be generated all over the code then you need some form of identifier generation. This can be done by the wire's underlying monad: type Identifier = Int type Game = WireM (StateT Identifier ((-) AppConfig)) A creature then may look something like this: creature :: Game World (Creature, GameDelta ()) The wire produces a creating action at the first instant, then switches to the creature's regular wire. The various GameDelta actions form at least a monoid under (), and depending on your design even a group: rec (creature1, gd1) - creature - w (creature2, gd2) - creature - w (creature3, gd3) - creature - w w - delay (World []) - World [c1, c2, c3] id - (gd1 gd2 gd3) That's the basic idea. Greets, Ertugrul -- Not to be or to be and (not to be or to be and (not to be or to be and (not to be or to be and ... that is the list monad. signature.asc Description: PGP signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
Nathan Hüsken wrote: Hey, When writing games in other (imperative) languages, I like to separate the game logic from the rendering. For this I use something similar to the observer pattern. With rendering I mean anything only related to how objects are drawn to the screen. Animation state for example. On my journey of exploring game programming with haskell (and FRP), I wonder what a good way of archiving something similar would be. [..] So I am wondering: Is there (or can someone think of) a different pattern by which this could be archived? Or asked different: How would you do it? Personally, I would recommend is a complete change in perspective. The main idea of FRP is that it is a method to describe the evolution of values in time. What is a game? It's just a picture that evolves in time. The user can exert influence on the evolution by clicking certain buttons on a mechanical device, but in the end, all he sees is a picture that moves. How to describe picture that moves? Your large picture is probably made from smaller pictures, for instance a small picture in the shape of something we often call a spaceship. So, you can implement a game by describing the evolution of smaller pictures, and then combine these into the description of a larger picture. Now, the smaller pictures tend to have hidden state, which means that their future evolution depends a lot on the past evolution of the other small pictures. In my experience with programming in FRP, it is very useful to describe the individual pictures in terms of tiny state machines and then connect these state machines via appropriate events and behaviors to each other. The essence here is to decouple the individual state machines from each other as much as possible and only then to use the FRP abstractions to connect and combine them into a large emergent state machine. (However, it is important to keep in mind that the fundamental abstraction is not a state machine, but a time evolution that remembers the past. This helps with embracing the new perspective and not accidentally fall back to previous ways of thinking. Whether that ends up with good code is up to you to find out, but if you decide to apply a new perspective, it's best to do it in an extremist way to gain the maximum benefit -- this benefit might certainly turn out to be zero, but you will never find out if you wet your feet only a little bit.) Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
On 11/27/2012 04:18 PM, Heinrich Apfelmus wrote: Nathan Hüsken wrote: Hey, When writing games in other (imperative) languages, I like to separate the game logic from the rendering. For this I use something similar to the observer pattern. With rendering I mean anything only related to how objects are drawn to the screen. Animation state for example. On my journey of exploring game programming with haskell (and FRP), I wonder what a good way of archiving something similar would be. [..] So I am wondering: Is there (or can someone think of) a different pattern by which this could be archived? Or asked different: How would you do it? Personally, I would recommend is a complete change in perspective. The main idea of FRP is that it is a method to describe the evolution of values in time. What is a game? It's just a picture that evolves in time. The user can exert influence on the evolution by clicking certain buttons on a mechanical device, but in the end, all he sees is a picture that moves. How to describe picture that moves? Your large picture is probably made from smaller pictures, for instance a small picture in the shape of something we often call a spaceship. So, you can implement a game by describing the evolution of smaller pictures, and then combine these into the description of a larger picture. Now, the smaller pictures tend to have hidden state, which means that their future evolution depends a lot on the past evolution of the other small pictures. In my experience with programming in FRP, it is very useful to describe the individual pictures in terms of tiny state machines and then connect these state machines via appropriate events and behaviors to each other. The essence here is to decouple the individual state machines from each other as much as possible and only then to use the FRP abstractions to connect and combine them into a large emergent state machine. That perspective certainly make sense. But couldn't one also describe a game as a set of entities (spaceships) that react to the clicking of buttons? If I take for example the breakout game from here [1]. It outputs an object scene of type Picture. But this picture is calculated from the objects ballPos and paddlePos. So first a game state (ballPos, paddlePos) is created and than transformed to something renderable. I believe all examples I have seen for games with FRP follow this pattern, and I would I want to do is seperate the steps of calculating the game state and calculating the renderable from it. (However, it is important to keep in mind that the fundamental abstraction is not a state machine, but a time evolution that remembers the past. This helps with embracing the new perspective and not accidentally fall back to previous ways of thinking. Whether that ends up with good code is up to you to find out, but if you decide to apply a new perspective, it's best to do it in an extremist way to gain the maximum benefit -- this benefit might certainly turn out to be zero, but you will never find out if you wet your feet only a little bit.) That certainly makes sense, and it is also very difficult for me to stick to the FRP perspective. But I do not see that seperating rendering and game logic code goes against the FRP perspective. Best Regards, Nathan [1] https://github.com/bernstein/breakout/blob/master/src/Main.hs ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in haskell FRP
Not sure, but maybe you can define a Drawable class with a method in converting inner state to something draw func could use, so it would be like this: draw :: Drawable a = a - IO () вторник, 27 ноября 2012 г. пользователь Nathan Hüsken писал: Hey, When writing games in other (imperative) languages, I like to separate the game logic from the rendering. For this I use something similar to the observer pattern. With rendering I mean anything only related to how objects are drawn to the screen. Animation state for example. On my journey of exploring game programming with haskell (and FRP), I wonder what a good way of archiving something similar would be. If the rendering has no internal state, one can just write a function draw :: GameLogicState - IO () But when the rendering of an object has an internal state (e.g. animation frame) than this is not possible. Now I could write a Wire/Signal (whatever FRP implementation I use) that translates to a RenderingState: render :: Signal GameLogicState RenderingState draw :: RenderingState - IO () which is fine, except when my game is made of many objects. Than I need to associate the state of one object in GameLogicState with a sub-signal in render. That could be done by giving every object an ID and letting GameLogicState contain a map from IDs to ObjectLogicState. I fear that when I really have a lot of objects, assembling and decomposing the map could become a major bottleneck. So I am wondering: Is there (or can someone think of) a different pattern by which this could be archived? Or asked different: How would you do it? Thanks! Nathan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org javascript:; http://www.haskell.org/mailman/listinfo/haskell-cafe -- Best Timur DeTeam Amirov Moscow, Russia ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in Haskell?
Andy Gimblett wrote: Hi all, I've been doing some GUI programming recently, using wx. To help manage dependencies between state and UI elements, I looked for a Haskell version of the Observer design pattern, and I found an implementation written by Bastiaan Heeren of ou.nl [1]. Now, before I make a hackage release: 1. Does anyone have any comments, on either version? There is no way to remove an observer, which is something I'd expect to have available. I realise this would require assigning a key to each observer (and thus perhaps storing them in an associative map) or some way to filter them, but I think if you can only ever add observers, it will get awkward. 2. In particular, is the MVar version sensible? I'm aiming for mutual exclusion between threads. I _think_ I've got it, but I'm perhaps not familiar enough with the semantics of MVar to be certain. Advice appreciated. If it _is_ sensible, then is there any reason not to just use this, and discard the IORef version? It looks fine (and thread-safe) to me, but I'd agree that you may as well just use the MVar version and leave out the IORef version. The current implementation is synchronous, in that any observer functions are called immediately and synchronously (and in the same thread as the change of subject value). I'm pondering extending the package with an asynchronous version where the update just trips a flag, and the observer function picks this up later - possibly in another thread. The idea there is to help in cases where certain operations have to be in a particular thread. But this will mean a change to the typeclass too, I guess - or the addition of another one for observers themselves. Again, any thoughts? I was a bit surprised at first that the observers were called synchronously. Asynchronous is what I'd expect, and it's also harder to code the asynchronous handlers wrongly. One blocking call (such as putMVar) in a synchronous handler can screw up your whole program by delaying the subsequent observers (and at that stage, the order in which the observers were added begins to matter). But my idea of how asynchronous would be implemented seems different to yours, judging by your description. Why not just augment this function in the synchronous version: notifyObservers :: Subject sub val = sub - IO () notifyObservers subject = do value - getValue subject observers - getObservers subject mapM_ ($ value) observers to become: notifyObserversAsync :: Subject sub val = sub - IO () notifyObserversAsync subject = do value - getValue subject observers - getObservers subject mapM_ (forkIO . ($ value)) observers This is what I was expecting to happen -- all the observer actions are spawned off into their own thread to run whatever code they want (either communicating back to an existing thread, or performing some long in-depth action). Thanks, Neil. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in Haskell?
Andy Gimblett-2 wrote: To help manage dependencies between state and UI elements, I looked for a Haskell version of the Observer design pattern Isn't Reactive Programming approach more suitable than Observer if we talk about Haskell? -- View this message in context: http://old.nabble.com/Observer-pattern-in-Haskell--tp26267269p26268135.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in Haskell?
Hi Neil, On 9 Nov 2009, at 14:50, Neil Brown wrote: 1. Does anyone have any comments, on either version? There is no way to remove an observer, which is something I'd expect to have available. I realise this would require assigning a key to each observer (and thus perhaps storing them in an associative map) or some way to filter them, but I think if you can only ever add observers, it will get awkward. Good point. This occurred to me when I referred to the Gang of Four book, while changing names for consistency. I must confess, in my current project I haven't needed it, but I see your point. 2. In particular, is the MVar version sensible? I'm aiming for mutual exclusion between threads. I _think_ I've got it, but I'm perhaps not familiar enough with the semantics of MVar to be certain. Advice appreciated. If it _is_ sensible, then is there any reason not to just use this, and discard the IORef version? It looks fine (and thread-safe) to me, but I'd agree that you may as well just use the MVar version and leave out the IORef version. Cool, thanks. was a bit surprised at first that the observers were called synchronously. Asynchronous is what I'd expect, and it's also harder to code the asynchronous handlers wrongly. One blocking call (such as putMVar) in a synchronous handler can screw up your whole program by delaying the subsequent observers (and at that stage, the order in which the observers were added begins to matter). True, but the observers shouldn't be able to access the MVars directly, I think? They should only be able to use the exposed interface, which won't let that happen? But my idea of how asynchronous would be implemented seems different to yours, judging by your description. Why not just augment this function in the synchronous version: notifyObservers :: Subject sub val = sub - IO () notifyObservers subject = do value - getValue subject observers - getObservers subject mapM_ ($ value) observers to become: notifyObserversAsync :: Subject sub val = sub - IO () notifyObserversAsync subject = do value - getValue subject observers - getObservers subject mapM_ (forkIO . ($ value)) observers This is what I was expecting to happen -- all the observer actions are spawned off into their own thread to run whatever code they want (either communicating back to an existing thread, or performing some long in-depth action). Interesting. That might be quite sensible. My thoughts have probably been coloured by how I've been doing things in wx. Ta for the suggestion. Cheers, -Andy ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in Haskell?
On 9 Nov 2009, at 15:21, Eduard Sergeev wrote: Andy Gimblett-2 wrote: To help manage dependencies between state and UI elements, I looked for a Haskell version of the Observer design pattern Isn't Reactive Programming approach more suitable than Observer if we talk about Haskell? Possibly. Care to expand? If you have a more elegant solution, which fits in well with ordinary wxHaskell, I'd be interested. Cheers, -Andy ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in Haskell?
Andy Gimblett-2 wrote: Possibly. Care to expand? If you have a more elegant solution, which fits in well with ordinary wxHaskell, I'd be interested. I believe there are a few experimental frameworks built on top of wxHaskell which use Functional Reactive Programming, like http://www.haskell.org/haskellwiki/Phooey Phooey . They seem to be more ellegant, but probably less practical for now since they are still experimental. I just thought that FRP is more suitable for Haskell but probably in case of wxHaskell it is not a case. Sorry if it was off topic. -- View this message in context: http://old.nabble.com/Observer-pattern-in-Haskell--tp26267269p26269564.html Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in Haskell?
On 9 Nov 2009, at 16:47, Eduard Sergeev wrote: Andy Gimblett-2 wrote: Possibly. Care to expand? If you have a more elegant solution, which fits in well with ordinary wxHaskell, I'd be interested. I believe there are a few experimental frameworks built on top of wxHaskell which use Functional Reactive Programming, like http://www.haskell.org/haskellwiki/Phooey Phooey . They seem to be more ellegant, but probably less practical for now since they are still experimental. I just thought that FRP is more suitable for Haskell but probably in case of wxHaskell it is not a case. Sorry if it was off topic. In that case, I am 100% in agreement with you. :-) I do look forward to using such technology in the future... Thanks! -Andy ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in Haskell?
Andy Gimblett wrote: was a bit surprised at first that the observers were called synchronously. Asynchronous is what I'd expect, and it's also harder to code the asynchronous handlers wrongly. One blocking call (such as putMVar) in a synchronous handler can screw up your whole program by delaying the subsequent observers (and at that stage, the order in which the observers were added begins to matter). True, but the observers shouldn't be able to access the MVars directly, I think? They should only be able to use the exposed interface, which won't let that happen? Just to clarify -- I meant access to another MVar. Basically, if I do this: do v - newMVar addObserver sub (putMVar v) If when the observers are run, the MVar v (that I've allocated) is non-empty, my code will block until it is empty, which will also block all the subsequent observers from being run (and block the code that called setValue) until the MVar is cleared by another thread. So my one poorly-written observer could deadlock (or cause stutter in) the system, whereas in the forkIO version, this observer would be fine -- it would block in its own new thread. Thanks, Neil. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in Haskell?
On 9 Nov 2009, at 17:41, Neil Brown wrote: Just to clarify -- I meant access to another MVar. Basically, if I do this: do v - newMVar addObserver sub (putMVar v) If when the observers are run, the MVar v (that I've allocated) is non-empty, my code will block until it is empty, which will also block all the subsequent observers from being run (and block the code that called setValue) until the MVar is cleared by another thread. So my one poorly-written observer could deadlock (or cause stutter in) the system, whereas in the forkIO version, this observer would be fine -- it would block in its own new thread. Ah yes, of course - I understand. Of course, there's nothing really to stop application authors doing such things in the main thread too... ;-) Thanks for the clarification, -Andy ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Observer pattern in Haskell?
I haven't looked at the code extensively, I just wanted to comment on this point: There is no way to remove an observer, which is something I'd expect to have available. I realise this would require assigning a key to each observer (and thus perhaps storing them in an associative map) or some way to filter them, but I think if you can only ever add observers, it will get awkward. It might be convenient to have the `addObserver` function return a detachment function as its result. At Microsoft, Erik Meijer is working on an Rx framework [1], which is an implementation of the GoF Observer pattern. The implementation is, as Erik describes it, the mathematical dual of the Enumerable pattern. In the Rx framework, the `addObserver` method returns an `IDisposable` object with a single method `dispose()`, this will detach the observer from its subject. This is more convenient than trying to remember the unique object identity of the observer (as that disallows anonymous lambdas). I don't know how this would work in a Haskell context, but it might be interesting to think about. - Tom Lokhorst [1]: http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Brian-Beckman-and-Erik-Meijer-Inside-the-NET-Reactive-Framework-Rx/ On Mon, Nov 9, 2009 at 3:50 PM, Neil Brown nc...@kent.ac.uk wrote: Andy Gimblett wrote: Hi all, I've been doing some GUI programming recently, using wx. To help manage dependencies between state and UI elements, I looked for a Haskell version of the Observer design pattern, and I found an implementation written by Bastiaan Heeren of ou.nl [1]. Now, before I make a hackage release: 1. Does anyone have any comments, on either version? There is no way to remove an observer, which is something I'd expect to have available. I realise this would require assigning a key to each observer (and thus perhaps storing them in an associative map) or some way to filter them, but I think if you can only ever add observers, it will get awkward. 2. In particular, is the MVar version sensible? I'm aiming for mutual exclusion between threads. I _think_ I've got it, but I'm perhaps not familiar enough with the semantics of MVar to be certain. Advice appreciated. If it _is_ sensible, then is there any reason not to just use this, and discard the IORef version? It looks fine (and thread-safe) to me, but I'd agree that you may as well just use the MVar version and leave out the IORef version. The current implementation is synchronous, in that any observer functions are called immediately and synchronously (and in the same thread as the change of subject value). I'm pondering extending the package with an asynchronous version where the update just trips a flag, and the observer function picks this up later - possibly in another thread. The idea there is to help in cases where certain operations have to be in a particular thread. But this will mean a change to the typeclass too, I guess - or the addition of another one for observers themselves. Again, any thoughts? I was a bit surprised at first that the observers were called synchronously. Asynchronous is what I'd expect, and it's also harder to code the asynchronous handlers wrongly. One blocking call (such as putMVar) in a synchronous handler can screw up your whole program by delaying the subsequent observers (and at that stage, the order in which the observers were added begins to matter). But my idea of how asynchronous would be implemented seems different to yours, judging by your description. Why not just augment this function in the synchronous version: notifyObservers :: Subject sub val = sub - IO () notifyObservers subject = do value - getValue subject observers - getObservers subject mapM_ ($ value) observers to become: notifyObserversAsync :: Subject sub val = sub - IO () notifyObserversAsync subject = do value - getValue subject observers - getObservers subject mapM_ (forkIO . ($ value)) observers This is what I was expecting to happen -- all the observer actions are spawned off into their own thread to run whatever code they want (either communicating back to an existing thread, or performing some long in-depth action). Thanks, Neil. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe