Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to define a reference to another variable

6 views
Skip to first unread message

carlmax

unread,
Jul 23, 2007, 10:39:55 AM7/23/07
to
Hi,
I'm confused about some scheme semantic, for example:
(define a (vector 1 2 3))
(define b a)
(vector-set! a 0 9)
(eq? a b) ==> #t

(define a 1)
(define b a)
(set! a 9)
(eq? a b) ==> #f

then how to make b as a's alias, that is, after changing a, b is changed
accordingly?


Pascal Bourguignon

unread,
Jul 23, 2007, 12:26:44 PM7/23/07
to
"carlmax" <car...@tom.com> writes:

You cannot make aliases in scheme. That's the point.

You can have objects, that are either mutable or immutable, and you
can bind these objects to variables. Arguments are passed by values,
that is the object that is bound to a variable is passed as argument,
but since these are objects, in general, it's a reference to the
object that is passed internally. Of course, in the case of immutable
objects, the compilers can optimize it and copy the object itself, but
the semantics are the same, this is invisible to the user. Well,
invisible unless you use eq? which is an implementation dependant
operator that allows you to see when such copying is done. Note that:

(define a 1)
(define b a)

(eqv? a b) ==> #t
(eq? a b) ==> #t or #f depending on the implementation.

See:
http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-9.html#%_idx_216


Note that when you call vector-set!, you are NOT modifying the binding
of b, but when you call set! you are modifying the binding of b. So
you shouldn't be surprized that thereafter, eqv? or equal? return different
results. (You could be surprized if eq? returned same results).


Assume we define a functional vector-set:

(define (copy-vector v)
(let loop ((r (make-vector (vector-length v)))
(i 0))
(if (>= i (vector-length v))
r
(begin (vector-set! r i (vector-ref v i))
(loop r (+ 1 i))))))

(define (vector-set v i o)
(let ((r (copy-vector v)))
(vector-set! r i o)
r))

Then we could get similar results, using similar operations:

> (define a (vector 1 2 3))
> (define b a)

> (equal? a b)
#t
> (eq? a b) ; since both a and b are bound to the same vector object.
#t
> (set! b (vector-set b 1 0)) ; now, we bind b to another vector object
> (equal? a b)
#f
> (eq? a b) ; since they're not equal?
#f
> b
#3(1 0 3)
> (define a 1)
> (define b 1)
> (equal? a b) ; since both a and b are bound to the same integer object.
#t
> (eq? a b) ; this could be #f, in some implementation, or if we tried with a bignum instead of 1.
#t
> (set! b 0) ; binding to another integer object.
> (equal? a b) ; obviously different.
#f
> (eq? a b)
#f
>

The only difference is that a vector is mutable: you can modify parts
of its data without modifying the object identity of the vector, while
integers are immutable: you cannot modify part of an integer.

You should also read: http://www.nhplace.com/kent/PS/EQUAL.html

Ok, but now if what you want to do is to really get aliasing behavior,
you can still implement this abstraction, but not using set!, you'll
have to use alias-set!. What you need to do, is to store the values,
not as variable binding, but inside a mutable object. For this, you
can use a vector, a cons cell, a structure, etc.

For example, with conses:

(define (make-alias value) (cons 'alias value))
(define (alias-get alias) (cdr alias))
(define (alias-set! alias v) (set-cdr! alias v))


> (define a (make-alias (vector 1 2 3)))
> (define b a)
> (eq? a b) ; a and b are bound to the same alias object.
#t
> (vector-set! (alias-get a) 0 9)
> (eq? a b) ; and this hasn't changed.
#t
> (define a (make-alias 1))
> (define b a)
> (alias-set! a 9)
> (eq? a b) ; alias-set doesn't change the bindings: both a and b are still bound to the same alias object.
#t
> (alias-get a)
9
> (alias-get b) ; therefore the "aliased" value is visible thru both a and b.
9
>

--
__Pascal Bourguignon__ http://www.informatimago.com/

HANDLE WITH EXTREME CARE: This product contains minute electrically
charged particles moving at velocities in excess of five hundred
million miles per hour.

Pascal Costanza

unread,
Jul 23, 2007, 12:33:58 PM7/23/07
to
Pascal Bourguignon wrote:
> "carlmax" <car...@tom.com> writes:
>
>> Hi,
>> I'm confused about some scheme semantic, for example:
>> (define a (vector 1 2 3))
>> (define b a)
>> (vector-set! a 0 9)
>> (eq? a b) ==> #t
>>
>> (define a 1)
>> (define b a)
>> (set! a 9)
>> (eq? a b) ==> #f
>>
>> then how to make b as a's alias, that is, after changing a, b is changed
>> accordingly?
>
> You cannot make aliases in scheme. That's the point.

Currently, identifier macros are being considered for inclusion in R6RS
Scheme (also known as symbol macros in Common Lisp). They would enable
aliases.

Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/

carlmax

unread,
Jul 23, 2007, 7:17:47 PM7/23/07
to
"Pascal Bourguignon" <p...@informatimago.com> write
news:<87644bf...@voyager.informatimago.com>...

>
>
> The only difference is that a vector is mutable: you can modify parts
> of its data without modifying the object identity of the vector, while
> integers are immutable: you cannot modify part of an integer.

I have never heard about mutable and immutable object. Thanks you very much.
I've just finihed HtDP, and there is no sentence about object.
I guess, most compound objects, like structure, list, vector are mutable,
and others
are immutable, am I right?


>
> You should also read: http://www.nhplace.com/kent/PS/EQUAL.html
>
>
>

I'll read it.
Thanks again.


Pascal Bourguignon

unread,
Jul 24, 2007, 8:08:41 AM7/24/07
to
"carlmax" <car...@tom.com> writes:

> "Pascal Bourguignon" <p...@informatimago.com> write
> news:<87644bf...@voyager.informatimago.com>...
>>
>>
>> The only difference is that a vector is mutable: you can modify parts
>> of its data without modifying the object identity of the vector, while
>> integers are immutable: you cannot modify part of an integer.
>
> I have never heard about mutable and immutable object. Thanks you very much.
> I've just finihed HtDP, and there is no sentence about object.
> I guess, most compound objects, like structure, list, vector are mutable,
> and others
> are immutable, am I right?

Basically, yes.

Note that you should also consider as immutable any quoted or literal
object.

(let ((mutable-v (vector 1 2 3))
(immutable-v #(1 2 3))
(mutable-l (list 1 2 3))
(immutable-l '(1 2 3))
(mutable-s (make-string 3 #\a))
(immutable-s "aaa"))
(etc))

See "Storage Model":
http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-6.html#%_sec_3.4

--
__Pascal Bourguignon__ http://www.informatimago.com/

"Remember, Information is not knowledge; Knowledge is not Wisdom;
Wisdom is not truth; Truth is not beauty; Beauty is not love;
Love is not music; Music is the best." -- Frank Zappa

Anton van Straaten

unread,
Jul 24, 2007, 1:40:00 PM7/24/07
to
carlmax wrote:
> "Pascal Bourguignon" <p...@informatimago.com> write
> news:<87644bf...@voyager.informatimago.com>...
>
>>
>>The only difference is that a vector is mutable: you can modify parts
>>of its data without modifying the object identity of the vector, while
>>integers are immutable: you cannot modify part of an integer.
>
>
> I have never heard about mutable and immutable object. Thanks you very much.
> I've just finihed HtDP, and there is no sentence about object.

HtDP talks about "mutable compound values". Part VIII deals with
"Changing Compound Values", with chapter 40 covering "Mutable
Structures" and chapter 43 "Changing Structures, Vectors, and Objects".

See
http://www.htdp.org/2003-09-26/Book/curriculum-Z-H-1.html#node_toc_node_part_VIII

Anton

0 new messages