listobjectstackscheme

Scheme stack-like object


Trying to build a very simple stack structure :

(define (make-stack lst)
  (lambda message
    (case (car message)
      ((see) (newline) (write lst))
      ((empty?) (null? lst))
      ((push) (begin
           (set-cdr! lst (list (car lst) (cdr lst)))
           (set-car! lst (cadr message))))
      ((pop) (let ((elt (car lst)))
           (set-car! lst (cadr lst))
           (set-cdr! lst (cddr lst))
           elt)))))

I can use it with:

(define L (make-stack (list 0)))
(L 'push 1)
(L 'push 2)
(L 'see)
(newline)
(write (L' pop))
(L 'see)

But I can't init it using an empty list, that's why I init my instantiation using (list 0). How to modify make-stack procedure for it to accept initialization with an empty list?

Edit: When I pass an empty list:

;The object (), passed as the first argument to `cdr`, is not the correct type.

Solution

  • Your error is caused by calling car / cdr on empty list. You can use set!:

    (define (make-stack lst)
      (lambda message
        (case (car message)
          ((see) (newline) (write lst))
          ((empty?) (null? lst))
          ((push) (set! lst (cons (cadr message) lst)))
          ((pop) (let ((elt (car lst)))
                   (set! lst (cdr lst))
                   elt)))))
    

    You should also decide what will happen when you pop from empty stack.

    Test:

    (define L (make-stack (list)))
    (L 'see)
    (L 'push 1)
    (L 'see)
    (L 'push 2)
    (L 'see)
    (newline)
    (write (L' pop))
    (L 'see)
    

    =>

    ()
    (1)
    (2 1)
    2
    (1)