Don’t understand the behavior of this code

This is an. example from “Racket Programming the Fun Way “
#lang racket
(define queue%
(class object%
(init [queue-list '()])
(define head '{})
(define tail '{})
(super-new)
(define/public (enqueue val)
(let ([t (mcons val '())])
(if (null? head)
(begin
(set! head t)
(set! tail t))
(begin
(set-mcdr! tail t)
(set! tail t)))))
(define/public (dequeue)
(if (null? head) (error "Queue is empty.")
(let ([val (mcar head)])
(set! head (mcdr head))
(when (null? head) (set! tail '()))
val)))
(define/public (print-queue)
(define (prt rest)
(if (null? rest)
(newline)
(let ([h (mcar rest)]
[t (mcdr rest)])
(printf "~a " h)
(prt t))))
(prt head))
(for ([v queue-list]) (enqueue v))))

(define queue (new queue% [queue-list '(tom dick harry)]))
(send queue print-queue)
(send queue dequeue)
'tom
(send queue enqueue 'sue)
(send queue print-queue)
(send queue dequeue)
'dick
(send queue dequeue)
'harry
(send queue dequeue)'sue
(send queue dequeue)

The result is similar to the text exept for repeating of each single name.
tom dick harry
'tom
'tom
dick harry sue
'dick
'dick
'harry
'harry
'sue
'sue
. . Queue is empty.

I have not found any errors in the code that I typed in. I have used the Macro Stepper provided and that didn’t reveal anything.

I go over each example that I run to be (sorta) sure that I understand what all of the pieces are doing and I do pretty well for a newbie wrapping my aging brain around them however, this one has me stumped , If any of you are bored please take a look and see if you spot anyything.
Cheers,
Munroe

When a text book/document for Racket contains a snippet like this:


(define queue (new queue% [queue-list '(tom dick harry)]))

(send queue print-queue)

(send queue dequeue)

; ’tom

it is trying to suggest that ’tim is the expected response. Don’t type it in, Or remove ’tom, ’dick, ’harry, and ’sue from your example and you will see the names only once.

For everyone else, here is the OP's code:

#lang racket

(define queue%
  (class object%
    (init [queue-list '()])
    
    (define head '{})
    (define tail '{})
    
    (super-new)
    
    (define/public (enqueue val)
      (let ([t (mcons val '())])
        (if (null? head)
            (begin
              (set! head t)
              (set! tail t))
            (begin
              (set-mcdr! tail t)
              (set! tail t)))))
    
    (define/public (dequeue)
      (if (null? head) (error "Queue is empty.")
          (let ([val (mcar head)])
            (set! head (mcdr head))
            (when (null? head) (set! tail '()))
            val)))
    
    (define/public (print-queue)
      (define (prt rest)
        (if (null? rest)
            (newline)
            (let ([h (mcar rest)]
                  [t (mcdr rest)])
              (printf "~a " h)
              (prt t))))
      (prt head))
    (for ([v queue-list]) (enqueue v))))

(define queue (new queue% [queue-list '(tom dick harry)]))
(send queue print-queue)
(send queue dequeue)
'tom
(send queue enqueue 'sue)
(send queue print-queue)
(send queue dequeue)
'dick
(send queue dequeue)
'harry
(send queue dequeue)'sue
(send queue dequeue)
2 Likes

As a slightly longer form explanation: all (non-void) values (of expressions) at the top level of a racket or racket/base module are printed. So placing 'tom in your program causes it to print.

Hi,

Thanks for the reply, even though it’s all rather embarrassing! I was clearly guilty of not seeing the forest because of all the trees! But what the heck it’s all part of the learning experience. :slight_smile: BTW the book is “Racket Programming the Fun Way”.

Cheers,
Munroe

2 Likes