From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Mark H Weaver Newsgroups: gmane.lisp.guile.user Subject: Re: read syntax vectors immutable Date: Thu, 22 Jun 2017 12:44:59 -0400 Message-ID: <87a850hsz8.fsf@netris.org> References: <20170622090458.GA15025@sph-desktop.fritz.box> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Trace: blaine.gmane.org 1498149944 17734 195.159.176.226 (22 Jun 2017 16:45:44 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Thu, 22 Jun 2017 16:45:44 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.2 (gnu/linux) Cc: guile-user@gnu.org To: j kalbhenn Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Thu Jun 22 18:45:35 2017 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dO5Ec-0004Cq-Nd for guile-user@m.gmane.org; Thu, 22 Jun 2017 18:45:34 +0200 Original-Received: from localhost ([::1]:60044 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dO5Ei-000819-0i for guile-user@m.gmane.org; Thu, 22 Jun 2017 12:45:40 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:51906) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dO5EL-000814-DH for guile-user@gnu.org; Thu, 22 Jun 2017 12:45:18 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dO5EI-0002Qu-98 for guile-user@gnu.org; Thu, 22 Jun 2017 12:45:17 -0400 Original-Received: from world.peace.net ([50.252.239.5]:47573) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dO5EI-0002Qb-51 for guile-user@gnu.org; Thu, 22 Jun 2017 12:45:14 -0400 Original-Received: from pool-72-93-34-106.bstnma.east.verizon.net ([72.93.34.106] helo=jojen) by world.peace.net with esmtpsa (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1dO55R-0003k9-55; Thu, 22 Jun 2017 12:36:05 -0400 In-Reply-To: <20170622090458.GA15025@sph-desktop.fritz.box> (j. kalbhenn's message of "Thu, 22 Jun 2017 09:04:58 +0000") X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 50.252.239.5 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane.org@gnu.org Original-Sender: "guile-user" Xref: news.gmane.org gmane.lisp.guile.user:13865 Archived-At: j kalbhenn 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 mu= table vector): #(0) > -- > > is this documented somewhere in the guile manual or part of the scheme st= andard? 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 =E2=80=98quote=E2=80=99 form, since they ma= y 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. =20=20 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. =20=20 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 =3D #(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 =3D #(0 0 0 1 0 0 1 0) scheme@(guile-user)> (mask 0) $3 =3D #(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 #: =20=20 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)=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20= =20=20=20=20=20 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