Search code examples
liststackschemer5rslifo

Implementation of LIFO list in Scheme


I'm having some trouble implementing a LIFO list in Scheme. My code works just fine if I only want to push one element on to the stack, but I want to be able to push several elements. Here is my code:

(define (make-stack)
(let ((stack '()))
    (lambda (msg . args)
      (cond ((eq? msg 'pop!)
             (set! stack (cdr stack)))
            ((eq? msg 'push!) 
             (if (= 1 (length args))
                 (set! stack (cons args stack))
                 (push stack args)))
            ((eq? msg 'stack) stack)
            (else "Not valid message!")))))
(define (push stack args)
  (if (null? args)
      stack
      (set! stack (cons (car args) stack)))
  (push stack (cdr args)))

This is just my last attempt, I've tried so many approaches that I can't keep count. I just can't understand how to get the elements out of 'args' and add them one by one to the stack. The 'push' procedure doesn't work at all, I just get an error on the last line (perhaps my recursion is wrong). As I said, this is my last attempt of many, I just can't make any sense of it.

EDIT:

I have now tried to implement push!, pop! and stack as independent procedures that take a stack object as an argument. pop! and push! were easy, but in push! the elements I want to add are already nested inside a list in push! so when I send it to the make-stack procedure it comes in as a nested list. I tried to make a recursive procedure to fix this:

(define (push! lifo . args)
   (if (null? args)
        lifo
        (lifo 'push! (car args))
   (push! lifo (cdr args))

This just goes in to a loop, and I can't see why... (recursion is a big problem for me)


Solution

  • Perhaps:

    (define (make-stack)
      (let ((stack '()))
        (lambda (msg . args)
          (cond 
            [(eq? msg 'pop!)  (set! stack (cdr stack))]
            [(eq? msg 'push!) (set! stack (append (reverse args) stack))]
            [(eq? msg 'stack) stack]
            [else "Not valid message!"]))))
    
    (define s (make-stack))
    (s 'push! 'a)
    (s 'push! 'b 'c 'd)
    (s 'stack)
    (s 'pop!)
    (s 'stack)
    

    Output:

    '(d c b a)
    '(c b a)