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

