[racket] Functional struct update with subtypes

From: David Van Horn (dvanhorn at ccs.neu.edu)
Date: Wed May 11 16:10:25 EDT 2011

On 5/11/11 4:03 PM, Nadeem Abdul Hamid wrote:
> On Wed, May 11, 2011 at 3:45 PM, David Van Horn<dvanhorn at ccs.neu.edu>  wrote:
>> Is there a good way to do a functional struct updates with subtypes of a
>> structure?
>
> There was some discussion about it a while ago in reference to
> struct-copy. The documentation has been updated with some useful
> examples, including usage of the new #parent parameter:
> http://docs.racket-lang.org/reference/struct-copy.html

I actually fat-fingered sending that email, so let me give some more 
context.  The #:parent parameter doesn't really help me.

Here are some struct definitions and a function, based on Land of Lisp:

(struct monster (id [hit #:mutable]) #:transparent)
(struct orc monster (club) #:transparent)
(struct hydra monster () #:transparent)
(struct slime monster (sliminess) #:transparent)
(struct brigand monster () #:transparent)

(define (damage! m n)
   (set-monster-hit! m (max 0 (- (monster-hit m) n))))

I'd like to write a functional version of damage!, but it looks like I 
can't.  The best I can do is write an ugly, not-really-generic version 
like this:

(define (damage m n)
   (let ((h (max 0 (- (monster-hit m) n))))
     (cond [(orc? m) (struct-copy orc m [hit #:parent monster h])]
           [(hydra? m) (struct-copy hydra m [hit #:parent monster h])]
           [(slime? m) (struct-copy slime m [hit #:parent monster h])]
           [(brigand? m) (struct-copy brigand m [hit #:parent monster 
h])])))

David


Posted on the users mailing list.