[plt-scheme] vectors by value
All functions are call by value in Scheme (but this might not mean what
you mean below).
set! changes the association of a value and a variable -- it does not
do anything to the value itself. For example:
(define x 1)
(define y x) ;; bind the variable y to whatever x evaluates to (1 in this case)
(set! y 3) ;; change y so it refers to 3 instead of 1
This same example above works with *any* kind of Scheme value, vectors,
numbers, cons cells, the empty list, functions, anything. Even tho I
just show it with numbers above, you can try it with any value you want.
Also, set! doesn't care if the variable is a variable in a define or a
variable that is a function argument -- it just changes what the
variable stands for, the values themselves don't change.
vector-set! on the other hand, only applies to vectors. It change the
elements of the vector.
As a (perhaps poor) analogy, set! is like going down the courhouse to
change your name, but vector-set! is like being punched. In one case
you change what things refer to and the other you change the things
themselves.
If this doesn't help, please check out http://www.htdp.org/ and read
part vii (changing the state of variables) and viii (changing compound
values).
As far as your final question goes, I don't think that you need to use
mutation at all (ie, no exclamation points). Instead, just create a new
list. Here is an example:
;; 2to3lst : (listof number) -> (listof number)
;; build a new list, where all 2s in the list are now 3s
(define (2to3lst l)
(cond
[(null? l) null]
[else (let ([n (car l)])
(if (= n 2)
(cons 3 (2to3lst (cdr l)))
(cons n (2to3lst (cdr l)))))]))
or, just:
(define (2to3lst l) (map 2to3 l))
(define (2to3 x) (if (= x 2) 3 x))
If you want to return a list with variations of the vectors in it, you
can just write a function that calclates the variations on the vectors
and then use the above techniques to apply it to a list. For example:
(define (square-elements v)
(apply vector (map square (vector->list v))))
(define (square x) (* x x))
(map square-element ...)
Hope that helps.
Robby
At Fri, 7 Feb 2003 19:26:49 -0700, "John T. Murphy" wrote:
> For list-related administrative tasks:
> http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
> This is probably a newbie question...
>
> With the following executed in the definitions window:
>
> (define mylist '(hi there))
> (define changemylist
> (lambda (x)
> (set! x (append x '(this is new)))
> (display x)(newline)
> x))
>
> (define myvector (list->vector '(hi there)))
> (define changemyvector
> (lambda (x)
> (vector-set! x 1 'yall)
> (display x)(newline)
> x))
>
> I find the following in the interactions window:
>
> Welcome to DrScheme, version 202.
> Language: Pretty Big (includes MrEd and Advanced).
> > mylist
> (hi there)
> > (changemylist mylist)
> (hi there this is new)
> (hi there this is new)
> > mylist
> (hi there)
> > myvector
> #2(hi there)
> > (changemyvector myvector)
> #(hi yall)
> #2(hi yall)
> > myvector
> #2(hi yall)
> >
>
> So, really I have two questions. First, is this indicating that for
> regular lists the argument is passed 'by value' and for vectors it's
> passed 'by reference'? I know these terms are pulled from other
> platforms, but what I mean, of course, is that resetting the value of
> the local variable within the function in the first example doesn't
> change the original list, but in the second it does change the original
> vector.
>
> Second, how do I avoid this? I'd like to have a function that receives a
> list with vectors as some of its elements, and returns a variation of
> this without changing the original.
>
> Will happily review documentation if someone points me to it, but so far
> I haven't been able to find anything relevant on my own.
>
> Thanks,
> John
>
> John T. Murphy
> University of Arizona
> Department of Anthropology
> jtmurphy at email.arizona.edu
>
>