[plt-scheme] vectors by value

From: Robert Bruce Findler (robby at cs.uchicago.edu)
Date: Fri Feb 7 21:50:04 EST 2003

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

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

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


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

Posted on the users mailing list.