[plt-scheme] Structure design, Immutable vs Mutable
I teach this functional approach to games in my CS1 course here
at Northeastern. Your game idea looks familiar and it wouldn't
pose any undue problems in the framework I have designed. See
http://www.ccs.neu.edu/home/matthias/HtDP/Prologue/book.html
for a loose description of the interface or look in Help Desk
for the world.ss teachpack.
;; ---
In this world framework, bodies -- say UFOs -- move independently
from a player -- say some tank -- on the ground. Since the
former are just time-dependent, their movement is controlled
via the per-clock-tick callback:
(lambda (world)
(make-world (world-tank world) (ufo-move* (world-ufo world))))
The latter is controlled via key events:
(lambda (world key-event)
(make-world (tank-move (world-tank world) key-event) (world-ufo
world)))
If you also want to move the tank continuously, do so with
the first callback.
;; ---
One specific point: I don't understand why you speak of subtypes
in your message. I consider this issue entirely orthogonal.
;; ---
Finally: I am also writing the second volume of HtDP (called How
to Design Classes) with this style. It turns out that in a CBPL
(aka OOPL) such an applicative (pure, functional) approach is
notationally even more economic than in a pure FPL.
-- Matthias
On Sep 26, 2007, at 1:53 PM, Henk Boom wrote:
> I'm working on a personal video game project where I have bodies which
> move around in a two dimensional world. I want to try to do this with
> immutable types because it they are something I am not yet quite used
> to using (coming from primarily imperative languages) and I'd like to
> give it a try.
>
> In general, a body can be updated for a given delta time and some
> forces which act upon it. In a mutable world, I would do:
>
> (apply-force! body force)*
> (update-body! body)
>
> With immutable structures I see that I could do:
>
> ;update-body: body number vect-2d -> body
> (update-body body dt (vect-2d+ force*))
>
> The problem is that I might have a subclass of this body which needs
> more information on update. For example, if I have a player body which
> has an orientation as well, I might need to pass it the direction the
> user wants it to face, so that it can turn towards it on the update.
> With some mutation I could do something like this:
>
> (set-player-target-direction! the-player some-direction)
> (map update-body bodies) ; the-player is in bodies so we don't need to
> do anything more
>
> Here I would use polymorphism to deal with the player turning on its
> update. How would I deal with these sorts of requirements with
> immutable structures?
>
> Another problem I see with subclasses is if I have a body method which
> moves a body by some distance.
>
> ;move-body: body vect-2d -> body
>
> This would create a new body with a changed position but all the old
> fields copied over. However, if I have a player object, I would have
> to override this method even though the behaviour for moving player is
> not that different, just because it would need to know to return a
> player instead of a body (and copy the extra fields over).
>
> I feel like there is some conceptual leap I have not made yet. Are
> there ways around these problems, or should I give up and move back to
> using mutation for this? Any suggestions would be appreciated.
>
> Henk Boom
> _________________________________________________
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme