Yes, I totally agree with Jules. The interesting part is to see how well this "scales", how easy it is to do modifications and add enhancements.

We're playing a lot with Creighton's Tetris code here at Anygma. Bob already added a preview of the next block, I changed the level tick so that the tick interval decreases continuously (meaning you can never win this Tetris game ;-) and I fixed the colors of the block (Creighton, letting white blocks fall on a white background is an interesting twitch, but rather hard to play ;-), all without too many modifications. But it is interesting to see if adding more features indeed can be done in a nice compositional way...

Peter

On Thu, Nov 20, 2008 at 8:04 AM, Jules Bean <jules@jellybean.co.uk> wrote:
Creighton Hogg wrote:
This code is still _really_ ugly, but it does work as far as I've tested

No it's not.

It's slightly ugly in places, that's all :)

Nice work!


That being said, my first real reactive program was surprisingly simple once I got comfortable with the semantics.  The actual reactive code isn't that complicated, but it did take a pretty big shift in thinking from writing explicit game loops.

I have a comment on this point, let me find the exact code:

-- This is one of the functions used to convert the event stream of keys
-- into an event stream of game state modifiers.  It makes me
-- fundamentally happy that it can be an entirely pure transformation of
-- the state instead of having to live instead a game loop.

movePiece :: Key -> Board -> (Piece -> Piece)

This is good design, but it's totally orthogonal to the use of reactive. All my conventional imperative haskell GUI programs contain at their core pure values like this (another alternative I sometimes use would be [(Key,Board -> Piece -> Piece)], accessed via Prelude.lookup). They are driven by an imperative scaffold instead of a reactive scaffold but actually isn't particularly hard - the scaffold is thin, the hard work is all in pure values like this.

The place where I believe FRP starts to really show its usefulness is in compostionality. The imperative scaffold doesn't compose as well (I don't think) as the reactive scaffold does (I hope!).

The interesting challenge to test this, I think, is to add some "modality" to your game. In particular I'm thinking of a "main menu" (that's one mode, different from playing, and presumably has different keybindings in effect), and perhaps a "game over" mode which has some kind of background animation displayed along with your final score and the option to return to the main menu.

It's in composing of different modes in this sense that I have begun to find imperative scaffolds clumsy.

Jules





_______________________________________________
Reactive mailing list
Reactive@haskell.org
http://www.haskell.org/mailman/listinfo/reactive