This sounds like a game development reference that I'm missing. Can anyone explain?
This sounds like a game development reference that I'm missing. Can anyone explain?
This is a hugely successful pattern throughout a number of aspects of gaming, graphics being one of the most classic examples. Double-buffered graphics don't suffer as much from tearing and other display artifacts.
Not really, no. Immutability comes at the cost of performance compared to mutability. The gap is shrinking between the two, but it's still wide enough that using pure immutable structures for frame buffers, shaders and other graphical concepts is simply not an option to write games.
Haskell is interesting in the sense that it doesn't prevent you from using mutable structures (e.g. Lenses, Writer) but it encodes this information in the type system. I'm really curious to read the conclusions that Carmack will draw from his experience but I wouldn't be surprised to read that at the very low levels, mutable structures are just unavoidable for high performance games.
Also, mutable structures accessed by concurrent threads is a problem that's much less difficult than most people claim, and it's often much easier to reason about locks and semaphores than about immutable lazily initialized structures.
> using pure immutable structures for frame buffers, shaders and other graphical concepts is simply not an option to write games.
Seeing as people have written games in Haskell, this is clearly not true.
> Haskell is interesting in the sense that it doesn't prevent you from using mutable structures (e.g. Lenses, Writer)
Lenses and Writer both only use immutable data. It is possible to use actual mutable data in the ST and IO monads.
> but it encodes this information in the type system.
This is true of IO, but not of ST. With ST, runST :: (forall s. ST s a) -> a, hides the effects.
> it's often much easier to reason about locks and semaphores than about immutable lazily initialized structures.
I don't know what you mean by this. In terms of functional correctness, immutable data-strucutures, lazy or otherwise, are much easier to reason about. If you are talking about resource-usage, sure, it's a little harder to reason about lazy data-structures than strict ones, but give me a space leak over a race condition to track down any day.
Not really. There's no question whatsoever that GHC can run a fine Wolf3D on fractions of a modern hardware setup. You could do it in pure Python with no NumPy. There's tools to help with the laziness stuff and a 3D rendering loop will fit those perfectly.
But the performance limits of immutable structures for simulation and graphics are certainly interesting to me.
Not really, 3d rendering in haskell via opengl is not new or interesting at this point. Frag is 8 years old for example: http://www.haskell.org/haskellwiki/Frag
You can even stream textures asynchronously using PBOs (pixel buffer objects), and use dual PBOs like double buffers (or using copy-on-write techniques to only re-upload dirty rectangles...)
[edit: If I'm wrong... ouch. But it's been a while.]
Games often want physics/model threads run with a consistent timestep, but have the rendering thread run as fast as possible.