[racket] Possible bug with "const"?

From: Neil Toronto (neil.toronto at gmail.com)
Date: Fri Jan 10 14:09:57 EST 2014

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 ⊥


Posted on the users mailing list.