public inbox for kawa@sourceware.org
 help / color / mirror / Atom feed
* srfi-164 (array) and generaized vectord
@ 2019-03-25 22:03 Per Bothner
  0 siblings, 0 replies; only message in thread
From: Per Bothner @ 2019-03-25 22:03 UTC (permalink / raw)
  To: Kawa mailing list; +Cc: Arthur A. Gleckler

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

I've been working on SRFI 164 (Enhanced multi-dimensional Arrays)
https://srfi.schemers.org/srfi-164/srfi-164.html
This is more-or-less the Kawa design: https://www.gnu.org/software/kawa/Arrays.html
which is a superset of SRFI 25 (https://srfi.schemers.org/srfi-25/srfi-25.html).

I've been frustrated by the lack of support and feedback, and am tempted to withdraw
the proposal because of that.  So if you care about multi-dimensional arrays, and
like the basic Kawa approach, please provide feedback (and encouragement).

I could declare the specification "good enough", but it depends on two concepts that
are also new:

* Ranges are used for convenient and efficient selection of slices and rectangular sections.
Kawa has ranges (https://www.gnu.org/software/kawa/Ranges.html) but they use a special
syntax which is not suitable for standardization, and otherwise there is little prior art.
I'm not sure what to do about that.  The SRFI 164 draft includes a simple range API, but
it is not implemented (even in Kawa), though it should be easy to do so.

* SRFI-164 has a concept of a "generalized vector", which is a superset of traditional
vectors, uniform vectors, bitvectors, and ranges. Roughly: sequences that are random-access
indexable. Kawa has a "generalized sequence" concept,  which (for example) allows indexing
using function-call syntax. However, I think it is useful to generalize functions like
vector-ref to work with "generalized vectors" but not go as far as allowing arbitrary
sequences.  The attached patch adds a new type "gvector" for generalized vector, and
generalized vector-ref and some other function signatures to work with gvectors.

Feedback more than welcome.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

[-- Attachment #2: gvector.patch --]
[-- Type: text/x-patch, Size: 12184 bytes --]

diff --git a/gnu/kawa/lispexpr/LangObjType.java b/gnu/kawa/lispexpr/LangObjType.java
index 1fd67473a..7cf14092a 100644
--- a/gnu/kawa/lispexpr/LangObjType.java
+++ b/gnu/kawa/lispexpr/LangObjType.java
@@ -65,6 +65,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue
   private static final int ARGVECTOR_TYPE_CODE = 34;
   private static final int JSTRING_TYPE_CODE = 35;
   private static final int ISTRING_TYPE_CODE = 36;
+  private static final int GVECTOR_TYPE_CODE = 37;
 
   public static final LangObjType pathType =
     new LangObjType("path", "gnu.kawa.io.Path",
@@ -107,9 +108,15 @@ public class LangObjType extends SpecialObjectType implements TypeValue
                     DFLONUM_TYPE_CODE);
 
   public static final LangObjType vectorType =
-    new LangObjType("vector", "gnu.lists.FVector",
+      new LangObjType("vector",
+                      "gnu.lists.FVector",
                     VECTOR_TYPE_CODE);
 
+  public static final LangObjType gvectorType =
+      new LangObjType("gvector",
+                      "gnu.lists.GVector",
+                      GVECTOR_TYPE_CODE);
+
   public static final LangObjType constVectorType =
     new LangObjType("constant-vector", "gnu.lists.FVector",
                     CONST_VECTOR_TYPE_CODE);
@@ -296,6 +303,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue
                 return 1;
             break; 
         case VECTOR_TYPE_CODE:
+        case GVECTOR_TYPE_CODE:
             if (valueType instanceof ArrayType
                 && ((ArrayType) valueType).getComponentType() instanceof ObjectType)
                 return 1;
@@ -374,6 +382,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue
       case JSTRING_TYPE_CODE:
       case LIST_TYPE_CODE:
       case VECTOR_TYPE_CODE:
+      case GVECTOR_TYPE_CODE:
       case BITVECTOR_TYPE_CODE:
       case C16VECTOR_TYPE_CODE:
       case S8VECTOR_TYPE_CODE:
@@ -588,6 +597,8 @@ public class LangObjType extends SpecialObjectType implements TypeValue
         return typeLangObjType.getDeclaredMethod("coerceToU8Vector", 1);
       case CONST_VECTOR_TYPE_CODE:
         return typeLangObjType.getDeclaredMethod("coerceToConstVector", 1);
+      case GVECTOR_TYPE_CODE:
+          return ClassType.make("gnu.lists.FVector").getDeclaredMethod("cast", 1);
       case VECTOR_TYPE_CODE:
       case BITVECTOR_TYPE_CODE:
       case C16VECTOR_TYPE_CODE:
@@ -671,6 +682,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue
         mname = "asSequenceOrNull";
         break;
       case VECTOR_TYPE_CODE:
+      case GVECTOR_TYPE_CODE:
       case BITVECTOR_TYPE_CODE:
       case C16VECTOR_TYPE_CODE:
       case S8VECTOR_TYPE_CODE:
@@ -772,6 +784,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue
       case ISTRING_TYPE_CODE:
           return IString.valueOf((CharSequence) obj);
       case VECTOR_TYPE_CODE:
+      case GVECTOR_TYPE_CODE:
           return FVector.cast(obj);
       case F32VECTOR_TYPE_CODE:
           return F32Vector.cast(obj);
@@ -921,6 +934,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue
           toStringType.emitCoerceFromObject(code);
           break;
       case VECTOR_TYPE_CODE:
+      case GVECTOR_TYPE_CODE:
       case BITVECTOR_TYPE_CODE:
       case C16VECTOR_TYPE_CODE:
       case S8VECTOR_TYPE_CODE:
@@ -964,6 +978,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue
         return new PrimProcedure("gnu.kawa.io.URIPath", "makeURI", 1);
       case VECTOR_TYPE_CODE:
         return new PrimProcedure("gnu.lists.FVector", "make", 1);
+      case GVECTOR_TYPE_CODE:
       case CONST_VECTOR_TYPE_CODE:
           return new PrimProcedure("gnu.lists.FVector", "makeConstant", 1); 
       case LIST_TYPE_CODE:
@@ -1058,6 +1073,7 @@ public class LangObjType extends SpecialObjectType implements TypeValue
     public CompileBuildObject getBuildObject() {
         switch (typeCode) {
         case VECTOR_TYPE_CODE:
+        case GVECTOR_TYPE_CODE:
         case BITVECTOR_TYPE_CODE:
         case C16VECTOR_TYPE_CODE:
         case S8VECTOR_TYPE_CODE:
diff --git a/gnu/kawa/lispexpr/LispLanguage.java b/gnu/kawa/lispexpr/LispLanguage.java
index 4abeaff9e..0f3854f6f 100644
--- a/gnu/kawa/lispexpr/LispLanguage.java
+++ b/gnu/kawa/lispexpr/LispLanguage.java
@@ -270,6 +270,7 @@ public abstract class LispLanguage extends Language
             types.put("constant-string", ClassType.make("java.lang.CharSequence"));
             types.put("abstract-string", ClassType.make("gnu.lists.CharSeq"));
             types.put("vector", LangObjType.vectorType);
+            types.put("gvector", LangObjType.gvectorType);
             types.put("string", LangObjType.stringType);
             types.put("empty-list", ClassType.make("gnu.lists.EmptyList"));
             types.put("sequence", LangObjType.sequenceType);
diff --git a/gnu/lists/BitVector.java b/gnu/lists/BitVector.java
index 7abfe1524..b2398880a 100644
--- a/gnu/lists/BitVector.java
+++ b/gnu/lists/BitVector.java
@@ -8,7 +8,7 @@ import java.io.*;
 /** Simple adjustable-length vector of Boolean values. */
 
 public  class BitVector extends SimpleVector<Boolean>
-    implements Comparable
+    implements Comparable, GVector<Boolean>
 {
     boolean[] data;
     protected static boolean[] empty = new boolean[0];
diff --git a/gnu/lists/F32Vector.java b/gnu/lists/F32Vector.java
index 74f56985b..ec634a587 100644
--- a/gnu/lists/F32Vector.java
+++ b/gnu/lists/F32Vector.java
@@ -8,7 +8,7 @@ import java.io.*;
 /** Simple adjustable-length vector of 32-bit floats. */
 
 public  class F32Vector extends SimpleVector<Float>
-    implements Comparable
+    implements Comparable, GVector<Float>
 {
     float[] data;
     protected static float[] empty = new float[0];
diff --git a/gnu/lists/F64Vector.java b/gnu/lists/F64Vector.java
index b720f38c9..f040f3cd0 100644
--- a/gnu/lists/F64Vector.java
+++ b/gnu/lists/F64Vector.java
@@ -8,7 +8,7 @@ import java.io.*;
 /** Simple adjustable-length vector of 64-bit doubles. */
 
 public  class F64Vector extends SimpleVector<Double>
-    implements Comparable
+    implements Comparable, GVector<Double>
 {
     double[] data;
     protected static double[] empty = new double[0];
diff --git a/gnu/lists/FVector.java b/gnu/lists/FVector.java
index b4ba1b800..8003c0237 100644
--- a/gnu/lists/FVector.java
+++ b/gnu/lists/FVector.java
@@ -8,7 +8,7 @@ import java.io.*;
 /** Simple adjustable-length vector of objects. */
 
 public  class FVector<E> extends SimpleVector<E>
-    implements Consumable, Comparable
+    implements Consumable, Comparable, GVector<E>
 {
     Object[] data;
     protected static Object[] empty = new Object[0];
@@ -64,16 +64,17 @@ public  class FVector<E> extends SimpleVector<E>
         this.info = VERY_SIMPLE_FLAG;
     }
 
-    public void copyFrom (int index, FVector<E> src, int start, int end) {
+    public void copyFrom (int index, SimpleVector<E> src, int start, int end) {
         int count = end-start;
         int sz = size();
         int src_sz = src.size();
         if (count < 0 || index+count > sz || end > src_sz)
             throw new ArrayIndexOutOfBoundsException();
         int sseg, dseg;
-        if ((sseg = src.getSegmentReadOnly(start, count)) >= 0 &&
+        //FVector<E> fsrc;
+        if (src instanceof FVector && (sseg = src.getSegmentReadOnly(start, count)) >= 0 &&
             (dseg = getSegment(index, count)) >= 0) {
-            System.arraycopy(src.data, sseg, data, dseg, count);
+            System.arraycopy(((FVector)src).data, sseg, data, dseg, count);
         } else {
             for (int i = 0; i < count; i++)
                 set(index+i, src.get(start+i));
diff --git a/gnu/lists/GVector.java b/gnu/lists/GVector.java
new file mode 100644
index 000000000..be88bc68f
--- /dev/null
+++ b/gnu/lists/GVector.java
@@ -0,0 +1,5 @@
+package gnu.lists;
+
+public interface GVector<E> extends AVector<E>, java.util.RandomAccess
+{
+}
diff --git a/gnu/lists/PrimIntegerVector.java b/gnu/lists/PrimIntegerVector.java
index b9184626e..e4e757a16 100644
--- a/gnu/lists/PrimIntegerVector.java
+++ b/gnu/lists/PrimIntegerVector.java
@@ -6,7 +6,7 @@ package gnu.lists;
 import java.io.*;
 
 public abstract class PrimIntegerVector<E> extends SimpleVector<E>
-    implements Comparable
+    implements Comparable, GVector<E>
 {
     protected static int compareToInt(PrimIntegerVector v1,
                                       PrimIntegerVector v2) {
diff --git a/gnu/lists/Range.java b/gnu/lists/Range.java
index b12952771..5b46f1ee4 100644
--- a/gnu/lists/Range.java
+++ b/gnu/lists/Range.java
@@ -5,7 +5,7 @@ import gnu.kawa.functions.MultiplyOp;
 import gnu.math.IntNum;
 import java.io.*;
 
-public class Range<E> extends AbstractSequence<E> implements AVector<E> {
+public class Range<E> extends AbstractSequence<E> implements GVector<E> {
     E start;
     Object step;
     int size;
diff --git a/gnu/lists/SimpleVector.java b/gnu/lists/SimpleVector.java
index d64ae2190..ed554f7c1 100644
--- a/gnu/lists/SimpleVector.java
+++ b/gnu/lists/SimpleVector.java
@@ -391,6 +391,28 @@ public abstract class SimpleVector<E> extends AbstractSequence<E>
         return copy;
     }
 
+    public static SimpleVector castOrNull(Object obj) {
+        if (obj instanceof Object[])
+            return new FVector((Object[]) obj);
+        // FIXME other array types
+        if (obj instanceof SimpleVector)
+            return (SimpleVector) obj;
+        return null;
+    }
+
+    public static SimpleVector cast(Object value) {
+        SimpleVector vec = castOrNull(value);
+        if (vec == null) {
+            String msg;
+            if (value == null)
+                msg = "cannot convert null to vector<E>";
+            else
+                msg = "cannot convert a "+value.getClass().getName()+" to FVector<E>";
+            throw new ClassCastException(msg);
+        }
+        return vec;
+    }
+
     /** This is convenience hack for printing "uniform vectors" (srfi 4).
      * It may go away without notice! */
     public String getTag() { return null; }
diff --git a/kawa/lib/vectors.scm b/kawa/lib/vectors.scm
index 5cd1a2f96..0eac58428 100644
--- a/kawa/lib/vectors.scm
+++ b/kawa/lib/vectors.scm
@@ -5,23 +5,23 @@
 (define (vector? x) :: <boolean>
   (instance? x vector))
 
-(define (make-vector (k :: <int>) #!optional (fill #!null)) :: vector
+(define (make-vector (k :: <int>) #!optional (fill #!null)) ::vector
   (gnu.lists.FVector k fill))
 
-(define (vector-length x :: <vector>) :: <int>
+(define (vector-length x ::gvector) :: <int>
   (invoke x 'size))
 
-(define (vector-set! (vector ::vector) (k ::int) obj) :: <void>
-  (invoke vector 'setAt k obj))
+(define (vector-set! (vec ::vector) (k ::int) obj) :: <void>
+  (invoke vec 'setAt k obj))
 
 (define-procedure vector-ref
   setter: vector-set!
   (begin
-    (define (vector-ref (vector :: <vector>) (k :: <int>))
+    (define (vector-ref (vector ::gvector) (k ::int))
       (invoke vector 'get k))
     vector-ref))
 
-(define (vector->list (vec :: <vector>)
+(define (vector->list (vec ::gvector)
                       #!optional (start ::int 0) (end ::int (vec:size)))
                       :: <list>
   (let loop ((result :: <list> '())
@@ -47,7 +47,7 @@
           (set! (result j) ch)
           (loop result (+ i 1) (+ j 1))))))
 
-(define (vector-copy (vec :: vector)
+(define (vector-copy (vec :: gvector)
                      #!optional
                      (start ::int 0)
                      (end ::int (vec:size)))
@@ -58,13 +58,13 @@
 
 (define (vector-copy! (to ::vector)
                       (at ::int)
-                      (from ::vector)
+                      (from ::gvector)
                       #!optional
                       (start ::int 0)
                       (end ::int (from:size)))
   (to:copyFrom  at from start end))
 
-(define (vector-fill! (vec :: vector) fill
+(define (vector-fill! (vec ::vector) fill
                       #!optional (start ::int 0) (end ::int (vec:size)))
   :: void
   (vec:fill start end fill))

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-03-25 22:03 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-25 22:03 srfi-164 (array) and generaized vectord Per Bothner

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