unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* read syntax vectors immutable
@ 2017-06-22  9:04 j kalbhenn
  2017-06-22 16:44 ` Mark H Weaver
  0 siblings, 1 reply; 4+ messages in thread
From: j kalbhenn @ 2017-06-22  9:04 UTC (permalink / raw)
  To: guile-user

vectors created using read syntax are apparently immutable with guile 2.2.2:

--
(define a #(0))
(if (vector? a) (vector-set! a 0 1))

In procedure vector-set!: Wrong type argument in position 1 (expecting mutable vector): #(0)
--

is this documented somewhere in the guile manual or part of the scheme standard? i could not find anything about it.



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: read syntax vectors immutable
  2017-06-22  9:04 read syntax vectors immutable j kalbhenn
@ 2017-06-22 16:44 ` Mark H Weaver
  2017-06-22 16:57   ` Mark H Weaver
  2017-06-23  9:24   ` j kalbhenn
  0 siblings, 2 replies; 4+ messages in thread
From: Mark H Weaver @ 2017-06-22 16:44 UTC (permalink / raw)
  To: j kalbhenn; +Cc: guile-user

j kalbhenn <jkal@posteo.eu> writes:

> vectors created using read syntax are apparently immutable with guile 2.2.2:
>
> --
> (define a #(0))
> (if (vector? a) (vector-set! a 0 1))
>
> In procedure vector-set!: Wrong type argument in position 1 (expecting mutable vector): #(0)
> --
>
> is this documented somewhere in the guile manual or part of the scheme standard? i could not find anything about it.

R5RS section 4.1.2 (Literal expressions) states:

     As noted in section *note Storage model::, it is an error to alter
     a constant (i.e.  the value of a literal expression) using a
     mutation procedure like 'set-car!' or 'string-set!'.

Also, if you look up 'quote' in the Guile index, it says:

     Note that an application must not attempt to modify literal lists
     or vectors obtained from a ‘quote’ form, since they may be in
     read-only memory.

Although only a few types are listed above, in fact it is an error to
mutate *any* literal, regardless of its type.

In Scheme, it has always been the case that literals are supposed to be
immutable.  However, earlier versions of Guile failed to detect improper
attempts to mutate literals in most cases, and yet doing so would lead
to unspecified and often very confusing behavior.

Literals are, in effect, part of the code itself, and successfully
mutating them typically has the effect of modifying the code itself.

For example, suppose you write a procedure that returns a vector of all
zeroes, but with a '1' at a given index.  Improperly mutating vector
literals, you might try this:

  GNU Guile 2.0.11
  Copyright (C) 1995-2014 Free Software Foundation, Inc.
  
  Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
  This program is free software, and you are welcome to redistribute it
  under certain conditions; type `,show c' for details.
  
  Enter `,help' for help.
  scheme@(guile-user)> (define (mask n)
                         (let ((v '#(0 0 0 0 0 0 0 0)))
                           (vector-set! v n 1)
                           v))
  scheme@(guile-user)> (mask 3)
  $1 = #(0 0 0 1 0 0 0 0)

So far, so good.  Now let's try some other values:

  scheme@(guile-user)> (mask 6)
  $2 = #(0 0 0 1 0 0 1 0)
  scheme@(guile-user)> (mask 0)
  $3 = #(1 0 0 1 0 0 1 0)

See, you're modifying the code.  Let's disassemble 'mask' to look at its
compiled code:

  scheme@(guile-user)> ,x mask
  Disassembly of #<procedure mask (n)>:
  
     0    (assert-nargs-ee/locals 1)      ;; 1 arg, 0 locals
     2    (object-ref 1)                  ;; #(1 0 0 1 0 0 1 0) at (unknown file):2:32
     4    (local-ref 0)                   ;; `n'
     6    (make-int8:1)                   ;; 1
     7    (vector-set)                                          at (unknown file):3:25
     8    (object-ref 1)                  ;; #(1 0 0 1 0 0 1 0) at (unknown file):2:32
    10    (return)                        

And indeed, the code has been modified.

To create a mutable vector, use 'vector', or apply 'vector-copy' to a
literal vector.  Also note that these are shallow copies, e.g. if you
have nested vector literals, 'vector-copy' will only copy the top layer.

       Mark



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: read syntax vectors immutable
  2017-06-22 16:44 ` Mark H Weaver
@ 2017-06-22 16:57   ` Mark H Weaver
  2017-06-23  9:24   ` j kalbhenn
  1 sibling, 0 replies; 4+ messages in thread
From: Mark H Weaver @ 2017-06-22 16:57 UTC (permalink / raw)
  To: j kalbhenn; +Cc: guile-user

I wrote:
> To create a mutable vector, use 'vector', or apply 'vector-copy' to a
> literal vector.  Also note that these are shallow copies, e.g. if you
> have nested vector literals, 'vector-copy' will only copy the top layer.

'make-vector' is also useful for many purposes.

       Mark



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: read syntax vectors immutable
  2017-06-22 16:44 ` Mark H Weaver
  2017-06-22 16:57   ` Mark H Weaver
@ 2017-06-23  9:24   ` j kalbhenn
  1 sibling, 0 replies; 4+ messages in thread
From: j kalbhenn @ 2017-06-23  9:24 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-user

thanks for the clarification (also to others who responded), very insightful.



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-06-23  9:24 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-22  9:04 read syntax vectors immutable j kalbhenn
2017-06-22 16:44 ` Mark H Weaver
2017-06-22 16:57   ` Mark H Weaver
2017-06-23  9:24   ` j kalbhenn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).