simulation in the haskell way

Hello, Haskellers! I'm relatively new to haskell and due to my strong imperative background, it's really a pain to learn haskell. But I'm really indulged in it. :) Now I think I understand the basics of Haskell very well, such as the type system and monad. And for those data-flow kind of applications, I can easily structure the problem in a functional way and sketch out an intuitive picture of the computation. But for simulation kind-of problems, in which I think OO really fits the best, what's the haskell way to structure such problems? I once thought maybe I can use the State monad to simulate objects. But it's really hard for me to implement, because I think State monad is used to simulate a global shared state, is it right? Then what's the best way to simulate private states or just instead how to solve simulation problems such as a physical engine using the haskell way? Best regards. Eric

Eric Wong
I'm relatively new to haskell and due to my strong imperative background, it's really a pain to learn haskell. But I'm really indulged in it. :)
Now I think I understand the basics of Haskell very well, such as the type system and monad. And for those data-flow kind of applications, I can easily structure the problem in a functional way and sketch out an intuitive picture of the computation. But for simulation kind-of problems, in which I think OO really fits the best, what's the haskell way to structure such problems? I once thought maybe I can use the State monad to simulate objects. But it's really hard for me to implement, because I think State monad is used to simulate a global shared state, is it right?
Then what's the best way to simulate private states or just instead how to solve simulation problems such as a physical engine using the haskell way?
A state monad is used to encode a stateful computation. Whether its state is global or not really only depends on how long the computation lives. Here is how you can use one to maintain a list of objects: computation :: State [Object] Result computation = do objs0 <- get (result, objs1) <- doSomethingWith objs0 put objs1 return result This is really just a convenient encoding of: computation :: [Object] -> (Result, [Object]) Whether that [Object] state is global really only depends on where you use evalState, execState or runState and how long the computation takes. I often do something like this, which you can regard as global 'state' (or rather a global environment): type AppIO = ReaderT AppConfig IO myApp :: AppIO () myApp = ... main :: IO () main = getAppConfig >>= evalStateT myApp Greets, Ertugrul. -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/

Ertugrul Soeylemez
computation :: State [Object] Result computation = do objs0 <- get (result, objs1) <- doSomethingWith objs0 put objs1 return result
Misindented, sorry. Again: computation :: State [Object] Result computation = do objs0 <- get (result, objs1) <- doSomethingWith objs0 put objs1 return result Greets, Ertugrul. -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/

You need to look into functional reactive programming, but be warned, this
is active research :-)
Two libraries I know of in which you can currently make working simulations
are Yampa and Elerea. But the former doesn't scale really well, and the
latter might not really be functional (I think it's not referentially
transparent)
Other libraries such as Reactive and Grapefruit are very promising, but I
don't know their current status.
Good luck. For me (I'm also an experienced imperative programmer in the
simulation field), Haskell is very addictive, but also insanely frustrating
because I never have the feeling I know the language well enough and I don't
see the big picture yet. So I can't yet achieve in Haskell what I can in
other languages, but purity and laziness are drugs, so you're doomed :-)
On Tue, Aug 18, 2009 at 2:42 PM, Eric Wong
Hello, Haskellers!
I'm relatively new to haskell and due to my strong imperative background, it's really a pain to learn haskell. But I'm really indulged in it. :)
Now I think I understand the basics of Haskell very well, such as the type system and monad. And for those data-flow kind of applications, I can easily structure the problem in a functional way and sketch out an intuitive picture of the computation. But for simulation kind-of problems, in which I think OO really fits the best, what's the haskell way to structure such problems? I once thought maybe I can use the State monad to simulate objects. But it's really hard for me to implement, because I think State monad is used to simulate a global shared state, is it right?
Then what's the best way to simulate private states or just instead how to solve simulation problems such as a physical engine using the haskell way?
Best regards. Eric _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

...) But for simulation kind-of problems, in which I think OO really fits the best, what's the haskell way to structure such problems? I once thought maybe I can use the State monad to simulate objects. But it's really hard for me to implement, because I think State monad is used to simulate a global shared state, is it right?
Then what's the best way to simulate private states or just instead how to solve simulation problems such as a physical engine using the haskell way?
A physical engine can be simulated using pure code, with a function from timestep to state. (Of course, that doesn't hold when you want to deal with user interaction.) I think there is no general answer to your question. My sugestion is to describe an example you would like to work with. Maurício

On Tuesday 18 August 2009, Maurício CA wrote:
...) But for simulation kind-of problems, in which I think OO really fits the best, what's the haskell way to structure such problems? I once thought maybe I can use the State monad to simulate objects. But it's really hard for me to implement, because I think State monad is used to simulate a global shared state, is it right?
Then what's the best way to simulate private states or just instead how to solve simulation problems such as a physical engine using the haskell way?
A physical engine can be simulated using pure code, with a function from timestep to state. (Of course, that doesn't hold when you want to deal with user interaction.) I think there is no general answer to your question. My sugestion is to describe an example you would like to work with.
Hi, I did a medium sized mobility models simulator this way. The simulation is represented as an infinite list of states, where the next state is created by applying a state transformation ("next") function to the previous state. This has the advantage that you can calculate values based on more than one state. The downside is that if you need to look back 100 stesp, you need to remember 100 states (though if enough of it is unchanged and shared then it's not really that much of a problem). As far as the details go -- different parts of the simulator are executed in different monads. "god-mode" code, like the "next" function has the type nextStep :: World -> World but the mobility model implementation (which tells a node how to move) is a stateful computation run by nextStep: mobilityModel :: StateT NodeState (Reader World) () But as Maurício said -- please describe what you want to achieve. At least what kind of simulation you'd like to write. -- Thanks! Marcin Kosiba

I used to think about a physical engine in a similar way, and I think it can work. But in some simulations that objects have lots of dependencies on others can be tricky. For instance, object o1 depends on o2, if we represent them in pure values, when we update o2, then o1 must be updated with a new o2 value, isn't it? Recently I want to implement the digital circuit simulation in SICP using Haskell as an exercise. In the Scheme version, each Wire is represented as a function with local states. It records the signal on the wire and actions it will take when the signal changes to activate other wires. How to represent the Wire in haskell purely? If I use State Monad (yes, it's pure :) to repsent a wire with local state, the interaction between connected wires is really tricky to implement. any ideas? thanks. Eric

You could read:
http://www.cs.nott.ac.uk/~nhn/FoPAD2007/Talks/nhn-FoPAD2007.pdf
http://haskell.cs.yale.edu/yale/papers/haskell-workshop03/yampa-arcade.pdf
http://www.cs.nott.ac.uk/~nhn/Talks/HW2002-FRPContinued.pdf
http://www.haskell.org/yale/papers/haskellworkshop02/index.html
http://www.haskell.org/haskellwiki/Frag
Basically, even in an imperative solution, if you have complex dependencies
between objects at the same time T, then my experience tells me your into
trouble, it's better to make all objects at time T depend on the state of
other objects at time T-dT. If you absolutely need to know at time T what
the state of another object is at time T, the network of dependencies needs
to be rearranged dynamically, and you might get different results (or
endless loops if you do it badly) in the case of mutual dependencies. This
is what Elerea does.
On Wed, Aug 19, 2009 at 12:40 AM, Eric Wong
I used to think about a physical engine in a similar way, and I think it can work. But in some simulations that objects have lots of dependencies on others can be tricky. For instance, object o1 depends on o2, if we represent them in pure values, when we update o2, then o1 must be updated with a new o2 value, isn't it?
Recently I want to implement the digital circuit simulation in SICP using Haskell as an exercise. In the Scheme version, each Wire is represented as a function with local states. It records the signal on the wire and actions it will take when the signal changes to activate other wires. How to represent the Wire in haskell purely?
If I use State Monad (yes, it's pure :) to repsent a wire with local state, the interaction between connected wires is really tricky to implement. any ideas?
thanks. Eric _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Eric Wong
I used to think about a physical engine in a similar way, and I think it can work. But in some simulations that objects have lots of dependencies on others can be tricky. For instance, object o1 depends on o2, if we represent them in pure values, when we update o2, then o1 must be updated with a new o2 value, isn't it?
This is something handled best by functional reactive programming. See Peter Verswyvelen's post. It allows you to encode this purely in an excitingly elegant way.
Recently I want to implement the digital circuit simulation in SICP using Haskell as an exercise. In the Scheme version, each Wire is represented as a function with local states. It records the signal on the wire and actions it will take when the signal changes to activate other wires. How to represent the Wire in haskell purely?
If I use State Monad (yes, it's pure :) to repsent a wire with local state, the interaction between connected wires is really tricky to implement. any ideas?
You don't. Either you use a state monad to hold _all_ wires (objects) in, say, a Map, a Set or an Array, or you use a completely different approach (like FRP). In other words, your state monad should represent all wires, not just one, because all wires together make up the state you want to work with. Greets, Ertugrul. -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/

It is interesting to note that recent work on AFRP (arrow-based FRP) -
namely "Causal Commutative Arrows" - optimizes a complete circuit of arrows
("interconnected objects" if you prefer to think that way) that all have
local state and local feedback loops into one large state and feedback loop,
essentially what optimized imperative simulations also do (e.g. thousands
of moving particles that are treated as a single state block of
position/velocity pairs). Together with stream fusion the researchers
working on this were able to generate optimized code that runs hundreds
(!!!) times faster than the best GHC could do. Impressive isn't it.
Unfortunately it will only work on static networks, not those with dynamic
switches in it, but I'm pretty sure that within say 5 years, this will all
be settled and it will become exiting times for simulation developers, we
will finally be pure, lazy *and* fast; it just needs a little push (since
it's now mostly pulling, okay I'll stop the nonsense, couldn't resist the
nerd talk ;-)
On Wed, Aug 19, 2009 at 1:29 AM, Ertugrul Soeylemez
Eric Wong
wrote: I used to think about a physical engine in a similar way, and I think it can work. But in some simulations that objects have lots of dependencies on others can be tricky. For instance, object o1 depends on o2, if we represent them in pure values, when we update o2, then o1 must be updated with a new o2 value, isn't it?
This is something handled best by functional reactive programming. See Peter Verswyvelen's post. It allows you to encode this purely in an excitingly elegant way.
Recently I want to implement the digital circuit simulation in SICP using Haskell as an exercise. In the Scheme version, each Wire is represented as a function with local states. It records the signal on the wire and actions it will take when the signal changes to activate other wires. How to represent the Wire in haskell purely?
If I use State Monad (yes, it's pure :) to repsent a wire with local state, the interaction between connected wires is really tricky to implement. any ideas?
You don't. Either you use a state monad to hold _all_ wires (objects) in, say, a Map, a Set or an Array, or you use a completely different approach (like FRP). In other words, your state monad should represent all wires, not just one, because all wires together make up the state you want to work with.
Greets, Ertugrul.
-- nightmare = unsafePerformIO (getWrongWife >>= sex) http://blog.ertes.de/
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Thanks for all your post. When I was using C and Python, I used to think of most applications in an simulation way. I think it's right to say that programs are simulations. But now I have to change my mind in Haskell, I have to think in a data-flow way, that is: data in, processing using function composition, data out. Even true simulation should be seen in such a perspective, right? And of course, I have to learn about FRP. Thanks, Eric

By "simulation way", do you mean "object-oriented way"? they are similar, but not equal, I think. OO is great for simulation, but simulation does not necessarily use OO. Virtual machine simulates real machines, you can use OO language to do it, but most use C in the real world I think. So, simulation way is more like an imperative way.
But it also relates to what do you mean by "simulation". If we are simulating things in the physics world, then it's most likely imperative, and most of the time an OO way. Because the physics world are more natrual in such a perspective. But if we are simulating the way people doing things, it may not necessarily be imperative. For instance Mathematics, It's more natural to simulate in a functional way.

Sorry for a mistake. "Shiyou Wang" is my identity in a private chinese group. Sorry for the confusing. :-( Eric

On Tue, Aug 18, 2009 at 5:19 PM, Eric Wong
Thanks for all your post.
When I was using C and Python, I used to think of most applications in an simulation way. I think it's right to say that programs are simulations.
On a philosophical note, this is a sign of expertise. Humans tend to think of the world, and things in, in the way that they understand things in their area of expertise. If you develop expertise in Haskell (or FP in general) you will like begin to see things in functional ways. Jason

When I was using C and Python, I used to think of most applications in an simulation way. I think it's right to say that programs are simulations. But now I have to change my mind in Haskell, I have to think in a data-flow way, that is: data in, processing using function composition, data out.
You have to think there's no in and out, since there's no state and so no before and after. And no flow, since time is just an ilusion of users. In Haskell, a program just "is". Sorry, could not resist the Jedi talk... Hope you like the language. Best, Maurício

I don't really agree that in Haskell when it comes to simulation a program
"just is". That is the idealized story.
At least when writing your own simulation engine, in practice you have to
deal with operational details such as future unknown values that can block
computations; to much laziness can cause hickups in the framerate since
unobserved computations build up over time (a bit like sum does) which is
why most Yampa simulations I've seen mark all the outputs deep strict (so
even the end user needs to know about the operational details); binding to
the head of signals and signal recursion causes space and time leaks, and
that's why Yampa doesn't provide first signals, which in turn gives problems
with inefficiency regarding too much redundant evaluation, etc...
*Wolfgang *Jeltsch is working on a PhD thesis for Grapefruit in which I hope
all problems with FRP will be nicely documented, since currently there
doesn't seem to be clear literature that tells the whole story with
pros/cons of each framework.
I even believe Luke Palmer abandoned Haskell for doing FRP and started
inventing his own language "Dana"; see http://lukepalmer.wordpress.com
And of course Conal Elliot's blog outlines some of the problems and beauties
of his latest FRP system (Reactive)
So it's not all sunshine and roses, but that's also what makes it
interesting :)
2009/8/19 Maurício CA
When I was using C and Python, I used to think of most applications in an
simulation way. I think it's right to say that programs are simulations. But now I have to change my mind in Haskell, I have to think in a data-flow way, that is: data in, processing using function composition, data out.
You have to think there's no in and out, since there's no state and so no before and after. And no flow, since time is just an ilusion of users. In Haskell, a program just "is".
Sorry, could not resist the Jedi talk...
Hope you like the language. Best, Maurício
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Then what's the best way to simulate private states or just instead how to solve simulation problems such as a physical engine using the haskell way?
perhaps Hipmunk ? http://hackage.haskell.org/package/Hipmunk
participants (9)
-
Eric Wong
-
Ertugrul Soeylemez
-
Jason Dagit
-
Jason Dusek
-
jean legrand
-
Marcin Kosiba
-
Maurício CA
-
Peter Verswyvelen
-
Shiyou Wang