The holiday season: time to grade lots of projects, and "goof off" by thinking about how those programs could better be expressed.
Here's a world/universe program written by one team in my class. It uses mutation all over the place: #lang racket (require (except-in (planet clements/rsound) overlay scale) 2htdp/universe 2htdp/image) (define octave 48) (define volume .4) (define duration 22050) (define (my-draw num) (empty-scene 100 100)) (define (my-key world key) (begin (cond [(equal? key "0") (set! octave 0)] [(equal? key "1") (set! octave 12)] [(equal? key "2") (set! octave 24)] [(equal? key "3") (set! octave 36)] [(equal? key "4") (set! octave 48)] [(equal? key "5") (set! octave 60)] [(equal? key "6") (set! octave 72)] [(equal? key "7") (set! octave 84)] [(equal? key "8") (set! octave 96)] [(or (equal? key "=") (equal? key "+")) (if (< volume 1) (set! volume (+ volume .1)) (set! volume volume))] [(or (equal? key "-") (equal? key "_")) (if (> volume 0) (set! volume (- volume .1)) (set! volume volume))] [(equal? key "z") (if (> duration 11025) (set! duration (- duration 11025)) (set! duration duration))] [(equal? key "x") (if (< duration 88200) (set! duration (+ duration 11025)) (set! duration duration))] [(equal? key "q") (play (make-tone (midi-note-num->pitch (+ 12 octave)) volume duration))] [(equal? key "w") (play (make-tone (midi-note-num->pitch (+ 13 octave)) volume duration))] [(equal? key "e") (play (make-tone (midi-note-num->pitch (+ 14 octave)) volume duration))] [(equal? key "r") (play (make-tone (midi-note-num->pitch (+ 15 octave)) volume duration))] [(equal? key "t") (play (make-tone (midi-note-num->pitch (+ 16 octave)) volume duration))] [(equal? key "y") (play (make-tone (midi-note-num->pitch (+ 17 octave)) volume duration))] [(equal? key "u") (play (make-tone (midi-note-num->pitch (+ 18 octave)) volume duration))] [(equal? key "i") (play (make-tone (midi-note-num->pitch (+ 19 octave)) volume duration))] [(equal? key "o") (play (make-tone (midi-note-num->pitch (+ 20 octave)) volume duration))] [(equal? key "p") (play (make-tone (midi-note-num->pitch (+ 21 octave)) volume duration))] [(equal? key "[") (play (make-tone (midi-note-num->pitch (+ 22 octave)) volume duration))] [(equal? key "]") (play (make-tone (midi-note-num->pitch (+ 23 octave)) volume duration))] [(equal? key "a") (play c-hi-hat-1)] [(equal? key "s") (play c-hi-hat-2)] [(equal? key "d") (play o-hi-hat)] [(equal? key "f") (play snare)] [(equal? key "g") (play bassdrum)] [(equal? key "h") (play bassdrum)] [(equal? key "j") (play bassdrum-synth)] [(equal? key "k") (play clap-1)] [(equal? key "l") (play clap-2)] [(equal? key ";") (play crash-cymbal)] [else #f]) 0)) (big-bang 0 (to-draw my-draw) (on-key my-key)) Standard functional update observation: This is definitely the natural way to write the program: certain keypresses correspond to certain changes in the state of the world, and the rest stays the same. New part? What if a world function could produce a list of "state change instructions"; something like (list (change world-volume 54) (change octave 34)). The caller of world can interpret this state change as a functional update. I see this as having an advantage over functional update in that the world doesn't require an explicit reference, and there's no chaining for multiple updates. Random connection: It occurs to me that this is essentially using the I/O monad for state. That is, evaluation of the function gets a single world to work with, and is unable to update it, but can produce a list of changes to be applied when the function returns. Thanks for letting me ramble, John
smime.p7s
Description: S/MIME cryptographic signature
_________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users