On 01/10/2014 11:23 AM, Sean Kanaley wrote:
> (define x (build-vector 4 (const (vector 1))))
> (vector-set! (vector-ref x 2) 0 5)
> x
'#(#(5) #(5) #(5) #(5))
-------- vs. --------------
> (define x (build-vector 4 (λ (x) (vector 1))))
> (vector-set! (vector-ref x 2) 0 5)
> x
'#(#(1) #(1) #(5) #(1))
---------------------------------------------------------------
Maybe I'm misunderstanding const, but to me it means "ignore arguments"
as opposed to signifying shared-structure / immutability (like a
"constant"). That's what #(1) is for. The top version should I believe
constantly return a fresh (different) vector regardless of its arguments.
I'm on 5.3.4 due to Ubuntu, in case this was already found.
It's because in Racket, application is call-by-value. IOW, your first
example using `const' is equivalent to this:
> (define the-value (vector 1))
> (define x (build-vector 4 (λ (x) the-value)))
> (vector-set! (vector-ref x 2) 0 5)
> x
'#(#(5) #(5) #(5) #(5))
Mutation gives you a way to observe evaluation order. (Kinda fun puzzle:
figure out how to observe it using `eq?'.)
If you want a `const' that works like you've been expecting, you'll need
one that takes a thunk as an argument. Then you can pass an unevaluated
(vector 1) as (λ () (vector 1)).
Neil ⊥
____________________
Racket Users list:
http://lists.racket-lang.org/users