1

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.
Will Ness
71.6k10 gold badges105 silver badges193 bronze badges
asked Jul 9, 2025 at 16:34
2
  • 1
    So what error do you get when doing (make-pile (list))? Commented Jul 9, 2025 at 16:42
  • 1
    Open your REPL and compare (list 1 (list 2 3)) to (cons 1 (list 2 3)). And think about what you get when you add the head of a list to the tail of the same list. Commented Jul 10, 2025 at 7:23

3 Answers 3

3

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)
answered Jul 9, 2025 at 17:28
Sign up to request clarification or add additional context in comments.

2 Comments

If lst is null, (list (cadr message)) is the same as (cons (cadr message) lst)
So you don't need the if call unless you want to keep the mutating behavior when the list is not null.
3

I think you're making the structure of your stack too complicated. Just treat it as a simple list, with the first element being the top of the stack, with no messing with set-car! or set-cdr! (Which are what's stopping you from having an empty stack and which cause the bottom of the stack to be a weird nested list construct after the first push). Your methods should look like

(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)))))

Then you can actually have an empty stack:

(define L (make-stack '()))
(L 'push 1)
(L 'push 2)
(L 'see) ; (2 1), compared to your current (2 1 (0 ()))
answered Jul 9, 2025 at 19:40

1 Comment

they might have that structure as a requirement, in preparation for implementing a queue or a deque. I'm just guessing. :)
1

Just don't initialize it with an empty list. Always store one extra element in your stack.

This will simplify things greatly. Change your empty? predicate accordingly.

answered Jul 9, 2025 at 17:25

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.