andre
2020-7-14 09:50:00

thank you @gfb


shaffan1996
2020-7-14 13:01:41

@shaffan1996 has joined the channel


chansey97
2020-7-14 18:28:16

Is there any imperative stack in Racket? e.g. pop push ps: I am writing non-recursive parser by a push-down machine. It is very imperative. I don’t think Racket list is good data structure for this sort of thing. Thanks.


soegaard2
2020-7-14 18:52:32

(define-simple-macro (push! x a-list) (set! a-list (cons x a-list))) (define-simple-macro (pop! a-list) (begin0 (car a-list) (set! a-list (cdr a-list))) (define my-stack '())


badkins
2020-7-14 18:53:58

@chansey97 just out of curiosity, why do you feel a list is a bad data structure? I think consing onto the head of the list (e.g. push) is efficient, and using car followed by cdr is efficient for popping.


chansey97
2020-7-14 18:59:25

@badkins Because list is a functional data structure (imo) and I don’t like to embed a functional data structures in imperative code. This is like a code smell.


badkins
2020-7-14 19:00:03

Yeah, but the list doesn’t know it’s a functional data structure, so it’s cool.


soegaard2
2020-7-14 19:00:54

Single linked lists are often used in C.


soegaard2
2020-7-14 19:02:59

(And Racket lists are single linked lists)


chansey97
2020-7-14 19:04:21

In fact, I am encapsulating my own stack, using list. Like following: (struct stack ([contents #:mutable])) A mutable stack must be boxed.


chansey97
2020-7-14 19:05:53

Very strange, why the racket base library does not provide mutable stack? I have found a <https://docs.racket-lang.org/data/Imperative_Queues.html|Imperative Queues>, but no stack…


soegaard2
2020-7-14 19:06:27

If you ever need a double linked list: https://github.com/soegaard/remacs/blob/master/dlist.rkt


chansey97
2020-7-14 19:08:19

@soegaard2 Is it a functional difference list? But what I want is imperative queue…


soegaard2
2020-7-14 19:08:45

No, it’s an old school imperative double linked list.


chansey97
2020-7-14 19:17:25

I am already using Imperative Queues, fortunately it works very well. Racket data lib has a Growable Vectors, it can implement stack.


chansey97
2020-7-14 19:22:21

@badkins list know itself is a functional data structure, because it is immutable.


badkins
2020-7-14 19:43:41

Well, Racket does have a mutable cons cell, but I know what you mean. In some cases, an immutable data structure may have some disadvantages from an efficiency perspective, but given the sharing that’s possible when using lists, it may be an exception.


sorawee
2020-7-14 19:49:11

The reason there’s imperative queue but not imperative stack is that Racket list can readily be used as a stack.


chansey97
2020-7-14 20:39:34

Since Racket does not provide stack data structure:angry:, I have to write it by myself… https://github.com/chansey97/imperative-stack


chansey97
2020-7-14 20:43:03

The implementation is simple. In fact, I just copy-paste the example code from CLRS.


chansey97
2020-7-14 20:51:35

@sorawee list is not a mutable stack, a mutable stack must be boxed.


chansey97
2020-7-14 20:52:12

Imagine that if you were writing imperative code and used some mutable data structures, e.g. mutable struct, mutable queue, mutable vector, mutable tree and so on. Then you will hope mutable stack:smirk:.


sorawee
2020-7-14 21:10:34

First, Racket programmers tend to avoid mutable data structures and imperative code, so what you mentioned is not really needed


sorawee
2020-7-14 21:11:13

Second, if you are going to use one stack locally, this code also works:


sorawee
2020-7-14 21:11:27

#lang racket (define (make-stack) (define *stack* '()) (define (stack-push! e) (set! *stack* (cons e *stack*))) (define (stack-pop!) (begin0 (first *stack*) (set! *stack* (rest *stack*)))) (define (stack-peek) (first *stack*)) (define (stack-empty?) (null? *stack*)) (values stack-push! stack-pop! stack-peek stack-empty?)) (define-values (push! pop! peek empty?) (make-stack))


chansey97
2020-7-14 21:40:15

For me, Racket is not only a practical programming language, but also an experimental platform for ideas.

There are many algorithms be not functional, such as: a non-recursive Top-Down parser which use a explicit stack. (we need mutable data)


chansey97
2020-7-14 21:58:11

Thanks. I understand what you mean. I originally did the same (except that I did not use multiple values).

But using a Racket’s list as a mutable stack is a bit weird (at least from the perspective of imperative style)


notjack
2020-7-14 22:23:04

There’s mlist which is a mutable singly-linked list and is slightly closer to what you want. But yeah it’s a bit weird.