[racket] Advice: simulating stateful API in functional setting

From: Stephen Bloch (sbloch at adelphi.edu)
Date: Sat Jul 16 10:25:04 EDT 2011

Carl Eastlund wrote:

> Why is affecting the sprite "functional" and affecting the picture
> "imperative"?  Any part of a program can be mutated imperatively, and
> likewise any part of a program can be passed around functionally.  If
> you need to modify the picture, why not pass around the picture as
> part of the world?  (Or at least enough information about changes to
> the picture to reconstruct it as needed.)

Nadeem Abdul Hamid wrote:
>  Why don't you just have the picture generated based on the state of the sprite each tick of the animation, just as in HtDP "world"? Functions like move, rotate, etc. produce a modified sprite, and when that sprite gets passed to the draw handler, the draw handler produces a new image of the world based on that state.

Mark Engelberg wrote:
> My instinct is to go for the sprite+picture world representation.  The
> draw handler just draws the picture held in the world representation
> overlaid with the sprite at its desired location.  The other movement
> functions both update the sprite part of the world struct and the
> picture part of the world struct (when the pen is down).

The answer to all three is "there might be multiple sprites."  Some operations (like "rotate", "pen-up", etc.) are really operations on a sprite, and can reasonably return a slightly-different sprite.  Others (like "move") affect both the sprite and the world picture.  A very few (like "clear") affect only the world picture, but there would be no harm in thinking of them as sprite operations that don't happen to change the sprite at all.  If I just return a sprite, I don't know how to get the drawing side effects.  If I return a world, I don't know how best to specify which sprite is supposed to do the operation, or what to do if the sprite in question isn't IN that world.

This would indeed be a lot simpler if there were only one sprite in a world, but that eliminates a lot of the cool multi-agent examples one can do in BYOB.

Stephen Bloch
sbloch at adelphi.edu

Posted on the users mailing list.