unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* [PATCH] New function array-mutable?
@ 2021-11-25 16:40 lloda
  2021-11-25 18:19 ` Maxime Devos
  2021-11-25 18:22 ` Maxime Devos
  0 siblings, 2 replies; 7+ messages in thread
From: lloda @ 2021-11-25 16:40 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: text/plain, Size: 80 bytes --]


Doesn't seem there was any simple way to check this from either Scheme or C.



[-- Attachment #2: 0001-New-function-array-mutable.patch --]
[-- Type: application/octet-stream, Size: 4544 bytes --]

From 45536ebe85bcc7285089799a8a1e7f0370f74976 Mon Sep 17 00:00:00 2001
From: Daniel Llorens <lloda@sarc.name>
Date: Thu, 25 Nov 2021 15:58:41 +0100
Subject: [PATCH] New function array-mutable?

* libguile/arrays.h
* libguile/arrays.c (scm_array_mutable_p): New function.
* doc/ref/api-data.texi: Documentation.
* NEWS: Update.
---
 NEWS                  |  4 ++++
 doc/ref/api-data.texi | 29 +++++++++++++++++++++++++++++
 libguile/arrays.c     | 27 +++++++++++++++++++++------
 libguile/arrays.h     |  1 +
 4 files changed, 55 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index 710b8ddda..b72cc8696 100644
--- a/NEWS
+++ b/NEWS
@@ -39,6 +39,10 @@ The functions `u8vector-copy' `s8vector-copy' `u16vector-copy'
 `f64vector-copy!'  `c32vector-copy!'  `c64vector-copy!' have been
 added. See SRFI-4 - Guile extensions" in the manual.
 
+** New function array-mutable?
+
+See "Array procedures" in the manual.
+
 ** `bytevector-fill!' supports partial fill through optional arguments
 
 This is an extension to the r6rs procedure. See "Manipulating
diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi
index 1df88e755..b74376039 100644
--- a/doc/ref/api-data.texi
+++ b/doc/ref/api-data.texi
@@ -7345,6 +7345,35 @@ but it is not used.  You should always pass @code{SCM_UNDEFINED} as
 its value.
 @end deffn
 
+@deffn {Scheme Procedure} array-mutable? array
+@deffnx {C Function} scm_array_mutable_p (array)
+Return @code{#t} if the root of @var{array} is mutable, and @code{#f}
+otherwise.
+
+Most literal arrays are immutable.
+@example
+(let ((a #(1 2 3)))
+  (array-set! a 'x 0) @result{} error!
+  a)
+(array-mutable? #(1 2 3)) @result{} #f
+@end example
+
+@example
+(let ((a (array-copy #(1 2 3))))
+  (array-set! a 'x 0) ; ok
+  a) @result{} #(x 2 3)
+(array-mutable? (vector-copy #(1 2 3))) @result{} #t
+@end example
+
+Arrays with empty roots are not considered immutable because
+@code{array-set!} operations with valid indices won't fail (since there
+are no valid indices).
+
+@example
+(array-mutable? #()) @result{} #t
+@end example
+@end deffn
+
 @deffn {Scheme Procedure} typed-array? obj type
 @deffnx {C Function} scm_typed_array_p (obj, type)
 Return @code{#t} if the @var{obj} is an array of type @var{type}, and
diff --git a/libguile/arrays.c b/libguile/arrays.c
index 924ee0094..6963f7cd9 100644
--- a/libguile/arrays.c
+++ b/libguile/arrays.c
@@ -28,10 +28,17 @@
 #include <errno.h>
 #include <string.h>
 
+#include "arrays.h"
 #include "array-map.h"
+#include "generalized-vectors.h"
+
 #include "bitvectors.h"
 #include "boolean.h"
 #include "bytevectors.h"
+#include "strings.h"
+#include "uniform.h"
+#include "vectors.h"
+
 #include "chars.h"
 #include "dynwind.h"
 #include "eq.h"
@@ -39,7 +46,6 @@
 #include "eval.h"
 #include "feature.h"
 #include "fports.h"
-#include "generalized-vectors.h"
 #include "gsubr.h"
 #include "list.h"
 #include "modules.h"
@@ -49,11 +55,6 @@
 #include "read.h"
 #include "srfi-13.h"
 #include "srfi-4.h"
-#include "strings.h"
-#include "uniform.h"
-#include "vectors.h"
-
-#include "arrays.h"
 
 SCM_INTERNAL SCM scm_i_array_ref (SCM v,
                                   SCM idx0, SCM idx1, SCM idxN);
@@ -90,6 +91,20 @@ SCM_DEFINE (scm_array_p_2, "array?", 1, 0, 0,
 }
 #undef FUNC_NAME
 
+SCM_DEFINE (scm_array_mutable_p, "array-mutable?", 1, 0, 0,
+            (SCM obj),
+            "Return @code{#t} if the root of array @var{obj} is mutable, and\n"
+            "@code{#f} otherwise.")
+#define FUNC_NAME s_scm_array_mutable_p
+{
+  scm_t_array_handle h;
+  scm_array_get_handle (obj, &h);
+  SCM val = scm_from_bool (h.writable_elements == h.elements);
+  scm_array_handle_release (&h);
+  return val;
+}
+#undef FUNC_NAME
+
 /* The array type predicate, with an extra argument kept for backward
    compatibility.  Note that we can't use `SCM_DEFINE' directly because there
    would be an argument count mismatch that would be caught by
diff --git a/libguile/arrays.h b/libguile/arrays.h
index 5457ddb95..e2306cabf 100644
--- a/libguile/arrays.h
+++ b/libguile/arrays.h
@@ -62,6 +62,7 @@ SCM_API SCM scm_array_rank (SCM ra);
 SCM_API int scm_is_array (SCM obj);
 SCM_API SCM scm_array_p (SCM v, SCM unused);
 SCM_INTERNAL SCM scm_array_p_2 (SCM);
+SCM_API SCM scm_array_mutable_p (SCM a);
 
 SCM_API int scm_is_typed_array (SCM obj, SCM type);
 SCM_API SCM scm_typed_array_p (SCM v, SCM type);
-- 
2.30.2


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

* Re: [PATCH] New function array-mutable?
  2021-11-25 16:40 [PATCH] New function array-mutable? lloda
@ 2021-11-25 18:19 ` Maxime Devos
  2021-11-25 19:10   ` lloda
       [not found]   ` <97DC61EC-3DD4-444B-98DB-AB9A823EA1F3@sarc.name>
  2021-11-25 18:22 ` Maxime Devos
  1 sibling, 2 replies; 7+ messages in thread
From: Maxime Devos @ 2021-11-25 18:19 UTC (permalink / raw)
  To: lloda, guile-devel

lloda schreef op do 25-11-2021 om 17:40 [+0100]:
> [...]

Suggestion: add a few tests to test-suite/tests/arrays.test:

(pass-if-equal "new"
  #t
  (array-mutable? (make-array #f '(1 2) '(3 4))))

(pass-if-equal "empty (two-dimensional)"
  #t
  (array-mutable? (array-copy #1())))

(pass-if-equal "empty (two-dimensional)"
  #t
  (array-mutable? (array-copy #2(() ()))))

(pass-if-equal "immutable copy"
  #f
  (array-mutable? (immutable-array-copy #2((h) (h)))))

This requires a currently non-existent procedure ‘make-immutable-
array’, copying an array into a new immutable array.

Greetings,
Maxime




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

* Re: [PATCH] New function array-mutable?
  2021-11-25 16:40 [PATCH] New function array-mutable? lloda
  2021-11-25 18:19 ` Maxime Devos
@ 2021-11-25 18:22 ` Maxime Devos
  2021-11-25 18:56   ` lloda
  1 sibling, 1 reply; 7+ messages in thread
From: Maxime Devos @ 2021-11-25 18:22 UTC (permalink / raw)
  To: lloda, guile-devel

lloda schreef op do 25-11-2021 om 17:40 [+0100]:
> +Arrays with empty roots are not considered immutable because
> +@code{array-set!} operations with valid indices won't fail (since
> there
> +are no valid indices).
> +
> +@example
> +(array-mutable? #()) @result{} #t
> +@end example
> +@end deffn

By this logic, shouldn't empty subarrays (*) with a possibly mutable
and non-empty root be considered mutable as well?

(*) called ‘shared arrays’ in the manual

Greetings,
Maxime




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

* Re: [PATCH] New function array-mutable?
  2021-11-25 18:22 ` Maxime Devos
@ 2021-11-25 18:56   ` lloda
  2021-11-27  8:42     ` lloda
  0 siblings, 1 reply; 7+ messages in thread
From: lloda @ 2021-11-25 18:56 UTC (permalink / raw)
  To: Maxime Devos; +Cc: guile-devel



> On 25 Nov 2021, at 19:22, Maxime Devos <maximedevos@telenet.be> wrote:
> 
> lloda schreef op do 25-11-2021 om 17:40 [+0100]:
>> +Arrays with empty roots are not considered immutable because
>> +@code{array-set!} operations with valid indices won't fail (since
>> there
>> +are no valid indices).
>> +
>> +@example
>> +(array-mutable? #()) @result{} #t
>> +@end example
>> +@end deffn
> 
> By this logic, shouldn't empty subarrays (*) with a possibly mutable
> and non-empty root be considered mutable as well?
> 
> (*) called ‘shared arrays’ in the manual
> 
> Greetings,
> Maxime

That would make sense, I think.

The test in the patch is the same one that is used to validate array_handle_xxx_writable_elements(), which looks only at the root and not at the array dimensions. Those two tests should be the same, so I'll have to change the test in array_handle_xxx_writable_elements().

Thanks

	Daniel





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

* Re: [PATCH] New function array-mutable?
  2021-11-25 18:19 ` Maxime Devos
@ 2021-11-25 19:10   ` lloda
       [not found]   ` <97DC61EC-3DD4-444B-98DB-AB9A823EA1F3@sarc.name>
  1 sibling, 0 replies; 7+ messages in thread
From: lloda @ 2021-11-25 19:10 UTC (permalink / raw)
  To: Maxime Devos; +Cc: guile-devel

[-- Attachment #1: Type: text/plain, Size: 1123 bytes --]



> On 25 Nov 2021, at 19:19, Maxime Devos <maximedevos@telenet.be> wrote:
> 
> lloda schreef op do 25-11-2021 om 17:40 [+0100]:
>> [...]
> 
> Suggestion: add a few tests to test-suite/tests/arrays.test:
> 
> (pass-if-equal "new"
>  #t
>  (array-mutable? (make-array #f '(1 2) '(3 4))))
> 
> (pass-if-equal "empty (two-dimensional)"
>  #t
>  (array-mutable? (array-copy #1())))
> 
> (pass-if-equal "empty (two-dimensional)"
>  #t
>  (array-mutable? (array-copy #2(() ()))))
> 
> (pass-if-equal "immutable copy"
>  #f
>  (array-mutable? (immutable-array-copy #2((h) (h)))))
> 
> This requires a currently non-existent procedure ‘make-immutable-
> array’, copying an array into a new immutable array.
> 
> Greetings,
> Maxime

I think literal arrays are always immutable, and one could base the test on that.

Is such a function useful in some other context? If one has an array which is already immutable, it can be referenced freely and copying it seems unnecessary. If one has a mutable array, is there any reason why one would want to make an immutable copy?

regards

	Daniel


[-- Attachment #2: Type: text/html, Size: 3221 bytes --]

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

* Re: [PATCH] New function array-mutable?
  2021-11-25 18:56   ` lloda
@ 2021-11-27  8:42     ` lloda
  0 siblings, 0 replies; 7+ messages in thread
From: lloda @ 2021-11-27  8:42 UTC (permalink / raw)
  To: Maxime Devos; +Cc: guile-devel



> On 25 Nov 2021, at 19:56, lloda <lloda@sarc.name> wrote:
> 
> 
> 
>> On 25 Nov 2021, at 19:22, Maxime Devos <maximedevos@telenet.be> wrote:
>> 
>> lloda schreef op do 25-11-2021 om 17:40 [+0100]:
>>> +Arrays with empty roots are not considered immutable because
>>> +@code{array-set!} operations with valid indices won't fail (since
>>> there
>>> +are no valid indices).
>>> +
>>> +@example
>>> +(array-mutable? #()) @result{} #t
>>> +@end example
>>> +@end deffn
>> 
>> By this logic, shouldn't empty subarrays (*) with a possibly mutable
>> and non-empty root be considered mutable as well?
>> 
>> (*) called ‘shared arrays’ in the manual
>> 
>> Greetings,
>> Maxime
> 
> That would make sense, I think.
> 
> The test in the patch is the same one that is used to validate array_handle_xxx_writable_elements(), which looks only at the root and not at the array dimensions. Those two tests should be the same, so I'll have to change the test in array_handle_xxx_writable_elements().
> 
> Thanks
> 
> 	Daniel

Another option would be to rename the function to array-root-mutable?. Then the condition would remain as is. This also makes sense because mutability isn't a property of the array descriptor, rather it's a property of the root.




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

* Re: [PATCH] New function array-mutable?
       [not found]   ` <97DC61EC-3DD4-444B-98DB-AB9A823EA1F3@sarc.name>
@ 2021-12-09 20:34     ` Maxime Devos
  0 siblings, 0 replies; 7+ messages in thread
From: Maxime Devos @ 2021-12-09 20:34 UTC (permalink / raw)
  To: lloda; +Cc: guile-devel

Hi,

lloda schreef op do 25-11-2021 om 20:08 [+0100]:
I think literal arrays are always immutable, and one could base the
test on that.
>
Is such a function useful in some other context? If one has an array which is already immutable, it can be referenced freely and copying it seems unnecessary. If one has a mutable array, is there any reason why one would want to make an immutable copy?

To avoid accidental mutation (though at the cost of making a copy).

Also, literals aren't necessarily immutable if 'eval' is used:

(let ((literal (make-array 0 1 1))) (eval `(array-set! ',literal #xff 0 0) (current-module)) literal)
;; output: #2((255))

As-is, this is a somewhat contrived example. But 'eval' is useful REPL-like things,
and if someone implements a REPL-like thing, they might want to ‘immutabilise’
all input first such that array-set! on literals will actually produce an exception
as one would expect.

An alternative method would be to compile the code before running
(which is what the standard REPL does IIUC), but _requiring_ this extra step seems
suboptimal to me.

Greetings,
Maxime.

p.s. Somehow, your e-mail ended up in spam, for no apparent reason.




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

end of thread, other threads:[~2021-12-09 20:34 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-25 16:40 [PATCH] New function array-mutable? lloda
2021-11-25 18:19 ` Maxime Devos
2021-11-25 19:10   ` lloda
     [not found]   ` <97DC61EC-3DD4-444B-98DB-AB9A823EA1F3@sarc.name>
2021-12-09 20:34     ` Maxime Devos
2021-11-25 18:22 ` Maxime Devos
2021-11-25 18:56   ` lloda
2021-11-27  8:42     ` lloda

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).