Reputation: 13
I've a problem about keeping a list in the memory without using set!
I have an initial empty list defined,
(define database (list))
then I have this procedure which checks if the password is correct and adds the pair to the list.
(define (set-pass l)
(if (pair? l)
(if (check-pass (second (last l)))
(add-to-list l)
"password does not meet policy requirements"
)
"invalid input"
)
)
And a add-to-list procedure:
(define (add-to-list l)
;(append database l)
;implement this.
)
Problem is, I have to call this procedure multiple times:
(set-pass '('john '(X p c F z C b Y h 1 2 3 4 : :)))
(set-pass '('john '(X p c F z C b Y : 1 2 3 4 : :)))
(set-pass '('john '(X p c F z C b : : 1 2 3 4 : :)))
I implemented the procedure add-to-list like I'm calling set-pass once (with append as shown above), but I couldn't find a way to implement if I call it multiple times. I tried a few things mentioned here, here and here. But I couldn't achieve what I wanted. So how can I do this?
Upvotes: 1
Views: 178
Reputation: 48745
It's possible to do this functionally by having the database as a variable:
(let loop ((input (read-line)) (database '()))
(display (format "inserting ~a\n" input))
(loop (read-line)
(cons input database)))
The other features (removing etc) work the same way you as recur with the altered structure according the operation.
You can also update a list with set-cdr!
. While set!
mutates what a symbol points to, set-cdr!
mutates the cdr
of a pair. Since it needs to be a pair you need to have the first element be some dummy data:
(define database (list "head"))
(define (add element)
(let ((tmp (cdr database)))
(set-cdr! database (cons element tmp))))
(define (delete element)
(let loop ((prev database) (cur (cdr database)))
(cond ((null? cur) #f)
((equal? (car cur) element)
(set-cdr! prev (cdr cur)))
(else (loop cur (cdr cur))))))
(define (get)
(cdr database))
(add 1)
(add 2)
(add 3)
(get) ; ==> (3 2 1)
(delete 2)
(get) ; ==> (3 1)
The second you allow mutation the cat is out of the bag and all mutation is available. Eg. you can make a mutable object with closures if set!
is provided and you can get mutable bindings with boxes if set-car!
/set-cdr!
is provided.
Upvotes: 1