[gambit-list] Idiomatic Scheme

Roger Wilson misterrogerwilson at gmail.com
Wed Jan 18 19:16:57 EST 2012


Hi,

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.


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....

(define (make-name-list seed-names)

  ;; The type the list is built from
  (define-type blob-name
    name
    (random init: 0))     ; Used for sorting


    (let ((unused-name-list '()))

      (define (randomise-list)
        ; Assign each name a random number and then sort them
        (map (lambda (x) (blob-name-random-set! x (random-integer 65536)))
unused-name-list)
        (sort! unused-name-list (lambda (x y)
            (if (< (blob-name-random x) (blob-name-random y)) #t #f))))


      ;; Put all the seed names in the list
      (map (lambda (x) (push (make-blob-name x) unused-name-list))
seed-names)


      (lambda (message . arguments)
        (cond ((eq? message ':get-name!)
              (if (null? unused-name-list)
                "No names available"
                (begin
                  (let ((name (blob-name-name (car unused-name-list))))
                    (set! unused-name-list (cdr unused-name-list))
                    name))))

              ; Add a name to the list, used to return names once they're
no longer needed
              ((eq? message ':put-name!)
                  (push (make-blob-name (car arguments)) unused-name-list)
                  (randomise-list))

              ; Debug, print the internal display
              ((eq? message ':display)
                (display unused-name-list))

              (else (error 'name-list "unrecognized message"))))))


;; Test drive code.......
(define name-list (make-name-list (list "Albert" "Bruce" "Clive")))
(display (name-list ':get-name!))
(name-list ':put-name! "David")
(name-list ':put-name! "Edgar")
(name-list ':put-name! "Frederick")

(display (name-list ':display))

Some points:

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.

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.

I've years of C/C++ programming behind me, which is probably readily
apparent.

How can I improve the code?

Thanks,
Roger.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20120119/e28f5a9a/attachment.htm>


More information about the Gambit-list mailing list