summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/clj/clojure/core.clj56
-rw-r--r--src/jvm/clojure/lang/APersistentMap.java4
-rw-r--r--src/jvm/clojure/lang/APersistentVector.java4
-rw-r--r--src/jvm/clojure/lang/ASeq.java4
-rw-r--r--src/jvm/clojure/lang/ArraySeq.java10
-rw-r--r--src/jvm/clojure/lang/CachedSeq.java65
-rw-r--r--src/jvm/clojure/lang/Cons.java18
-rw-r--r--src/jvm/clojure/lang/Delay.java17
-rw-r--r--src/jvm/clojure/lang/EnumerationSeq.java2
-rw-r--r--src/jvm/clojure/lang/FnSeq.java62
-rw-r--r--src/jvm/clojure/lang/ISeq.java2
-rw-r--r--src/jvm/clojure/lang/IteratorSeq.java2
-rw-r--r--src/jvm/clojure/lang/LazyCons.java2
-rw-r--r--src/jvm/clojure/lang/LazySeq.java54
-rw-r--r--src/jvm/clojure/lang/PersistentArrayMap.java2
-rw-r--r--src/jvm/clojure/lang/PersistentHashMap.java4
-rw-r--r--src/jvm/clojure/lang/PersistentList.java2
-rw-r--r--src/jvm/clojure/lang/PersistentQueue.java2
-rw-r--r--src/jvm/clojure/lang/PersistentStructMap.java2
-rw-r--r--src/jvm/clojure/lang/PersistentTreeMap.java2
-rw-r--r--src/jvm/clojure/lang/Range.java2
-rw-r--r--src/jvm/clojure/lang/StreamSeq.java2
-rw-r--r--src/jvm/clojure/lang/StringSeq.java2
23 files changed, 71 insertions, 251 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index ca3acfac..2cf79beb 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -391,30 +391,6 @@
[item & more]
(spread (cons item more)))
-(defmacro delay
- "Takes a body of expressions and yields a Delay object that will
- invoke the body only the first time it is forced (with force), and
- will cache the result and return it on all subsequent force calls"
- [& body]
- (list 'new 'clojure.lang.Delay (list* `fn [] body)))
-
-(defn delay?
- "returns true if x is a Delay created with delay"
- [x] (instance? clojure.lang.Delay x))
-
-(defn force
- "If x is a Delay, returns the (possibly cached) value of its expression, else returns x"
- [x] (. clojure.lang.Delay (force x)))
-
-(defn fnseq
- "Returns a seq object whose first is first and whose rest is the
- value produced by calling restfn with no arguments. restfn will be
- called at most once per step in the sequence, e.g. calling rest
- repeatedly on the head of the seq calls restfn once - the value it
- yields is cached."
- [first restfn]
- (new clojure.lang.FnSeq first restfn))
-
(defmacro lazy-cons
"Expands to code which produces a seq object whose first is
first-expr and whose rest is rest-expr, neither of which is
@@ -425,21 +401,6 @@
[first-expr & rest-expr]
(list 'new 'clojure.lang.LazyCons (list `fn (list [] first-expr) (list* [(gensym)] rest-expr))))
-;(defmacro lazy-seq
-; "Expands to code which produces a seq object whose first is the
-; value of first-expr and whose rest is the value of rest-expr,
-; neither of which is evaluated until first/rest is called. Each expr
-; will be evaluated every step in the sequence, e.g. calling
-; first/rest repeatedly on the same node of the seq evaluates
-; first/rest-expr repeatedly - the values they yield are not cached."
-; [first-expr rest-expr]
-; (list 'new 'clojure.lang.LazySeq (list `fn (list [] first-expr) (list [(gensym)] rest-expr))))
-
-(defn cache-seq
- "Given a seq s, returns a lazy seq that will touch each element of s
- at most once, caching the results."
- [s] (when s (clojure.lang.CachedSeq. s)))
-
(defn concat
"Returns a lazy seq representing the concatenation of the elements in the supplied colls."
([] nil)
@@ -457,6 +418,23 @@
(cat (concat x y) zs))))
;;;;;;;;;;;;;;;;at this point all the support for syntax-quote exists;;;;;;;;;;;;;;;;;;;;;;
+(defmacro delay
+ "Takes a body of expressions and yields a Delay object that will
+ invoke the body only the first time it is forced (with force), and
+ will cache the result and return it on all subsequent force
+ calls. Any closed over locals will be cleared prior to the tail call
+ of body, (i.e. they will not be retained)."
+ [& body]
+ (list 'new 'clojure.lang.Delay (list* `#^{:once true} fn* [] body)))
+
+(defn delay?
+ "returns true if x is a Delay created with delay"
+ [x] (instance? clojure.lang.Delay x))
+
+(defn force
+ "If x is a Delay, returns the (possibly cached) value of its expression, else returns x"
+ [x] (. clojure.lang.Delay (force x)))
+
(defmacro if-not
"Evaluates test. If logical false, evaluates and returns then expr, otherwise else expr, if supplied, else nil."
([test then] `(if-not ~test ~then nil))
diff --git a/src/jvm/clojure/lang/APersistentMap.java b/src/jvm/clojure/lang/APersistentMap.java
index 4d8bc8f7..fd700e0e 100644
--- a/src/jvm/clojure/lang/APersistentMap.java
+++ b/src/jvm/clojure/lang/APersistentMap.java
@@ -130,7 +130,7 @@ static public class KeySeq extends ASeq{
return ((Map.Entry) seq.first()).getKey();
}
- public ISeq rest(){
+ public Seqable more(){
return create(seq.rest());
}
@@ -161,7 +161,7 @@ static public class ValSeq extends ASeq{
return ((Map.Entry) seq.first()).getValue();
}
- public ISeq rest(){
+ public Seqable more(){
return create(seq.rest());
}
diff --git a/src/jvm/clojure/lang/APersistentVector.java b/src/jvm/clojure/lang/APersistentVector.java
index 4cb753a8..8e6a85b8 100644
--- a/src/jvm/clojure/lang/APersistentVector.java
+++ b/src/jvm/clojure/lang/APersistentVector.java
@@ -438,7 +438,7 @@ public IStream stream() throws Exception {
return v.nth(i);
}
- public ISeq rest(){
+ public Seqable more(){
if(i + 1 < v.count())
return new APersistentVector.Seq(v, i + 1);
return null;
@@ -490,7 +490,7 @@ static class RSeq extends ASeq implements IndexedSeq{
return v.nth(i);
}
- public ISeq rest(){
+ public Seqable more(){
if(i > 0)
return new APersistentVector.RSeq(v, i - 1);
return null;
diff --git a/src/jvm/clojure/lang/ASeq.java b/src/jvm/clojure/lang/ASeq.java
index 8bd830d1..c4f4f7ca 100644
--- a/src/jvm/clojure/lang/ASeq.java
+++ b/src/jvm/clojure/lang/ASeq.java
@@ -110,6 +110,10 @@ public ISeq cons(Object o){
return new Cons(o, this);
}
+public ISeq rest(){
+ return RT.seq(more());
+}
+
// java.util.Collection implementation
public Object[] toArray(){
diff --git a/src/jvm/clojure/lang/ArraySeq.java b/src/jvm/clojure/lang/ArraySeq.java
index bbe3b199..f0d825a4 100644
--- a/src/jvm/clojure/lang/ArraySeq.java
+++ b/src/jvm/clojure/lang/ArraySeq.java
@@ -65,7 +65,7 @@ public Object first(){
return Reflector.prepRet(Array.get(array, i));
}
-public ISeq rest(){
+public Seqable more(){
if(oa != null)
{
if(i + 1 < oa.length)
@@ -138,7 +138,7 @@ static public class ArraySeq_int extends ASeq implements IndexedSeq, IReduce{
return array[i];
}
- public ISeq rest(){
+ public Seqable more(){
if(i + 1 < array.length)
return new ArraySeq_int(meta(), array, i + 1);
return null;
@@ -186,7 +186,7 @@ static public class ArraySeq_float extends ASeq implements IndexedSeq, IReduce{
return array[i];
}
- public ISeq rest(){
+ public Seqable more(){
if(i + 1 < array.length)
return new ArraySeq_float(meta(), array, i + 1);
return null;
@@ -233,7 +233,7 @@ static public class ArraySeq_double extends ASeq implements IndexedSeq, IReduce{
return array[i];
}
- public ISeq rest(){
+ public Seqable more(){
if(i + 1 < array.length)
return new ArraySeq_double(meta(), array, i + 1);
return null;
@@ -280,7 +280,7 @@ static public class ArraySeq_long extends ASeq implements IndexedSeq, IReduce{
return array[i];
}
- public ISeq rest(){
+ public Seqable more(){
if(i + 1 < array.length)
return new ArraySeq_long(meta(), array, i + 1);
return null;
diff --git a/src/jvm/clojure/lang/CachedSeq.java b/src/jvm/clojure/lang/CachedSeq.java
deleted file mode 100644
index 7d21952d..00000000
--- a/src/jvm/clojure/lang/CachedSeq.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * 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.
- **/
-
-/* rich Aug 10, 2008 */
-
-package clojure.lang;
-
-public class CachedSeq extends ASeq{
-ISeq s;
-Object _first;
-ISeq _rest;
-
-public CachedSeq(ISeq s){
- this.s = s;
- this._first = this;
- this._rest = this;
-}
-
-CachedSeq(IPersistentMap meta, Object first, ISeq rest){
- super(meta);
- this._first = first;
- this._rest = rest;
-}
-
-final
-synchronized
-public Object first(){
- if(_first == this)
- _first = s.first();
- return _first;
-}
-
-final
-synchronized
-public ISeq rest(){
- if(_rest == this)
- {
- //force sequential evaluation
- if(_first == this)
- first();
- ISeq rs = s.rest();
- if(rs == null)
- _rest = rs;
- else
- _rest = new CachedSeq(rs);
- s = null;
- }
- return _rest;
-}
-
-public CachedSeq withMeta(IPersistentMap meta){
- if(meta == meta())
- return this;
- //force before copying
- rest();
- return new CachedSeq(meta, _first, _rest);
-}
-}
diff --git a/src/jvm/clojure/lang/Cons.java b/src/jvm/clojure/lang/Cons.java
index c9e65eb3..a120aa19 100644
--- a/src/jvm/clojure/lang/Cons.java
+++ b/src/jvm/clojure/lang/Cons.java
@@ -15,30 +15,30 @@ package clojure.lang;
public class Cons extends ASeq{
private final Object _first;
-private final ISeq _rest;
+private final Seqable _more;
-public Cons(Object first, ISeq rest){
+public Cons(Object first, Seqable _more){
this._first = first;
- this._rest = rest;
+ this._more = _more;
}
-public Cons(IPersistentMap meta, Object _first, ISeq _rest){
+public Cons(IPersistentMap meta, Object _first, Seqable _more){
super(meta);
this._first = _first;
- this._rest = _rest;
+ this._more = _more;
}
public Object first(){
return _first;
}
-public ISeq rest(){
- return _rest;
+public Seqable more(){
+ return _more;
}
public int count(){
- return 1 + RT.count(_rest);
+ return 1 + RT.count(_more);
}
public ISeq seq(){
@@ -46,6 +46,6 @@ public ISeq seq(){
}
public Cons withMeta(IPersistentMap meta){
- return new Cons(meta, _first, _rest);
+ return new Cons(meta, _first, _more);
}
}
diff --git a/src/jvm/clojure/lang/Delay.java b/src/jvm/clojure/lang/Delay.java
index a0dfd0b6..eed98fd0 100644
--- a/src/jvm/clojure/lang/Delay.java
+++ b/src/jvm/clojure/lang/Delay.java
@@ -35,4 +35,21 @@ synchronized Object get() throws Exception{
}
return val;
}
+
+ static public class Seq extends Delay implements Seqable{
+ public Seq(IFn fn) {
+ super(fn);
+ }
+
+ public ISeq seq() {
+ try
+ {
+ return (ISeq) get();
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+ }
}
diff --git a/src/jvm/clojure/lang/EnumerationSeq.java b/src/jvm/clojure/lang/EnumerationSeq.java
index 7c579651..2cd7688c 100644
--- a/src/jvm/clojure/lang/EnumerationSeq.java
+++ b/src/jvm/clojure/lang/EnumerationSeq.java
@@ -52,7 +52,7 @@ public Object first(){
return state.val;
}
-public ISeq rest(){
+public Seqable more(){
if(state._rest == state)
synchronized(state)
{
diff --git a/src/jvm/clojure/lang/FnSeq.java b/src/jvm/clojure/lang/FnSeq.java
deleted file mode 100644
index f8d2098f..00000000
--- a/src/jvm/clojure/lang/FnSeq.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * 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;
-
-public class FnSeq extends ASeq{
-
-final Object _first;
-IFn _restFn;
-//volatile
-ISeq _rest;
-
-public FnSeq(Object first, IFn restFn){
- this._first = first;
- this._restFn = restFn;
- this._rest = this;
-}
-
-public FnSeq(IPersistentMap meta, Object first, IFn restFn, ISeq rest){
- super(meta);
- this._first = first;
- this._rest = rest;
- this._restFn = restFn;
-}
-
-public Object first(){
- return _first;
-}
-
-synchronized public ISeq rest(){
- if(_restFn != null)
- {
- try
- {
- _rest = (ISeq) _restFn.invoke();
- }
- catch(Exception ex)
- {
- throw new Error(ex);
- }
- _restFn = null;
- }
- return _rest;
-}
-
-
-synchronized public FnSeq withMeta(IPersistentMap meta){
- if(meta == meta())
- return this;
- //force eval of restFn before copying
- rest();
- return new FnSeq(meta, _first, _restFn, _rest);
-}
-
-}
diff --git a/src/jvm/clojure/lang/ISeq.java b/src/jvm/clojure/lang/ISeq.java
index 2e7adb3b..4a24b2b1 100644
--- a/src/jvm/clojure/lang/ISeq.java
+++ b/src/jvm/clojure/lang/ISeq.java
@@ -22,6 +22,8 @@ Object first();
ISeq rest();
+Seqable more();
+
ISeq cons(Object o);
}
diff --git a/src/jvm/clojure/lang/IteratorSeq.java b/src/jvm/clojure/lang/IteratorSeq.java
index 4a5ab80c..6015428c 100644
--- a/src/jvm/clojure/lang/IteratorSeq.java
+++ b/src/jvm/clojure/lang/IteratorSeq.java
@@ -50,7 +50,7 @@ public Object first(){
return state.val;
}
-public ISeq rest(){
+public Seqable more(){
if(state._rest == state)
synchronized(state)
{
diff --git a/src/jvm/clojure/lang/LazyCons.java b/src/jvm/clojure/lang/LazyCons.java
index ee60a891..20daba01 100644
--- a/src/jvm/clojure/lang/LazyCons.java
+++ b/src/jvm/clojure/lang/LazyCons.java
@@ -49,7 +49,7 @@ public Object first(){
final
synchronized
-public ISeq rest(){
+public Seqable more(){
if(_rest == sentinel)
{
try
diff --git a/src/jvm/clojure/lang/LazySeq.java b/src/jvm/clojure/lang/LazySeq.java
deleted file mode 100644
index ea66333f..00000000
--- a/src/jvm/clojure/lang/LazySeq.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * 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.
- **/
-
-/* rich Apr 20, 2008 */
-
-package clojure.lang;
-
-final public class LazySeq extends ASeq{
-final IFn f;
-
-public LazySeq(IFn f){
- this.f = f;
-}
-
-final public Object first(){
- try
- {
- return f.invoke();
- }
- catch(Exception e)
- {
- throw new RuntimeException(e);
- }
-}
-
-final public ISeq rest(){
- try
- {
- return RT.seq(f.invoke(null));
- }
- catch(Exception e)
- {
- throw new RuntimeException(e);
- }
-}
-
-LazySeq(IPersistentMap meta, IFn f){
- super(meta);
- this.f = f;
-}
-
-public Obj withMeta(IPersistentMap meta){
- if(meta == meta())
- return this;
- return new LazySeq(meta, f);
-}
-}
diff --git a/src/jvm/clojure/lang/PersistentArrayMap.java b/src/jvm/clojure/lang/PersistentArrayMap.java
index d8fbd354..6fa05319 100644
--- a/src/jvm/clojure/lang/PersistentArrayMap.java
+++ b/src/jvm/clojure/lang/PersistentArrayMap.java
@@ -216,7 +216,7 @@ static class Seq extends ASeq{
return new MapEntry(array[i],array[i+1]);
}
- public ISeq rest(){
+ public Seqable more(){
if(i + 2 < array.length)
return new Seq(array, i + 2);
return null;
diff --git a/src/jvm/clojure/lang/PersistentHashMap.java b/src/jvm/clojure/lang/PersistentHashMap.java
index d696cd5a..f4c700e4 100644
--- a/src/jvm/clojure/lang/PersistentHashMap.java
+++ b/src/jvm/clojure/lang/PersistentHashMap.java
@@ -349,7 +349,7 @@ final static class FullNode implements INode{
return s.first();
}
- public ISeq rest(){
+ public Seqable more(){
ISeq nexts = s.rest();
if(nexts != null)
return new Seq(nexts, i, node);
@@ -507,7 +507,7 @@ final static class BitmapIndexedNode implements INode{
return s.first();
}
- public ISeq rest(){
+ public Seqable more(){
ISeq nexts = s.rest();
if(nexts != null)
return new Seq(nexts, i, node);
diff --git a/src/jvm/clojure/lang/PersistentList.java b/src/jvm/clojure/lang/PersistentList.java
index b3949007..7fa3e859 100644
--- a/src/jvm/clojure/lang/PersistentList.java
+++ b/src/jvm/clojure/lang/PersistentList.java
@@ -64,7 +64,7 @@ public Object first(){
return _first;
}
-public ISeq rest(){
+public Seqable more(){
if(_count == 1)
return null;
return (ISeq) _rest;
diff --git a/src/jvm/clojure/lang/PersistentQueue.java b/src/jvm/clojure/lang/PersistentQueue.java
index 552cdb42..f2205741 100644
--- a/src/jvm/clojure/lang/PersistentQueue.java
+++ b/src/jvm/clojure/lang/PersistentQueue.java
@@ -140,7 +140,7 @@ static class Seq extends ASeq{
return f.first();
}
- public ISeq rest(){
+ public Seqable more(){
ISeq f1 = f.rest();
ISeq r1 = rseq;
if(f1 == null)
diff --git a/src/jvm/clojure/lang/PersistentStructMap.java b/src/jvm/clojure/lang/PersistentStructMap.java
index 01e86346..affad2fe 100644
--- a/src/jvm/clojure/lang/PersistentStructMap.java
+++ b/src/jvm/clojure/lang/PersistentStructMap.java
@@ -216,7 +216,7 @@ static class Seq extends ASeq{
return new MapEntry(keys.first(), vals[i]);
}
- public ISeq rest(){
+ public Seqable more(){
if(i + 1 < vals.length)
return new Seq(_meta, keys.rest(), vals, i + 1, ext);
return ext.seq();
diff --git a/src/jvm/clojure/lang/PersistentTreeMap.java b/src/jvm/clojure/lang/PersistentTreeMap.java
index 1cd40969..035c01eb 100644
--- a/src/jvm/clojure/lang/PersistentTreeMap.java
+++ b/src/jvm/clojure/lang/PersistentTreeMap.java
@@ -781,7 +781,7 @@ static public class Seq extends ASeq{
return stack.first();
}
- public ISeq rest(){
+ public Seqable more(){
Node t = (Node) stack.first();
ISeq nextstack = push(asc ? t.right() : t.left(), stack.rest(), asc);
if(nextstack != null)
diff --git a/src/jvm/clojure/lang/Range.java b/src/jvm/clojure/lang/Range.java
index 226a77ba..59d3dda3 100644
--- a/src/jvm/clojure/lang/Range.java
+++ b/src/jvm/clojure/lang/Range.java
@@ -39,7 +39,7 @@ public Object first(){
return n;
}
-public ISeq rest(){
+public Seqable more(){
if(n < end-1)
return new Range(_meta, n + 1, end);
return null;
diff --git a/src/jvm/clojure/lang/StreamSeq.java b/src/jvm/clojure/lang/StreamSeq.java
index 44cfe28c..dfc8cf63 100644
--- a/src/jvm/clojure/lang/StreamSeq.java
+++ b/src/jvm/clojure/lang/StreamSeq.java
@@ -41,7 +41,7 @@ public class StreamSeq extends ASeq {
return _first;
}
- synchronized public ISeq rest() {
+ synchronized public Seqable more() {
if (stream != null) {
try {
_rest = create(stream);
diff --git a/src/jvm/clojure/lang/StringSeq.java b/src/jvm/clojure/lang/StringSeq.java
index cf370224..f5800f45 100644
--- a/src/jvm/clojure/lang/StringSeq.java
+++ b/src/jvm/clojure/lang/StringSeq.java
@@ -38,7 +38,7 @@ public Object first(){
return Character.valueOf(s.charAt(i));
}
-public ISeq rest(){
+public Seqable more(){
if(i + 1 < s.length())
return new StringSeq(_meta, s, i + 1);
return null;