Hi,<div><br></div><div>I'm still using Gambit Scheme from time to time and having a lot of fun with it.  I've a newbie question however, I'm trying to figure out the best way to structure code.  With that in mind are there any comments on the following code?  I'm trying to create an 'object' that holds a list of names, can return a random one on request that can later be returned to it.  </div>
<div><br></div><div>What's the proper Scheme way of doing this kind of thing?  Here's my stab, it returns a function that then accepts 'messages' as parameters....</div><div><br></div><div><div><div>(define (make-name-list seed-names)</div>
<div>  </div><div>  ;; The type the list is built from</div><div>  (define-type blob-name</div><div>    name</div><div>    (random init: 0))     ; Used for sorting</div><div><br></div><div><br></div><div>    (let ((unused-name-list '()))</div>
<div><br></div><div>      (define (randomise-list)  </div><div>        ; Assign each name a random number and then sort them      </div><div>        (map (lambda (x) (blob-name-random-set! x (random-integer 65536))) unused-name-list)</div>
<div>        (sort! unused-name-list (lambda (x y) </div><div>            (if (< (blob-name-random x) (blob-name-random y)) #t #f))))</div><div><br></div><div><br></div><div>      ;; Put all the seed names in the list</div>
<div>      (map (lambda (x) (push (make-blob-name x) unused-name-list)) seed-names)</div><div>    </div><div><br></div><div>      (lambda (message . arguments)</div><div>        (cond ((eq? message ':get-name!)</div><div>
              (if (null? unused-name-list)</div><div>                "No names available"</div><div>                (begin</div><div>                  (let ((name (blob-name-name (car unused-name-list))))</div><div>
                    (set! unused-name-list (cdr unused-name-list))</div><div>                    name))))  </div><div><br></div><div>              ; Add a name to the list, used to return names once they're no longer needed      </div>
<div>              ((eq? message ':put-name!)</div><div>                  (push (make-blob-name (car arguments)) unused-name-list)</div><div>                  (randomise-list))</div><div><br></div><div>              ; Debug, print the internal display    </div>
<div>              ((eq? message ':display)</div><div>                (display unused-name-list))</div><div><br></div><div>              (else (error 'name-list "unrecognized message"))))))</div></div><div>
<br></div><div><br></div><div>;; Test drive code.......</div><div>(define name-list (make-name-list (list "Albert" "Bruce" "Clive")))</div><div>(display (name-list ':get-name!))</div><div>
(name-list ':put-name! "David")</div><div>(name-list ':put-name! "Edgar")</div><div>(name-list ':put-name! "Frederick")</div><div><br></div><div>(display (name-list ':display))</div>
<div><br></div></div><div>Some points:</div><div><br></div><div>In particular I'm unhappy with the way the message arguments are accessed as (car arguments) rather than by explicit name.  I can see that being a potential cause of bugs if the number of arguments grows and they vary with each message.</div>
<div><br></div><div>I realise that the randomise-list function is probably called too often and maintaining a 'dirty bit' would allow it to be only called when necessary when getting a name.</div><div><br></div><div>
I've years of C/C++ programming behind me, which is probably readily apparent.  </div><div><br></div><div>How can I improve the code?</div><div><br></div><div>Thanks,</div><div>Roger.</div>