New Upstream Snapshot - clojure
Ready changes
Summary
Merged new upstream version: 1.11.1+git20221207.1.527b330+ds (was: 1.11.1).
Resulting package
Built on 2023-01-18T23:43 (took 6m18s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-snapshots clojureapt install -t fresh-snapshots libclojure-java
Lintian Result
- clojure_1.11.1+git20221207.1.527b330+ds-1~jan+nus2.dsc
- clojure_1.11.1+git20221207.1.527b330+ds-1~jan+nus2_all.deb
- clojure_1.11.1+git20221207.1.527b330+ds-1~jan+nus2_amd64.buildinfo
- libclojure-java_1.11.1+git20221207.1.527b330+ds-1~jan+nus2_all.deb
- clojure_1.11.1+git20221207.1.527b330+ds-1~jan+nus2_amd64.changes
Diff
diff --git a/.github/PULL_REQUEST_TEMPLATE b/.github/PULL_REQUEST_TEMPLATE
deleted file mode 100644
index 31b549a8..00000000
--- a/.github/PULL_REQUEST_TEMPLATE
+++ /dev/null
@@ -1,5 +0,0 @@
-Hi! This project does not accept pull requests.
-
-Please see the guidelines for contribution on how to file issues or provide patches:
-
-https://github.com/clojure/clojure/blob/master/CONTRIBUTING.md
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 18cf4cc0..00000000
--- a/.gitignore
+++ /dev/null
@@ -1,9 +0,0 @@
-*.jar
-target
-clojure.iws
-clojure.ipr
-nbproject/private/
-maven-classpath
-maven-classpath.properties
-.idea/
-*.iml
diff --git a/debian/changelog b/debian/changelog
index bab9d0f0..99222f8e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+clojure (1.11.1+git20221207.1.527b330+ds-1) UNRELEASED; urgency=low
+
+ * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk> Wed, 18 Jan 2023 23:39:33 -0000
+
clojure (1.11.1-2) unstable; urgency=medium
* Change the symlinked maven artifact for libclojure-java from 1.11.x to
diff --git a/debian/patches/02-modify-cli-usage.patch b/debian/patches/02-modify-cli-usage.patch
index dc445cf7..7749a10a 100644
--- a/debian/patches/02-modify-cli-usage.patch
+++ b/debian/patches/02-modify-cli-usage.patch
@@ -1,10 +1,10 @@
Description: Simplify the usage instructions for the command line tool
Author: Emmanuel Bourg <ebourg@apache.org>
Forwarded: not-needed
-Index: clojure/src/clj/clojure/main.clj
+Index: clojure.git/src/clj/clojure/main.clj
===================================================================
---- clojure.orig/src/clj/clojure/main.clj
-+++ clojure/src/clj/clojure/main.clj
+--- clojure.git.orig/src/clj/clojure/main.clj
++++ clojure.git/src/clj/clojure/main.clj
@@ -567,7 +567,7 @@ by default when a new command-line REPL
[args]
(println "WARNING: clojure.lang.Repl is deprecated.
diff --git a/pom.xml b/pom.xml
index b15f6402..2dd37faa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
<artifactId>clojure</artifactId>
<name>clojure</name>
<packaging>jar</packaging>
- <version>1.11.1</version>
+ <version>1.12.0-master-SNAPSHOT</version>
<url>http://clojure.org/</url>
<description>Clojure core environment and runtime library.</description>
@@ -30,7 +30,7 @@
<connection>scm:git:git@github.com:clojure/clojure.git</connection>
<developerConnection>scm:git:git@github.com:clojure/clojure.git</developerConnection>
<url>git@github.com:clojure/clojure.git</url>
- <tag>clojure-1.11.1</tag>
+ <tag>HEAD</tag>
</scm>
<properties>
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index 42abb7f0..a146fcfa 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -2924,7 +2924,7 @@
(cons (first s) (take-while pred (rest s))))))))
(defn drop
- "Returns a lazy sequence of all but the first n items in coll.
+ "Returns a laziness-preserving sequence of all but the first n items in coll.
Returns a stateful transducer when no collection is provided."
{:added "1.0"
:static true}
@@ -2941,12 +2941,14 @@
result
(rf result input))))))))
([n coll]
- (let [step (fn [n coll]
- (let [s (seq coll)]
- (if (and (pos? n) s)
- (recur (dec n) (rest s))
- s)))]
- (lazy-seq (step n coll)))))
+ (if (instance? clojure.lang.IDrop coll)
+ (or (.drop ^clojure.lang.IDrop coll n) ())
+ (let [step (fn [n coll]
+ (let [s (seq coll)]
+ (if (and (pos? n) s)
+ (recur (dec n) (rest s))
+ s)))]
+ (lazy-seq (step n coll))))))
(defn drop-last
"Return a lazy sequence of all but the last n (default 1) items in coll"
@@ -3167,20 +3169,24 @@
{:added "1.0"
:static true}
[coll n]
+ (if (instance? clojure.lang.IDrop coll)
+ (.drop ^clojure.lang.IDrop coll n)
(loop [n n xs (seq coll)]
(if (and xs (pos? n))
(recur (dec n) (next xs))
- xs)))
+ xs))))
(defn nthrest
"Returns the nth rest of coll, coll when n is 0."
{:added "1.3"
:static true}
[coll n]
+ (if (instance? clojure.lang.IDrop coll)
+ (or (.drop ^clojure.lang.IDrop coll n) ())
(loop [n n xs coll]
(if-let [xs (and (pos? n) (seq xs))]
(recur (dec n) (rest xs))
- xs)))
+ xs))))
(defn partition
"Returns a lazy sequence of lists of n items each, at offsets step
@@ -6238,13 +6244,6 @@ fails, attempts to require sym's namespace and retries."
([m k f x y z & more]
(assoc m k (apply f (get m k) x y z more))))
-(defn empty?
- "Returns true if coll has no items - same as (not (seq coll)).
- Please use the idiom (seq x) rather than (not (empty? x))"
- {:added "1.0"
- :static true}
- [coll] (not (seq coll)))
-
(defn coll?
"Returns true if x implements IPersistentCollection"
{:added "1.0"
@@ -6300,6 +6299,16 @@ fails, attempts to require sym's namespace and retries."
:static true}
[coll] (instance? clojure.lang.Counted coll))
+(defn empty?
+ "Returns true if coll has no items. To check the emptiness of a seq,
+ please use the idiom (seq x) rather than (not (empty? x))"
+ {:added "1.0"
+ :static true}
+ [coll]
+ (if (counted? coll)
+ (zero? (count coll))
+ (not (seq coll))))
+
(defn reversible?
"Returns true if coll implements Reversible"
{:added "1.0"
@@ -7339,6 +7348,50 @@ fails, attempts to require sym's namespace and retries."
(let [seg (doall (take n s))]
(cons seg (partition-all n step (nthrest s step))))))))
+(defn splitv-at
+ "Returns a vector of [(into [] (take n) coll) (drop n coll)]"
+ {:added "1.12"}
+ [n coll]
+ [(into [] (take n) coll) (drop n coll)])
+
+(defn partitionv
+ "Returns a lazy sequence of vectors of n items each, at offsets step
+ apart. If step is not supplied, defaults to n, i.e. the partitions
+ do not overlap. If a pad collection is supplied, use its elements as
+ necessary to complete last partition upto n items. In case there are
+ not enough padding elements, return a partition with less than n items."
+ {:added "1.12"}
+ ([n coll]
+ (partitionv n n coll))
+ ([n step coll]
+ (lazy-seq
+ (when-let [s (seq coll)]
+ (let [p (into [] (take n) s)]
+ (when (= n (count p))
+ (cons p (partitionv n step (nthrest s step))))))))
+ ([n step pad coll]
+ (lazy-seq
+ (when-let [s (seq coll)]
+ (let [p (into [] (take n) s)]
+ (if (= n (count p))
+ (cons p (partitionv n step pad (nthrest s step)))
+ (list (into [] (take n) (concat p pad)))))))))
+
+(defn partitionv-all
+ "Returns a lazy sequence of vector partitions, but may include
+ partitions with fewer than n items at the end.
+ Returns a stateful transducer when no collection is provided."
+ {:added "1.12"}
+ ([n]
+ (partition-all n))
+ ([n coll]
+ (partitionv-all n n coll))
+ ([n step coll]
+ (lazy-seq
+ (when-let [s (seq coll)]
+ (let [seg (into [] (take n) coll)]
+ (cons seg (partitionv-all n step (drop step s))))))))
+
(defn shuffle
"Return a random permutation of coll"
{:added "1.2"
diff --git a/src/jvm/clojure/lang/AFunction.java b/src/jvm/clojure/lang/AFunction.java
index 2ef5cd9b..4ab8c693 100644
--- a/src/jvm/clojure/lang/AFunction.java
+++ b/src/jvm/clojure/lang/AFunction.java
@@ -17,6 +17,8 @@ import java.util.Comparator;
public abstract class AFunction extends AFn implements IObj, Comparator, Fn, Serializable {
+private static final long serialVersionUID = 4469383498184457675L;
+
public volatile MethodImplCache __methodImplCache;
public IPersistentMap meta(){
diff --git a/src/jvm/clojure/lang/AMapEntry.java b/src/jvm/clojure/lang/AMapEntry.java
index 41ae7563..56debb4f 100644
--- a/src/jvm/clojure/lang/AMapEntry.java
+++ b/src/jvm/clojure/lang/AMapEntry.java
@@ -16,6 +16,8 @@ import java.io.StringWriter;
public abstract class AMapEntry extends APersistentVector implements IMapEntry{
+private static final long serialVersionUID = -5007980429903443802L;
+
public Object nth(int i){
if(i == 0)
return key();
diff --git a/src/jvm/clojure/lang/APersistentMap.java b/src/jvm/clojure/lang/APersistentMap.java
index 7f962712..3dfb73a5 100644
--- a/src/jvm/clojure/lang/APersistentMap.java
+++ b/src/jvm/clojure/lang/APersistentMap.java
@@ -14,6 +14,9 @@ import java.io.Serializable;
import java.util.*;
public abstract class APersistentMap extends AFn implements IPersistentMap, Map, Iterable, Serializable, MapEquivalence, IHashEq {
+
+private static final long serialVersionUID = 6736310834519110267L;
+
int _hash;
int _hasheq;
diff --git a/src/jvm/clojure/lang/APersistentSet.java b/src/jvm/clojure/lang/APersistentSet.java
index 1c2ce8f4..2c8caad8 100644
--- a/src/jvm/clojure/lang/APersistentSet.java
+++ b/src/jvm/clojure/lang/APersistentSet.java
@@ -18,6 +18,9 @@ import java.util.Iterator;
import java.util.Set;
public abstract class APersistentSet extends AFn implements IPersistentSet, Collection, Set, Serializable, IHashEq {
+
+private static final long serialVersionUID = 889908853183699706L;
+
int _hash;
int _hasheq;
final IPersistentMap impl;
diff --git a/src/jvm/clojure/lang/APersistentVector.java b/src/jvm/clojure/lang/APersistentVector.java
index 3e88d14d..07115684 100644
--- a/src/jvm/clojure/lang/APersistentVector.java
+++ b/src/jvm/clojure/lang/APersistentVector.java
@@ -19,6 +19,9 @@ public abstract class APersistentVector extends AFn implements IPersistentVector
List,
RandomAccess, Comparable,
Serializable, IHashEq {
+
+private static final long serialVersionUID = 4667575149454420891L;
+
int _hash;
int _hasheq;
diff --git a/src/jvm/clojure/lang/ASeq.java b/src/jvm/clojure/lang/ASeq.java
index f0f8e5d4..ec1b4d67 100644
--- a/src/jvm/clojure/lang/ASeq.java
+++ b/src/jvm/clojure/lang/ASeq.java
@@ -14,6 +14,9 @@ import java.io.Serializable;
import java.util.*;
public abstract class ASeq extends Obj implements ISeq, Sequential, List, Serializable, IHashEq {
+
+private static final long serialVersionUID = 4748650717905139299L;
+
transient int _hash;
transient int _hasheq;
diff --git a/src/jvm/clojure/lang/ArityException.java b/src/jvm/clojure/lang/ArityException.java
index 49b7914b..5c0f384f 100644
--- a/src/jvm/clojure/lang/ArityException.java
+++ b/src/jvm/clojure/lang/ArityException.java
@@ -15,6 +15,8 @@ package clojure.lang;
*/
public class ArityException extends IllegalArgumentException {
+ private static final long serialVersionUID = 2265783180488869950L;
+
final public int actual;
final public String name;
diff --git a/src/jvm/clojure/lang/ArrayChunk.java b/src/jvm/clojure/lang/ArrayChunk.java
index 97430839..ba6334cf 100644
--- a/src/jvm/clojure/lang/ArrayChunk.java
+++ b/src/jvm/clojure/lang/ArrayChunk.java
@@ -16,6 +16,8 @@ import java.io.Serializable;
public final class ArrayChunk implements IChunk, Serializable {
+private static final long serialVersionUID = -8302142882294545702L;
+
final Object[] array;
final int off;
final int end;
diff --git a/src/jvm/clojure/lang/BigInt.java b/src/jvm/clojure/lang/BigInt.java
index a3ca9694..1f2b7580 100644
--- a/src/jvm/clojure/lang/BigInt.java
+++ b/src/jvm/clojure/lang/BigInt.java
@@ -17,6 +17,8 @@ import java.math.BigDecimal;
public final class BigInt extends Number implements IHashEq{
+private static final long serialVersionUID = 5097771279236135022L;
+
final public long lpart;
final public BigInteger bipart;
diff --git a/src/jvm/clojure/lang/ChunkedCons.java b/src/jvm/clojure/lang/ChunkedCons.java
index b52bc2b6..25b32200 100644
--- a/src/jvm/clojure/lang/ChunkedCons.java
+++ b/src/jvm/clojure/lang/ChunkedCons.java
@@ -14,6 +14,8 @@ package clojure.lang;
final public class ChunkedCons extends ASeq implements IChunkedSeq{
+private static final long serialVersionUID = 2773920188566401743L;
+
final IChunk chunk;
final ISeq _more;
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 12cf1e56..758108e8 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -410,7 +410,6 @@ static class DefExpr implements Expr{
public final Expr meta;
public final boolean initProvided;
public final boolean isDynamic;
- public final boolean shadowsCoreMapping;
public final String source;
public final int line;
public final int column;
@@ -419,9 +418,8 @@ static class DefExpr implements Expr{
final static Method setMetaMethod = Method.getMethod("void setMeta(clojure.lang.IPersistentMap)");
final static Method setDynamicMethod = Method.getMethod("clojure.lang.Var setDynamic(boolean)");
final static Method symintern = Method.getMethod("clojure.lang.Symbol intern(String, String)");
- final static Method internVar = Method.getMethod("clojure.lang.Var refer(clojure.lang.Symbol, clojure.lang.Var)");
- public DefExpr(String source, int line, int column, Var var, Expr init, Expr meta, boolean initProvided, boolean isDynamic, boolean shadowsCoreMapping){
+ public DefExpr(String source, int line, int column, Var var, Expr init, Expr meta, boolean initProvided, boolean isDynamic){
this.source = source;
this.line = line;
this.column = column;
@@ -429,7 +427,6 @@ static class DefExpr implements Expr{
this.init = init;
this.meta = meta;
this.isDynamic = isDynamic;
- this.shadowsCoreMapping = shadowsCoreMapping;
this.initProvided = initProvided;
}
@@ -475,18 +472,6 @@ static class DefExpr implements Expr{
public void emit(C context, ObjExpr objx, GeneratorAdapter gen){
objx.emitVar(gen, var);
-
- if (shadowsCoreMapping)
- {
- gen.dup();
- gen.getField(VAR_TYPE, "ns", NS_TYPE);
- gen.swap();
- gen.dup();
- gen.getField(VAR_TYPE, "sym", SYMBOL_TYPE);
- gen.swap();
- gen.invokeVirtual(NS_TYPE, internVar);
- }
-
if(isDynamic)
{
gen.push(isDynamic);
@@ -544,13 +529,11 @@ static class DefExpr implements Expr{
Var v = lookupVar(sym, true);
if(v == null)
throw Util.runtimeException("Can't refer to qualified var that doesn't exist");
- boolean shadowsCoreMapping = false;
if(!v.ns.equals(currentNS()))
{
if(sym.ns == null)
{
v = currentNS().intern(sym);
- shadowsCoreMapping = true;
registerVar(v);
}
// throw Util.runtimeException("Name conflict, can't def " + sym + " because namespace: " + currentNS().name +
@@ -594,7 +577,7 @@ static class DefExpr implements Expr{
Expr meta = mm.count()==0 ? null:analyze(context == C.EVAL ? context : C.EXPRESSION, mm);
return new DefExpr((String) SOURCE.deref(), lineDeref(), columnDeref(),
v, analyze(context == C.EVAL ? context : C.EXPRESSION, RT.third(form), v.sym.name),
- meta, RT.count(form) == 3, isDynamic, shadowsCoreMapping);
+ meta, RT.count(form) == 3, isDynamic);
}
}
}
diff --git a/src/jvm/clojure/lang/Cons.java b/src/jvm/clojure/lang/Cons.java
index 88dceef3..9378881d 100644
--- a/src/jvm/clojure/lang/Cons.java
+++ b/src/jvm/clojure/lang/Cons.java
@@ -16,6 +16,8 @@ import java.io.Serializable;
final public class Cons extends ASeq implements Serializable {
+private static final long serialVersionUID = 6682587018567831263L;
+
private final Object _first;
private final ISeq _more;
diff --git a/src/jvm/clojure/lang/Cycle.java b/src/jvm/clojure/lang/Cycle.java
index 87769555..a605e8ca 100644
--- a/src/jvm/clojure/lang/Cycle.java
+++ b/src/jvm/clojure/lang/Cycle.java
@@ -14,6 +14,8 @@ package clojure.lang;
public class Cycle extends ASeq implements IReduce, IPending {
+private static final long serialVersionUID = 4007270937279943908L;
+
private final ISeq all; // never null
private final ISeq prev;
private volatile ISeq _current; // lazily realized
diff --git a/src/jvm/clojure/lang/EnumerationSeq.java b/src/jvm/clojure/lang/EnumerationSeq.java
index 3616fa78..acd13ca1 100644
--- a/src/jvm/clojure/lang/EnumerationSeq.java
+++ b/src/jvm/clojure/lang/EnumerationSeq.java
@@ -17,6 +17,9 @@ import java.io.NotSerializableException;
import java.util.Enumeration;
public class EnumerationSeq extends ASeq{
+
+private static final long serialVersionUID = 5227192199685595994L;
+
final Enumeration iter;
final State state;
diff --git a/src/jvm/clojure/lang/ExceptionInfo.java b/src/jvm/clojure/lang/ExceptionInfo.java
index 92040d21..f7b704de 100644
--- a/src/jvm/clojure/lang/ExceptionInfo.java
+++ b/src/jvm/clojure/lang/ExceptionInfo.java
@@ -16,6 +16,9 @@ package clojure.lang;
* exception classes.
*/
public class ExceptionInfo extends RuntimeException implements IExceptionInfo {
+
+ private static final long serialVersionUID = -1073473305916521986L;
+
public final IPersistentMap data;
public ExceptionInfo(String s, IPersistentMap data) {
diff --git a/src/jvm/clojure/lang/FnLoaderThunk.java b/src/jvm/clojure/lang/FnLoaderThunk.java
index 692e45c7..1411bf49 100644
--- a/src/jvm/clojure/lang/FnLoaderThunk.java
+++ b/src/jvm/clojure/lang/FnLoaderThunk.java
@@ -14,6 +14,8 @@ package clojure.lang;
public class FnLoaderThunk extends RestFn{
+private static final long serialVersionUID = 2194257205455463687L;
+
final Var v;
final ClassLoader loader;
final String fnClassName;
diff --git a/src/jvm/clojure/lang/IDrop.java b/src/jvm/clojure/lang/IDrop.java
new file mode 100644
index 00000000..336c0a82
--- /dev/null
+++ b/src/jvm/clojure/lang/IDrop.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) Rich Hickey. All rights reserved.
+ * The use and distribution terms for this software are covered by the
+ * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+ * which can be found in the file epl-v10.html at the root of this distribution.
+ * By using this software in any fashion, you are agreeing to be bound by
+ * the terms of this license.
+ * You must not remove this notice, or any other, from this software.
+ **/
+
+package clojure.lang;
+
+/**
+ * Persistent or algorithmically defined collections can implement IDrop to provide
+ * a means of dropping N items that is more efficient than sequential walking.
+ */
+public interface IDrop{
+ /**
+ * Returns a collection that is Sequential, ISeq, and IReduceInit. It is also
+ * useful if the returned coll implements IDrop for subsequent use in a
+ * partition-like scenario.
+ *
+ * If n is <= 0, return this.
+ * If n drops to or past the end of the collection, return null.
+ *
+ * @param n Items to drop
+ * @return Collection that is Sequential, ISeq, and IReduceInit
+ */
+ Sequential drop(int n);
+}
diff --git a/src/jvm/clojure/lang/Iterate.java b/src/jvm/clojure/lang/Iterate.java
index aec0c14a..0bbe733d 100644
--- a/src/jvm/clojure/lang/Iterate.java
+++ b/src/jvm/clojure/lang/Iterate.java
@@ -14,6 +14,8 @@ package clojure.lang;
public class Iterate extends ASeq implements IReduce, IPending {
+private static final long serialVersionUID = -78221705247226450L;
+
private static final Object UNREALIZED_SEED = new Object();
private final IFn f; // never null
private final Object prevSeed;
diff --git a/src/jvm/clojure/lang/IteratorSeq.java b/src/jvm/clojure/lang/IteratorSeq.java
index 9ecdbc48..18b9cf35 100644
--- a/src/jvm/clojure/lang/IteratorSeq.java
+++ b/src/jvm/clojure/lang/IteratorSeq.java
@@ -15,6 +15,9 @@ import java.io.NotSerializableException;
import java.util.Iterator;
public class IteratorSeq extends ASeq{
+
+private static final long serialVersionUID = -2631916503522522760L;
+
final Iterator iter;
final State state;
diff --git a/src/jvm/clojure/lang/LazySeq.java b/src/jvm/clojure/lang/LazySeq.java
index 0ca4e462..f9f9bfb2 100644
--- a/src/jvm/clojure/lang/LazySeq.java
+++ b/src/jvm/clojure/lang/LazySeq.java
@@ -16,6 +16,8 @@ import java.util.*;
public final class LazySeq extends Obj implements ISeq, Sequential, List, IPending, IHashEq{
+private static final long serialVersionUID = 7700080124382322592L;
+
private IFn fn;
private Object sv;
private ISeq s;
diff --git a/src/jvm/clojure/lang/LongRange.java b/src/jvm/clojure/lang/LongRange.java
index 348e3620..d1bfba2f 100644
--- a/src/jvm/clojure/lang/LongRange.java
+++ b/src/jvm/clojure/lang/LongRange.java
@@ -16,87 +16,82 @@ import java.util.Iterator;
import java.util.NoSuchElementException;
/**
- * Implements the special common case of a finite range based on long start, end, and step.
+ * Implements the special common case of a finite range based on long start, end, and step,
+ * with no more than Integer.MAX_VALUE items.
*/
-public class LongRange extends ASeq implements Counted, IChunkedSeq, IReduce {
+public class LongRange extends ASeq implements Counted, IChunkedSeq, IReduce, IDrop {
-private static final int CHUNK_SIZE = 32;
+private static final long serialVersionUID = -1467242400566893909L;
// Invariants guarantee this is never an empty or infinite seq
// assert(start != end && step != 0)
final long start;
final long end;
final long step;
-final BoundsCheck boundsCheck;
-private volatile LongChunk _chunk; // lazy
-private volatile ISeq _chunkNext; // lazy
-private volatile ISeq _next; // cached
+final int count;
-private static interface BoundsCheck extends Serializable {
- boolean exceededBounds(long val);
-}
-
-private static BoundsCheck positiveStep(final long end) {
- return new BoundsCheck() {
- public boolean exceededBounds(long val){
- return (val >= end);
- }
- };
-}
-
-private static BoundsCheck negativeStep(final long end) {
- return new BoundsCheck() {
- public boolean exceededBounds(long val){
- return (val <= end);
- }
- };
-}
-
-private LongRange(long start, long end, long step, BoundsCheck boundsCheck){
+private LongRange(long start, long end, long step, int count){
this.start = start;
this.end = end;
this.step = step;
- this.boundsCheck = boundsCheck;
+ this.count = count;
}
-private LongRange(long start, long end, long step, BoundsCheck boundsCheck, LongChunk chunk, ISeq chunkNext){
+private LongRange(IPersistentMap meta, long start, long end, long step, int count){
+ super(meta);
this.start = start;
this.end = end;
this.step = step;
- this.boundsCheck = boundsCheck;
- this._chunk = chunk;
- this._chunkNext = chunkNext;
+ this.count = count;
}
-private LongRange(IPersistentMap meta, long start, long end, long step, BoundsCheck boundsCheck, LongChunk chunk, ISeq chunkNext){
- super(meta);
- this.start = start;
- this.end = end;
- this.step = step;
- this.boundsCheck = boundsCheck;
- this._chunk = chunk;
- this._chunkNext = chunkNext;
+// returns exact size of remaining items OR throws ArithmeticException for overflow case
+static long rangeCount(long start, long end, long step) {
+ // (1) count = ceiling ( (end - start) / step )
+ // (2) ceiling(a/b) = (a+b+o)/b where o=-1 for positive stepping and +1 for negative stepping
+ // thus: count = end - start + step + o / step
+ return Numbers.add(Numbers.add(Numbers.minus(end, start), step), step > 0 ? -1 : 1) / step;
}
public static ISeq create(long end) {
- if(end > 0)
- return new LongRange(0L, end, 1L, positiveStep(end));
- return PersistentList.EMPTY;
+ if(end > 0) {
+ try {
+ return new LongRange(0L, end, 1L, Math.toIntExact(rangeCount(0L, end, 1L)));
+ } catch(ArithmeticException e) {
+ return Range.create(end); // count > Integer.MAX_VALUE
+ }
+ } else {
+ return PersistentList.EMPTY;
+ }
}
public static ISeq create(long start, long end) {
- if(start >= end)
+ if(start >= end) {
return PersistentList.EMPTY;
- return new LongRange(start, end, 1L, positiveStep(end));
+ } else {
+ try {
+ return new LongRange(start, end, 1L, Math.toIntExact(rangeCount(start, end, 1L)));
+ } catch(ArithmeticException e) {
+ return Range.create(start, end);
+ }
+ }
}
public static ISeq create(final long start, long end, long step) {
if(step > 0) {
if(end <= start) return PersistentList.EMPTY;
- return new LongRange(start, end, step, positiveStep(end));
+ try {
+ return new LongRange(start, end, step, Math.toIntExact(rangeCount(start, end, step)));
+ } catch(ArithmeticException e) {
+ return Range.create(start, end, step);
+ }
} else if(step < 0) {
if(end >= start) return PersistentList.EMPTY;
- return new LongRange(start, end, step, negativeStep(end));
+ try {
+ return new LongRange(start, end, step, Math.toIntExact(rangeCount(start, end, step)));
+ } catch(ArithmeticException e) {
+ return Range.create(start, end, step);
+ }
} else {
if(end == start) return PersistentList.EMPTY;
return Repeat.create(start);
@@ -106,134 +101,70 @@ public static ISeq create(final long start, long end, long step) {
public Obj withMeta(IPersistentMap meta){
if(meta == _meta)
return this;
- return new LongRange(meta, start, end, step, boundsCheck, _chunk, _chunkNext);
+ return new LongRange(meta, start, end, step, count);
}
public Object first() {
return start;
}
-public void forceChunk() {
- if(_chunk != null) return;
-
- long count;
- try {
- count = rangeCount(start, end, step);
- } catch(ArithmeticException e) {
- // size of total range is > Long.MAX_VALUE so must step to count
- // this only happens in pathological range cases like:
- // (range -9223372036854775808 9223372036854775807 9223372036854775807)
- count = steppingCount(start, end, step);
- }
-
- if (count > CHUNK_SIZE) { // not last chunk
- long nextStart = start + (step * CHUNK_SIZE); // cannot overflow, must be < end
- _chunkNext = new LongRange(nextStart, end, step, boundsCheck);
- _chunk = new LongChunk(start, step, CHUNK_SIZE);
- } else { // last chunk
- _chunk = new LongChunk(start, step, (int) count); // count must be <= CHUNK_SIZE
- }
-}
-
public ISeq next() {
- if(_next != null)
- return _next;
-
- forceChunk();
- if(_chunk.count() > 1) {
- LongChunk smallerChunk = _chunk.dropFirst();
- _next = new LongRange(smallerChunk.first(), end, step, boundsCheck, smallerChunk, _chunkNext);
- return _next;
+ if(count > 1) {
+ return new LongRange(start + step, end, step, count-1);
+ } else {
+ return null;
}
- return chunkedNext();
}
public IChunk chunkedFirst() {
- forceChunk();
- return _chunk;
+ return new LongChunk(start, step, count);
}
public ISeq chunkedNext() {
- return chunkedMore().seq();
+ return null;
}
public ISeq chunkedMore() {
- forceChunk();
- if(_chunkNext == null)
- return PersistentList.EMPTY;
- return _chunkNext;
+ return PersistentList.EMPTY;
}
-// fallback count mechanism for pathological cases
-// returns either exact count or CHUNK_SIZE+1
-long steppingCount(long start, long end, long step) {
- long count = 1;
- long s = start;
- while(count <= CHUNK_SIZE) {
- try {
- s = Numbers.add(s, step);
- if(boundsCheck.exceededBounds(s))
- break;
- else
- count++;
- } catch(ArithmeticException e) {
- break;
- }
+public Sequential drop(int n) {
+ if(n <= 0) {
+ return this;
+ } else if(n < count) {
+ return new LongRange(start+(step*n), end, step, count - n);
+ } else {
+ return null;
}
- return count;
-}
-
-// returns exact size of remaining items OR throws ArithmeticException for overflow case
-long rangeCount(long start, long end, long step) {
- // (1) count = ceiling ( (end - start) / step )
- // (2) ceiling(a/b) = (a+b+o)/b where o=-1 for positive stepping and +1 for negative stepping
- // thus: count = end - start + step + o / step
- return Numbers.add(Numbers.add(Numbers.minus(end, start), step), this.step > 0 ? -1 : 1) / step;
}
public int count() {
- try {
- long c = rangeCount(start, end, step);
- if(c > Integer.MAX_VALUE) {
- return Numbers.throwIntOverflow();
- } else {
- return (int) c;
- }
- } catch(ArithmeticException e) {
- // rare case from large range or step, fall back to iterating and counting
- Iterator iter = this.iterator();
- long count = 0;
- while(iter.hasNext()) {
- iter.next();
- count++;
- }
-
- if(count > Integer.MAX_VALUE)
- return Numbers.throwIntOverflow();
- else
- return (int)count;
- }
+ return count;
}
public Object reduce(IFn f) {
Object acc = start;
long i = start + step;
- while(! boundsCheck.exceededBounds(i)) {
+ int n = count;
+ while(n > 1) {
acc = f.invoke(acc, i);
if (acc instanceof Reduced) return ((Reduced)acc).deref();
i += step;
+ n--;
}
return acc;
}
public Object reduce(IFn f, Object val) {
Object acc = val;
+ int n = count;
long i = start;
do {
acc = f.invoke(acc, i);
if (RT.isReduced(acc)) return ((Reduced)acc).deref();
i += step;
- } while(! boundsCheck.exceededBounds(i));
+ n--;
+ } while(n > 0);
return acc;
}
@@ -243,26 +174,22 @@ public Iterator iterator() {
class LongRangeIterator implements Iterator {
private long next;
- private boolean hasNext;
+ private int remaining;
public LongRangeIterator() {
this.next = start;
- this.hasNext = true;
+ this.remaining = count;
}
public boolean hasNext() {
- return hasNext;
+ return remaining > 0;
}
public Object next() {
- if (hasNext) {
+ if (remaining > 0) {
long ret = next;
- try {
- next = Numbers.add(next, step);
- hasNext = ! boundsCheck.exceededBounds(next);
- } catch(ArithmeticException e) {
- hasNext = false;
- }
+ next = next + step;
+ remaining = remaining - 1;
return ret;
} else {
throw new NoSuchElementException();
@@ -322,4 +249,4 @@ private static class LongChunk implements IChunk, Serializable {
}
}
-}
\ No newline at end of file
+}
diff --git a/src/jvm/clojure/lang/MapEntry.java b/src/jvm/clojure/lang/MapEntry.java
index 310199c1..777b2627 100644
--- a/src/jvm/clojure/lang/MapEntry.java
+++ b/src/jvm/clojure/lang/MapEntry.java
@@ -13,6 +13,9 @@ package clojure.lang;
import java.util.Iterator;
public class MapEntry extends AMapEntry{
+
+private static final long serialVersionUID = -3752414622414469244L;
+
final Object _key;
final Object _val;
diff --git a/src/jvm/clojure/lang/Namespace.java b/src/jvm/clojure/lang/Namespace.java
index 68cded63..35981577 100644
--- a/src/jvm/clojure/lang/Namespace.java
+++ b/src/jvm/clojure/lang/Namespace.java
@@ -18,6 +18,9 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicReference;
public class Namespace extends AReference implements Serializable {
+
+private static final long serialVersionUID = -3134444395801383865L;
+
final public Symbol name;
transient final AtomicReference<IPersistentMap> mappings = new AtomicReference<IPersistentMap>();
transient final AtomicReference<IPersistentMap> aliases = new AtomicReference<IPersistentMap>();
@@ -47,11 +50,22 @@ public IPersistentMap getMappings(){
return mappings.get();
}
+/**
+ * An interned mapping is one where a var's ns matches the current ns and its sym matches the mapping key.
+ * Once established, interned mappings should never change.
+ */
+private boolean isInternedMapping(Symbol sym, Object o){
+ return(o instanceof Var &&
+ ((Var) o).ns == this &&
+ ((Var) o).sym.equals(sym));
+}
+
public Var intern(Symbol sym){
if(sym.ns != null)
{
throw new IllegalArgumentException("Can't intern namespace-qualified symbol");
}
+
IPersistentMap map = getMappings();
Object o;
Var v = null;
@@ -63,32 +77,50 @@ public Var intern(Symbol sym){
mappings.compareAndSet(map, newMap);
map = getMappings();
}
- if(o instanceof Var && ((Var) o).ns == this)
+ if(isInternedMapping(sym, o))
return (Var) o;
if(v == null)
v = new Var(this, sym);
- warnOrFailOnReplace(sym, o, v);
-
+ if(checkReplacement(sym, o, v)){
+ while (!mappings.compareAndSet(map, map.assoc(sym, v)))
+ map = getMappings();
- while(!mappings.compareAndSet(map, map.assoc(sym, v)))
- map = getMappings();
+ return v;
+ }
- return v;
+ return (Var) o;
}
-private void warnOrFailOnReplace(Symbol sym, Object o, Object v){
- if (o instanceof Var)
- {
- Namespace ns = ((Var)o).ns;
- if (ns == this || (v instanceof Var && ((Var)v).ns == RT.CLOJURE_NS))
- return;
- if (ns != RT.CLOJURE_NS)
- throw new IllegalStateException(sym + " already refers to: " + o + " in namespace: " + name);
- }
- RT.errPrintWriter().println("WARNING: " + sym + " already refers to: " + o + " in namespace: " + name
- + ", being replaced by: " + v);
+/*
+ This method checks if a namespace's mapping is applicable and warns on problematic cases.
+ It will return a boolean indicating if a mapping is replaceable.
+ The semantics of what constitutes a legal replacement mapping is summarized as follows:
+
+| classification | in namespace ns | newval = anything other than ns/name | newval = ns/name |
+|----------------+------------------------+--------------------------------------+-------------------------------------|
+| native mapping | name -> ns/name | no replace, warn-if newval not-core | no replace, warn-if newval not-core |
+| alias mapping | name -> other/whatever | warn + replace | warn + replace |
+*/
+private boolean checkReplacement(Symbol sym, Object old, Object neu){
+ if(old instanceof Var) {
+ Namespace ons = ((Var)old).ns;
+ Namespace nns = neu instanceof Var ? ((Var) neu).ns : null;
+
+ if(isInternedMapping(sym, old)){
+ if(nns != RT.CLOJURE_NS){
+ RT.errPrintWriter().println("REJECTED: attempt to replace interned var "
+ + old + " with " + neu + " in " + name + ", you must ns-unmap first");
+ return false;
+ }
+ else
+ return false;
+ }
+ }
+ RT.errPrintWriter().println("WARNING: " + sym + " already refers to: " + old + " in namespace: " + name
+ + ", being replaced by: " + neu);
+ return true;
}
Object reference(Symbol sym, Object val){
@@ -96,6 +128,7 @@ Object reference(Symbol sym, Object val){
{
throw new IllegalArgumentException("Can't intern namespace-qualified symbol");
}
+
IPersistentMap map = getMappings();
Object o;
while((o = map.valAt(sym)) == null)
@@ -107,13 +140,14 @@ Object reference(Symbol sym, Object val){
if(o == val)
return o;
- warnOrFailOnReplace(sym, o, val);
-
- while(!mappings.compareAndSet(map, map.assoc(sym, val)))
- map = getMappings();
+ if(checkReplacement(sym, o, val)){
+ while (!mappings.compareAndSet(map, map.assoc(sym, val)))
+ map = getMappings();
- return val;
+ return val;
+ }
+ return o;
}
public static boolean areDifferentInstancesOfSameClassName(Class cls1, Class cls2) {
diff --git a/src/jvm/clojure/lang/Obj.java b/src/jvm/clojure/lang/Obj.java
index bd7ee918..655d0911 100644
--- a/src/jvm/clojure/lang/Obj.java
+++ b/src/jvm/clojure/lang/Obj.java
@@ -16,6 +16,8 @@ import java.io.Serializable;
public abstract class Obj implements IObj, Serializable {
+private static final long serialVersionUID = 802029099426284526L;
+
final IPersistentMap _meta;
public Obj(IPersistentMap meta){
diff --git a/src/jvm/clojure/lang/PersistentArrayMap.java b/src/jvm/clojure/lang/PersistentArrayMap.java
index 1f86fd80..18bbcaa7 100644
--- a/src/jvm/clojure/lang/PersistentArrayMap.java
+++ b/src/jvm/clojure/lang/PersistentArrayMap.java
@@ -27,7 +27,9 @@ import java.util.NoSuchElementException;
* <p>null keys and values are ok, but you won't be able to distinguish a null value via valAt - use contains/entryAt</p>
*/
-public class PersistentArrayMap extends APersistentMap implements IObj, IEditableCollection, IMapIterable, IKVReduce{
+public class PersistentArrayMap extends APersistentMap implements IObj, IEditableCollection, IMapIterable, IKVReduce, IDrop{
+
+private static final long serialVersionUID = -2074065891090893601L;
final Object[] array;
static final int HASHTABLE_THRESHOLD = 16;
@@ -348,11 +350,19 @@ public ISeq seq(){
return null;
}
+public Sequential drop(int n) {
+ if(array.length > 0) {
+ return ((Seq) seq()).drop(n);
+ } else {
+ return null;
+ }
+}
+
public IPersistentMap meta(){
return _meta;
}
-static class Seq extends ASeq implements Counted{
+static class Seq extends ASeq implements Counted, IReduce, IDrop {
final Object[] array;
final int i;
@@ -381,16 +391,52 @@ static class Seq extends ASeq implements Counted{
return (array.length - i) / 2;
}
+ public Sequential drop(int n) {
+ if(n < count()) {
+ return new Seq(array, i + (2 * n));
+ } else {
+ return null;
+ }
+ }
+
public Obj withMeta(IPersistentMap meta){
if(meta() == meta)
return this;
return new Seq(meta, array, i);
}
+
+ public Iterator iterator() {
+ return new Iter(array, i-2, APersistentMap.MAKE_ENTRY);
+ }
+
+ public Object reduce(IFn f) {
+ if(i < array.length) {
+ Object acc = MapEntry.create(array[i], array[i+1]);
+ for(int j=i+2;j < array.length;j+=2){
+ acc = f.invoke(acc, MapEntry.create(array[j], array[j+1]));
+ if(RT.isReduced(acc))
+ return ((IDeref)acc).deref();
+ }
+ return acc;
+ } else {
+ return f.invoke();
+ }
+ }
+
+ public Object reduce(IFn f, Object init) {
+ Object acc = init;
+ for(int j=i;j < array.length;j+=2){
+ acc = f.invoke(acc, MapEntry.create(array[j], array[j+1]));
+ if(RT.isReduced(acc))
+ return ((IDeref)acc).deref();
+ }
+ return acc;
+ }
}
static class Iter implements Iterator{
- IFn f;
- Object[] array;
+ final IFn f;
+ final Object[] array;
int i;
//for iterator
diff --git a/src/jvm/clojure/lang/PersistentHashMap.java b/src/jvm/clojure/lang/PersistentHashMap.java
index 0cb12597..8f15944b 100644
--- a/src/jvm/clojure/lang/PersistentHashMap.java
+++ b/src/jvm/clojure/lang/PersistentHashMap.java
@@ -27,6 +27,8 @@ import java.util.concurrent.atomic.AtomicReference;
public class PersistentHashMap extends APersistentMap implements IEditableCollection, IObj, IMapIterable, IKVReduce {
+private static final long serialVersionUID = -8682496769319143320L;
+
final int count;
final INode root;
final boolean hasNull;
diff --git a/src/jvm/clojure/lang/PersistentHashSet.java b/src/jvm/clojure/lang/PersistentHashSet.java
index d3a71626..b481a944 100644
--- a/src/jvm/clojure/lang/PersistentHashSet.java
+++ b/src/jvm/clojure/lang/PersistentHashSet.java
@@ -16,6 +16,8 @@ import java.util.List;
public class PersistentHashSet extends APersistentSet implements IObj, IEditableCollection {
+private static final long serialVersionUID = 6973890746204954938L;
+
static public final PersistentHashSet EMPTY = new PersistentHashSet(null, PersistentHashMap.EMPTY);
final IPersistentMap _meta;
diff --git a/src/jvm/clojure/lang/PersistentList.java b/src/jvm/clojure/lang/PersistentList.java
index 618d52fc..225651d6 100644
--- a/src/jvm/clojure/lang/PersistentList.java
+++ b/src/jvm/clojure/lang/PersistentList.java
@@ -15,6 +15,8 @@ import java.util.*;
public class PersistentList extends ASeq implements IPersistentList, IReduce, List, Counted {
+private static final long serialVersionUID = -8833289659955219995L;
+
private final Object _first;
private final IPersistentList _rest;
private final int _count;
diff --git a/src/jvm/clojure/lang/PersistentQueue.java b/src/jvm/clojure/lang/PersistentQueue.java
index af916193..881c1900 100644
--- a/src/jvm/clojure/lang/PersistentQueue.java
+++ b/src/jvm/clojure/lang/PersistentQueue.java
@@ -24,6 +24,8 @@ import java.util.NoSuchElementException;
public class PersistentQueue extends Obj implements IPersistentList, Collection, Counted, IHashEq{
+private static final long serialVersionUID = 8247184423915313132L;
+
final public static PersistentQueue EMPTY = new PersistentQueue(null, 0, null, null);
//*
diff --git a/src/jvm/clojure/lang/PersistentStructMap.java b/src/jvm/clojure/lang/PersistentStructMap.java
index 734428c0..7e9c92e3 100644
--- a/src/jvm/clojure/lang/PersistentStructMap.java
+++ b/src/jvm/clojure/lang/PersistentStructMap.java
@@ -19,6 +19,8 @@ import java.util.NoSuchElementException;
public class PersistentStructMap extends APersistentMap implements IObj{
+private static final long serialVersionUID = -2701411408470234065L;
+
public static class Def implements Serializable{
final ISeq keys;
final IPersistentMap keyslots;
diff --git a/src/jvm/clojure/lang/PersistentVector.java b/src/jvm/clojure/lang/PersistentVector.java
index fcd9e46c..4b9f3260 100644
--- a/src/jvm/clojure/lang/PersistentVector.java
+++ b/src/jvm/clojure/lang/PersistentVector.java
@@ -19,7 +19,9 @@ import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicReference;
-public class PersistentVector extends APersistentVector implements IObj, IEditableCollection, IReduce, IKVReduce{
+public class PersistentVector extends APersistentVector implements IObj, IEditableCollection, IReduce, IKVReduce, IDrop{
+
+private static final long serialVersionUID = -7896022351281214157L;
public static class Node implements Serializable {
transient public final AtomicReference<Thread> edit;
@@ -363,7 +365,18 @@ public Object kvreduce(IFn f, Object init){
return init;
}
-static public final class ChunkedSeq extends ASeq implements IChunkedSeq,Counted{
+public Sequential drop(int n) {
+ if(n < 0) {
+ return this;
+ } else if(n < cnt) {
+ int offset = n%32;
+ return new ChunkedSeq(this, this.arrayFor(n), n-offset, offset);
+ } else {
+ return null;
+ }
+}
+
+static public final class ChunkedSeq extends ASeq implements IChunkedSeq,Counted,IReduce,IDrop{
public final PersistentVector vec;
final Object[] node;
@@ -428,6 +441,73 @@ static public final class ChunkedSeq extends ASeq implements IChunkedSeq,Counted
public int count(){
return vec.cnt - (i + offset);
}
+
+ public Iterator iterator() {
+ return vec.rangedIterator(i +offset, vec.cnt);
+ }
+
+ public Object reduce(IFn f) {
+ Object acc;
+ if (i +offset < vec.cnt)
+ acc = node[offset];
+ else
+ return f.invoke();
+
+ for(int j=offset+1;j<node.length;++j){
+ acc = f.invoke(acc,node[j]);
+ if(RT.isReduced(acc))
+ return ((IDeref)acc).deref();
+ }
+
+ int step = 0;
+ for(int ii = i +node.length; ii<vec.cnt; ii+=step){
+ Object[] array = vec.arrayFor(ii);
+ for(int j = 0;j<array.length;++j){
+ acc = f.invoke(acc,array[j]);
+ if(RT.isReduced(acc))
+ return ((IDeref)acc).deref();
+ }
+ step = array.length;
+ }
+ return acc;
+ }
+
+ public Object reduce(IFn f, Object init) {
+ Object acc = init;
+ for(int j=offset;j<node.length;++j){
+ acc = f.invoke(acc,node[j]);
+ if(RT.isReduced(acc))
+ return ((IDeref)acc).deref();
+ }
+
+ int step = 0;
+ for(int ii = i +node.length; ii<vec.cnt; ii+=step){
+ Object[] array = vec.arrayFor(ii);
+ for(int j = 0;j<array.length;++j){
+ acc = f.invoke(acc,array[j]);
+ if(RT.isReduced(acc))
+ return ((IDeref)acc).deref();
+ }
+ step = array.length;
+ }
+ return acc;
+ }
+
+ public Sequential drop(int n) {
+ int o = offset + n;
+ if(o < node.length) { // in current array
+ return new ChunkedSeq(vec, node, i, o);
+ } else {
+ int i = this.i +o;
+ if(i < vec.cnt) { // in vec
+ Object[] array = vec.arrayFor(i);
+ int newOffset = i%32;
+ return new ChunkedSeq(vec, vec.arrayFor(i), i-newOffset, newOffset);
+ } else {
+ return null;
+ }
+ }
+ }
}
public IPersistentCollection empty(){
diff --git a/src/jvm/clojure/lang/Range.java b/src/jvm/clojure/lang/Range.java
index 4f638e9f..1e4fbf6e 100644
--- a/src/jvm/clojure/lang/Range.java
+++ b/src/jvm/clojure/lang/Range.java
@@ -18,6 +18,8 @@ import java.util.*;
*/
public class Range extends ASeq implements IChunkedSeq, IReduce {
+private static final long serialVersionUID = -71973733672395145L;
+
private static final int CHUNK_SIZE = 32;
// Invariants guarantee this is never an "empty" seq
@@ -99,7 +101,7 @@ public static ISeq create(final Object start, Object end, Object step) {
public Obj withMeta(IPersistentMap meta){
if(meta == _meta)
return this;
- return new Range(meta, end, start, step, boundsCheck, _chunk, _chunkNext);
+ return new Range(meta, start, end, step, boundsCheck, _chunk, _chunkNext);
}
public Object first(){
diff --git a/src/jvm/clojure/lang/Ratio.java b/src/jvm/clojure/lang/Ratio.java
index 6c7a9bb6..02af3fde 100644
--- a/src/jvm/clojure/lang/Ratio.java
+++ b/src/jvm/clojure/lang/Ratio.java
@@ -17,6 +17,9 @@ import java.math.BigDecimal;
import java.math.MathContext;
public class Ratio extends Number implements Comparable{
+
+private static final long serialVersionUID = -576272795628662988L;
+
final public BigInteger numerator;
final public BigInteger denominator;
diff --git a/src/jvm/clojure/lang/Repeat.java b/src/jvm/clojure/lang/Repeat.java
index 2ce4f2da..1190b1e5 100644
--- a/src/jvm/clojure/lang/Repeat.java
+++ b/src/jvm/clojure/lang/Repeat.java
@@ -12,7 +12,9 @@ package clojure.lang;
/* Alex Miller, Dec 5, 2014 */
-public class Repeat extends ASeq implements IReduce {
+public class Repeat extends ASeq implements IReduce, IDrop {
+
+private static final long serialVersionUID = -5140377547192202551L;
private static final long INFINITE = -1;
@@ -97,4 +99,17 @@ public Object reduce(IFn f, Object start){
}
}
+public Sequential drop(int n) {
+ if(count == INFINITE) {
+ return this;
+ } else {
+ long droppedCount = count-n;
+ if(droppedCount > 0) {
+ return new Repeat(droppedCount, val);
+ } else {
+ return null;
+ }
+ }
+}
+
}
diff --git a/src/jvm/clojure/lang/RestFn.java b/src/jvm/clojure/lang/RestFn.java
index 98646835..f6d84430 100644
--- a/src/jvm/clojure/lang/RestFn.java
+++ b/src/jvm/clojure/lang/RestFn.java
@@ -10,6 +10,9 @@
package clojure.lang;
public abstract class RestFn extends AFunction{
+
+private static final long serialVersionUID = -4319097849151802009L;
+
abstract public int getRequiredArity();
protected Object doInvoke(Object args) {
diff --git a/src/jvm/clojure/lang/StringSeq.java b/src/jvm/clojure/lang/StringSeq.java
index bcb269d5..31633808 100644
--- a/src/jvm/clojure/lang/StringSeq.java
+++ b/src/jvm/clojure/lang/StringSeq.java
@@ -12,7 +12,13 @@
package clojure.lang;
-public class StringSeq extends ASeq implements IndexedSeq{
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+public class StringSeq extends ASeq implements IndexedSeq,IDrop,IReduceInit{
+
+private static final long serialVersionUID = 7975525539139301753L;
+
public final CharSequence s;
public final int i;
@@ -51,4 +57,24 @@ public int index(){
public int count(){
return s.length() - i;
}
+
+public Sequential drop(int n) {
+ int ii = i + n;
+ if (ii < s.length()) {
+ return new StringSeq(_meta, s, ii);
+ } else {
+ return null;
+ }
+}
+
+public Object reduce(IFn f, Object start) {
+ Object acc = start;
+ for(int ii=i; ii < s.length(); ii++) {
+ acc = f.invoke(acc, s.charAt(ii));
+ if(RT.isReduced(acc))
+ return ((IDeref)acc).deref();
+ }
+ return acc;
+}
+
}
diff --git a/src/jvm/clojure/lang/Symbol.java b/src/jvm/clojure/lang/Symbol.java
index 630ef1bb..5957bbeb 100644
--- a/src/jvm/clojure/lang/Symbol.java
+++ b/src/jvm/clojure/lang/Symbol.java
@@ -17,6 +17,9 @@ import java.io.ObjectStreamException;
public class Symbol extends AFn implements IObj, Comparable, Named, Serializable, IHashEq{
+
+private static final long serialVersionUID = 1191039485148212259L;
+
final String ns;
final String name;
private int _hasheq;
diff --git a/src/jvm/clojure/lang/Var.java b/src/jvm/clojure/lang/Var.java
index 78766192..96f0cee6 100644
--- a/src/jvm/clojure/lang/Var.java
+++ b/src/jvm/clojure/lang/Var.java
@@ -19,6 +19,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
public final class Var extends ARef implements IFn, IRef, Settable, Serializable{
+private static final long serialVersionUID = 8368961370796295279L;
+
static class TBox{
volatile Object val;
diff --git a/test/clojure/test_clojure/rt.clj b/test/clojure/test_clojure/rt.clj
index 39526975..298fcb00 100644
--- a/test/clojure/test_clojure/rt.clj
+++ b/test/clojure/test_clojure/rt.clj
@@ -9,7 +9,8 @@
; Author: Stuart Halloway
(ns clojure.test-clojure.rt
- (:require clojure.set)
+ (:require [clojure.string :as string]
+ clojure.set)
(:use clojure.test clojure.test-helper))
(defn bare-rt-print
@@ -75,31 +76,29 @@
(.bindRoot #'example-var 0)
(is (not (contains? (meta #'example-var) :macro))))
-(deftest last-var-wins-for-core
+(deftest ns-intern-policies
(testing "you can replace a core name, with warning"
(let [ns (temp-ns)
- replacement (gensym)]
- (with-err-string-writer (intern ns 'prefers replacement))
+ replacement (gensym)
+ e1 (with-err-string-writer (intern ns 'prefers replacement))]
+ (is (string/starts-with? e1 "WARNING"))
(is (= replacement @('prefers (ns-publics ns))))))
- (testing "you can replace a name you defined before"
+ (testing "you can replace a defined alias"
(let [ns (temp-ns)
s (gensym)
v1 (intern ns 'foo s)
- v2 (intern ns 'bar s)]
- (with-err-string-writer (.refer ns 'flatten v1))
- (.refer ns 'flatten v2)
+ v2 (intern ns 'bar s)
+ e1 (with-err-string-writer (.refer ns 'flatten v1))
+ e2 (with-err-string-writer (.refer ns 'flatten v2))]
+ (is (string/starts-with? e1 "WARNING"))
+ (is (string/starts-with? e2 "WARNING"))
(is (= v2 (ns-resolve ns 'flatten)))))
- (testing "you cannot intern over an existing non-core name"
- (let [ns (temp-ns 'clojure.set)
- replacement (gensym)]
- (is (thrown? IllegalStateException
- (intern ns 'subset? replacement)))
- (is (nil? ('subset? (ns-publics ns))))
- (is (= #'clojure.set/subset? ('subset? (ns-refers ns))))))
- (testing "you cannot refer over an existing non-core name"
- (let [ns (temp-ns 'clojure.set)
- replacement (gensym)]
- (is (thrown? IllegalStateException
- (.refer ns 'subset? #'clojure.set/intersection)))
- (is (nil? ('subset? (ns-publics ns))))
- (is (= #'clojure.set/subset? ('subset? (ns-refers ns)))))))
+ (testing "you cannot replace an interned var"
+ (let [ns1 (temp-ns)
+ ns2 (temp-ns)
+ v1 (intern ns1 'foo 1)
+ v2 (intern ns2 'foo 2)
+ e1 (with-err-string-writer (.refer ns1 'foo v2))]
+ (is (string/starts-with? e1 "REJECTED"))
+ (is (= v1 (ns-resolve ns1 'foo))))))
+
diff --git a/test/clojure/test_clojure/sequences.clj b/test/clojure/test_clojure/sequences.clj
index 4eb99e78..bc79c1f6 100644
--- a/test/clojure/test_clojure/sequences.clj
+++ b/test/clojure/test_clojure/sequences.clj
@@ -781,6 +781,8 @@
(partition 5 [1 2 3]) ()
+ (partition 4 4 [0 0 0] (range 10)) '((0 1 2 3) (4 5 6 7) (8 9 0 0))
+
; (partition 0 [1 2 3]) (repeat nil) ; infinite sequence of nil
(partition -1 [1 2 3]) ()
(partition -2 [1 2 3]) () )
@@ -796,6 +798,25 @@
(is (= (assoc (array-map (repeat 1 :x) :y) '(:x) :z) {'(:x) :z}))
(is (= (assoc (hash-map (repeat 1 :x) :y) '(:x) :z) {'(:x) :z})))
+(deftest test-partitionv
+ (are [x y] (= x y)
+ (partitionv 2 [1 2 3]) '((1 2))
+ (partitionv 2 [1 2 3 4]) '((1 2) (3 4))
+ (partitionv 2 []) ()
+
+ (partitionv 2 3 [1 2 3 4 5 6 7]) '((1 2) (4 5))
+ (partitionv 2 3 [1 2 3 4 5 6 7 8]) '((1 2) (4 5) (7 8))
+ (partitionv 2 3 []) ()
+
+ (partitionv 1 []) ()
+ (partitionv 1 [1 2 3]) '((1) (2) (3))
+
+ (partitionv 4 4 [0 0 0] (range 10)) '([0 1 2 3] [4 5 6 7] [8 9 0 0])
+
+ (partitionv 5 [1 2 3]) ()
+
+ (partitionv -1 [1 2 3]) ()
+ (partitionv -2 [1 2 3]) () ))
(deftest test-iterate
(are [x y] (= x y)
@@ -986,7 +1007,12 @@
() '(1 2)
[] [1 2]
{} {:a 1 :b 2}
- #{} #{1 2} ))
+ #{} #{1 2})
+
+ ; CLJ-2718
+ (is (= '(:a) (drop 1 (repeat 2 :a))))
+ (is (= () (drop 2 (repeat 2 :a))))
+ (is (= () (drop 3 (repeat 2 :a)))))
(defspec longrange-equals-range 1000
(prop/for-all [start gen/int
@@ -1058,6 +1084,15 @@
(reduce + (iterator-seq (.iterator (range 100)))) 4950
(reduce + (iterator-seq (.iterator (range 0.0 100.0 1.0)))) 4950.0 ))
+(deftest range-meta
+ (are [r] (= r (with-meta r {:a 1}))
+ (range 10)
+ (range 5 10)
+ (range 5 10 1)
+ (range 10.0)
+ (range 5.0 10.0)
+ (range 5.0 10.0 1.0)))
+
(deftest range-test
(let [threads 10
n 1000
@@ -1119,7 +1154,10 @@
{}
#{}
""
- (into-array []) )
+ (into-array [])
+ (transient [])
+ (transient #{})
+ (transient {}))
(are [x] (not (empty? x))
'(1 2)
@@ -1128,7 +1166,10 @@
{:a 1 :b 2}
#{1 2}
"abc"
- (into-array [1 2]) ))
+ (into-array [1 2])
+ (transient [1])
+ (transient #{1})
+ (transient {1 2})))
(deftest test-every?
@@ -1331,6 +1372,12 @@
(is (= (partition-all 4 2 [1 2 3 4 5 6 7 8 9])
[[1 2 3 4] [3 4 5 6] [5 6 7 8] [7 8 9] [9]])))
+(deftest test-partitionv-all
+ (is (= (partitionv-all 4 [1 2 3 4 5 6 7 8 9])
+ [[1 2 3 4] [5 6 7 8] [9]]))
+ (is (= (partitionv-all 4 2 [1 2 3 4 5 6 7 8 9])
+ [[1 2 3 4] [3 4 5 6] [5 6 7 8] [7 8 9] [9]])))
+
(deftest test-shuffle-invariants
(is (= (count (shuffle [1 2 3 4])) 4))
(let [shuffled-seq (shuffle [1 2 3 4])]
@@ -1458,6 +1505,42 @@
:kf #(some-> % :k #{0 1 2})
:vf :item))))))
+(deftest test-reduce-on-coll-seqs
+ ;; reduce on seq of coll, both with and without an init
+ (are [coll expected expected-init]
+ (and
+ (= expected-init (reduce conj [:init] (seq coll)))
+ (= expected (reduce conj (seq coll))))
+ ;; (seq [ ... ])
+ [] [] [:init]
+ [1] 1 [:init 1]
+ [[1] 2] [1 2] [:init [1] 2]
+
+ ;; (seq { ... })
+ {} [] [:init]
+ {1 1} [1 1] [:init [1 1]]
+ {1 1 2 2} [1 1 [2 2]] [:init [1 1] [2 2]]
+
+ ;; (seq (hash-map ... ))
+ (hash-map) [] [:init]
+ (hash-map 1 1) [1 1] [:init [1 1]]
+ (hash-map 1 1 2 2) [1 1 [2 2]] [:init [1 1] [2 2]]
+
+ ;; (seq (sorted-map ... ))
+ (sorted-map) [] [:init]
+ (sorted-map 1 1) [1 1] [:init [1 1]]
+ (sorted-map 1 1 2 2) [1 1 [2 2]] [:init [1 1] [2 2]])
+
+ (are [coll expected expected-init]
+ (and
+ (= expected-init (reduce + 100 (seq coll)))
+ (= expected (reduce + (seq coll))))
+
+ ;; (seq (range ...))
+ (range 0) 0 100
+ (range 1 2) 1 101
+ (range 1 3) 3 103))
+
(defspec iteration-seq-equals-reduce 1000
(prop/for-all [initk gen/int
seed gen/int]
Debdiff
[The following lists of changes regard files as different if they have different names, permissions or owners.]
Files in second set of .debs but not in first
-rw-r--r-- root/root /usr/share/java/clojure-1.12.0-master-SNAPSHOT.jar -rw-r--r-- root/root /usr/share/maven-repo/org/clojure/clojure/1.12.0-master-SNAPSHOT/clojure-1.12.0-master-SNAPSHOT.pom lrwxrwxrwx root/root /usr/share/java/clojure-1.11.jar -> clojure-1.12.0-master-SNAPSHOT.jar lrwxrwxrwx root/root /usr/share/maven-repo/org/clojure/clojure/1.10.x/clojure-1.10.x.jar -> ../../../../../java/clojure-1.11.1+git20221207.1.527b330+ds.jar lrwxrwxrwx root/root /usr/share/maven-repo/org/clojure/clojure/1.12.0-master-SNAPSHOT/clojure-1.12.0-master-SNAPSHOT.jar -> ../../../../../java/clojure-1.12.0-master-SNAPSHOT.jar lrwxrwxrwx root/root /usr/share/maven-repo/org/clojure/clojure/1.x/clojure-1.x.jar -> ../../../../../java/clojure-1.12.0-master-SNAPSHOT.jar
Files in first set of .debs but not in second
-rw-r--r-- root/root /usr/share/java/clojure-1.11.1.jar -rw-r--r-- root/root /usr/share/maven-repo/org/clojure/clojure/1.11.1/clojure-1.11.1.pom lrwxrwxrwx root/root /usr/share/java/clojure-1.11.jar -> clojure-1.11.1.jar lrwxrwxrwx root/root /usr/share/maven-repo/org/clojure/clojure/1.10.x/clojure-1.10.x.jar -> ../../../../../java/clojure-1.11.1.jar lrwxrwxrwx root/root /usr/share/maven-repo/org/clojure/clojure/1.11.1/clojure-1.11.1.jar -> ../../../../../java/clojure-1.11.1.jar lrwxrwxrwx root/root /usr/share/maven-repo/org/clojure/clojure/1.x/clojure-1.x.jar -> ../../../../../java/clojure-1.11.1.jar
No differences were encountered between the control files of package clojure
No differences were encountered between the control files of package libclojure-java