From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30378 invoked by alias); 25 Mar 2019 22:03:35 -0000 Mailing-List: contact kawa-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: kawa-owner@sourceware.org Received: (qmail 30352 invoked by uid 89); 25 Mar 2019 22:03:34 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-27.6 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.1 spammy=HTo:U*kawa, Enhanced, Double, withdraw X-HELO: aibo.runbox.com Received: from aibo.runbox.com (HELO aibo.runbox.com) (91.220.196.211) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 25 Mar 2019 22:03:31 +0000 Received: from [10.9.9.211] (helo=mailfront11.runbox.com) by mailtransmit03.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1h8Xgk-0007W6-Ne; Mon, 25 Mar 2019 23:03:26 +0100 Received: by mailfront11.runbox.com with esmtpsa (uid:757155 ) (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.82) id 1h8XgZ-0006UL-9u; Mon, 25 Mar 2019 23:03:16 +0100 To: Kawa mailing list Cc: "Arthur A. Gleckler" From: Per Bothner Subject: srfi-164 (array) and generaized vectord Message-ID: <6cfe874c-eac2-bc7d-b27a-60b5e710dfca@bothner.com> Date: Mon, 25 Mar 2019 22:03:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------BCA921CD11AA4CDD1A9F855B" X-IsSubscribed: yes X-SW-Source: 2019-q1/txt/msg00026.txt.bz2 This is a multi-part message in MIME format. --------------BCA921CD11AA4CDD1A9F855B Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1757 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/ --------------BCA921CD11AA4CDD1A9F855B Content-Type: text/x-patch; name="gvector.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="gvector.patch" Content-length: 12184 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 - implements Comparable + implements Comparable, GVector { 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 - implements Comparable + implements Comparable, GVector { 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 - implements Comparable + implements Comparable, GVector { 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 extends SimpleVector - implements Consumable, Comparable + implements Consumable, Comparable, GVector { Object[] data; protected static Object[] empty = new Object[0]; @@ -64,16 +64,17 @@ public class FVector extends SimpleVector this.info = VERY_SIMPLE_FLAG; } - public void copyFrom (int index, FVector src, int start, int end) { + public void copyFrom (int index, SimpleVector 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 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 extends AVector, 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 extends SimpleVector - implements Comparable + implements Comparable, GVector { 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 extends AbstractSequence implements AVector { +public class Range extends AbstractSequence implements GVector { 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 extends AbstractSequence 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"; + else + msg = "cannot convert a "+value.getClass().getName()+" to FVector"; + 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) :: (instance? x vector)) -(define (make-vector (k :: ) #!optional (fill #!null)) :: vector +(define (make-vector (k :: ) #!optional (fill #!null)) ::vector (gnu.lists.FVector k fill)) -(define (vector-length x :: ) :: +(define (vector-length x ::gvector) :: (invoke x 'size)) -(define (vector-set! (vector ::vector) (k ::int) obj) :: - (invoke vector 'setAt k obj)) +(define (vector-set! (vec ::vector) (k ::int) obj) :: + (invoke vec 'setAt k obj)) (define-procedure vector-ref setter: vector-set! (begin - (define (vector-ref (vector :: ) (k :: )) + (define (vector-ref (vector ::gvector) (k ::int)) (invoke vector 'get k)) vector-ref)) -(define (vector->list (vec :: ) +(define (vector->list (vec ::gvector) #!optional (start ::int 0) (end ::int (vec:size))) :: (let loop ((result :: '()) @@ -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)) --------------BCA921CD11AA4CDD1A9F855B--