[racket] Advice: simulating stateful API in functional setting

From: Mark Engelberg (mark.engelberg at gmail.com)
Date: Sat Jul 16 00:45:54 EDT 2011

On Fri, Jul 15, 2011 at 11:56 AM, Stephen Bloch <sbloch at adelphi.edu> wrote:
> Last Monday I attended Dan Garcia's workshop on BYOB.  He kept pointing out (presumably for the benefit of Emmanuel and me) that it really is a functional language.  And yes, it has "map", "filter", "foldl", and "lambda"... but most of the examples and assignments one normally does in BYOB use very stateful turtle graphics.  So naturally I thought "Could I simulate this in universe?"
>
> I defined a sprite struct (with an icon, a location, a direction, a pen, etc.) and a world struct (with a list of sprites and a picture), and wrote a bunch of low-level operations on these that would obviously be needed.  So far so good.  I'm imagining that student code might say something like
>
>        ; zigzag : sprite -> sprite
>        (define (zigzag sprite)
>                (move 10 (rotate-cw 45 (move 10 (rotate-ccw sprite)))))
>        ...
>        (define this-sprite (make-sprite (bitmap "sprite-icon.png") (make-posn 0 0) 0 ... zigzag)
>        ...
>        (run-byob-world (list this-sprite that-sprite third-sprite) initial-background-picture)
> which would in turn call big-bang with a prewritten draw handler and a tick handler that calls each sprite's action on it.

I see you're already representing the World as a picture and a list of
sprites, so just let the kids manipulate that directly.

Since you want to support multiple sprites, what if each sprite in the
sprite list had a name, so the contract is:
move: String (sprite-name) Integer (distance) World -> World
So:
(define (zigzag sprite-name world)
  (move sprite-name 10 (rotate-cw sprite-name 45 (move sprite-name 10
(rotate-ccw sprite-name world)))))

You could also provide functions to add and delete sprites from the world.
add-sprite: String (sprite-name) Posn (start-location) World -> World
delete-sprite: String (sprite-name) World -> World

Then, give them some sort of
blank-canvas
which is a make-world that has an empty list of sprites and an empty
scene as the picture.



Posted on the users mailing list.