> From: Linas Vepstas <linasveps...@gmail.com> > > 2009/4/18 Mark Polesky <markpole...@yahoo.com>: > > Subject: passing an alist to a procedure without making a copy? > > > > (define my-alist '((a . 1)) ) > > > > (set! my-alist (acons 'b 2 my-alist)) > > > > (define (alist-prepend alist key value) > > (set! alist (acons key value alist))) > > > > (alist-prepend my-alist 'c 3) > > ________________________________ > > > > How can I get (alist-prepend) to operate > > on the original alist? > > Create a pointer to it: > > guile> (define p-list (list my-alist)) > guile> p-list > (((b . 2) (a . 1))) > guile> (define (alist-prepend palist key value) > ... (set-car! palist (acons key value (car palist)))) > guile> (alist-prepend p-list 'c 3) > guile> p-list > (((c . 3) (b . 2) (a . 1))) > > However, this seems like an awkward way of doing > things; I'm thinking that you are bringing a > C/perl/python/java mindset to scheme, and that will > hobble you in general. For starters, always think > "how can I solve this problem without using set! > (or set-car!, or any kind of set!)" > > --linas >
The answer that Linas gives is totally correct. But I notice the subject line of the original question has to do with avoiding a copy, which makes me think that the awkward desire arises from a misunderstanding of when a copy happens. This makes only one list of numbers and never copies it: (define (upto N) (define (consdown k ls) (if (zero? k) ls (consdown (- k 1) (cons k ls)) )) (consdown N '()) ) (define a (upto 5)) (define b a) (define c b) (list a b c) ==> ((1 2 3 4 5) (1 2 3 4 5) (1 2 3 4 5)) The numbers upto 5 will be found only once in memory, even though they have each been printed three times, and are part of the value of three variables. The recursive definition of (upto N) will be run with no extra space no matter how big N is. (That is, only a small fixed amount of space beyond that required to store one copy of the result.) -- Keith