summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/clj/clojure/core.clj38
-rw-r--r--src/clj/clojure/core_print.clj12
-rw-r--r--src/jvm/clojure/lang/Compiler.java2
-rw-r--r--src/jvm/clojure/lang/Delay.java2
-rw-r--r--src/jvm/clojure/lang/ISeq.java2
-rw-r--r--src/jvm/clojure/lang/LispReader.java24
-rw-r--r--src/jvm/clojure/lang/PersistentList.java2
-rw-r--r--src/jvm/clojure/lang/RT.java30
-rw-r--r--src/jvm/clojure/lang/Sequence.java16
9 files changed, 88 insertions, 40 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj
index d95e3972..3d13eba0 100644
--- a/src/clj/clojure/core.clj
+++ b/src/clj/clojure/core.clj
@@ -407,32 +407,36 @@
[first-expr & rest-expr]
(list 'new 'clojure.lang.LazyCons (list `fn (list [] first-expr) (list* [(gensym)] rest-expr))))
+
+(defmacro lazy-seq
+ "Takes a body of expressions that returns an ISeq or nil, and yields
+ a Seqable object that will invoke the body only the first time seq
+ is called, and will cache the result and return it on all subsequent
+ seq calls. Any closed over locals will be cleared prior to the tail
+ call of body."
+ [& body]
+ (list 'new 'clojure.lang.Delay$Seq (list* '#^{:once true} fn* [] body)))
+
(defn concat
- "Returns a lazy seq representing the concatenation of the elements in the supplied colls."
+ "Returns a lazy sequence representing the concatenation of the elements in the supplied colls."
([] nil)
([x] (seq x))
([x y]
- (if (seq x)
- (lazy-cons (first x) (concat (rest x) y))
- (seq y)))
+ (lazy-seq
+ (if (seq x)
+ (cons (first x) (concat (more x) y))
+ (seq y))))
([x y & zs]
(let [cat (fn cat [xys zs]
- (if (seq xys)
- (lazy-cons (first xys) (cat (rest xys) zs))
- (when zs
- (recur (first zs) (rest zs)))))]
+ (lazy-seq
+ (if (seq xys)
+ (cons (first xys) (cat (more xys) zs))
+ (when zs
+ (seq (cat (first zs) (rest zs)))))))]
(cat (concat x y) zs))))
;;;;;;;;;;;;;;;;at this point all the support for syntax-quote exists;;;;;;;;;;;;;;;;;;;;;;
-(defmacro lazy-seq
- "Takes a body of expressions that returns an ISeq or nil, and yields
- a Seqable object that will invoke the body only the first time seq
- is called, and will cache the result and return it on all subsequent
- seq calls. Any closed over locals will be cleared prior to the tail
- call of body."
- [& body]
- (list 'new 'clojure.lang.Delay$Seq (list* `#^{:once true} fn* [] body)))
(defmacro delay
"Takes a body of expressions and yields a Delay object that will
@@ -3726,7 +3730,7 @@
the coordination overhead."
([f coll]
(let [n (inc (.. Runtime getRuntime availableProcessors))
- agents (doall (map #(agent (f %)) (take n coll)))
+ agents (doall (map #(send (agent %) f) (take n coll)))
wget (fn [a] (await1 a) @a)
step (fn step [[x & xs :as s]
[a & as :as acycle]]
diff --git a/src/clj/clojure/core_print.clj b/src/clj/clojure/core_print.clj
index 7a79a903..59b045b3 100644
--- a/src/clj/clojure/core_print.clj
+++ b/src/clj/clojure/core_print.clj
@@ -128,14 +128,18 @@
(defmethod print-dup clojure.lang.Var [#^clojure.lang.Var o, #^Writer w]
(.write w (str "#=(var " (.name (.ns o)) "/" (.sym o) ")")))
-(defmethod print-method clojure.lang.ISeq [o, #^Writer w]
+(defmethod print-method clojure.lang.Sequence [o, #^Writer w]
(print-meta o w)
(print-sequential "(" pr-on " " ")" o w))
-(defmethod print-dup clojure.lang.ISeq [o w] (print-method o w))
+(defmethod print-dup clojure.lang.Sequence [o w] (print-method o w))
(defmethod print-dup clojure.lang.IPersistentList [o w] (print-method o w))
-(prefer-method print-method clojure.lang.IPersistentList clojure.lang.ISeq)
-(prefer-method print-dup clojure.lang.IPersistentList clojure.lang.ISeq)
+(prefer-method print-method clojure.lang.IPersistentList clojure.lang.Sequence)
+(prefer-method print-dup clojure.lang.IPersistentList clojure.lang.Sequence)
+(prefer-method print-method clojure.lang.Sequence clojure.lang.IPersistentCollection)
+(prefer-method print-dup clojure.lang.Sequence clojure.lang.IPersistentCollection)
+(prefer-method print-method clojure.lang.Sequence java.util.Collection)
+(prefer-method print-dup clojure.lang.Sequence java.util.Collection)
(defmethod print-method clojure.lang.IPersistentList [o, #^Writer w]
(print-meta o w)
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 50921f7f..efd52ab6 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -3960,6 +3960,8 @@ private static Expr analyze(C context, Object form, String name) throws Exceptio
//todo symbol macro expansion?
try
{
+ if(form instanceof Sequence)
+ form = RT.seq(form);
if(form == null)
return NIL_EXPR;
else if(form == Boolean.TRUE)
diff --git a/src/jvm/clojure/lang/Delay.java b/src/jvm/clojure/lang/Delay.java
index 83e58a37..c1bacc99 100644
--- a/src/jvm/clojure/lang/Delay.java
+++ b/src/jvm/clojure/lang/Delay.java
@@ -38,7 +38,7 @@ public class Delay {
return val;
}
- static public class Seq extends Delay implements IPersistentCollection, List {
+ static public class Seq extends Delay implements IPersistentCollection, List, Sequential, Sequence {
public Seq(IFn fn) {
super(fn);
}
diff --git a/src/jvm/clojure/lang/ISeq.java b/src/jvm/clojure/lang/ISeq.java
index 4a24b2b1..2db905ef 100644
--- a/src/jvm/clojure/lang/ISeq.java
+++ b/src/jvm/clojure/lang/ISeq.java
@@ -16,7 +16,7 @@ package clojure.lang;
* ISeqs are immutable values, i.e. neither first(), nor rest() changes
* or invalidates the ISeq
*/
-public interface ISeq extends IPersistentCollection, Sequential{
+public interface ISeq extends IPersistentCollection, Sequential, Sequence{
Object first();
diff --git a/src/jvm/clojure/lang/LispReader.java b/src/jvm/clojure/lang/LispReader.java
index 922d1cbf..49400339 100644
--- a/src/jvm/clojure/lang/LispReader.java
+++ b/src/jvm/clojure/lang/LispReader.java
@@ -28,6 +28,7 @@ static final Symbol THE_VAR = Symbol.create("var");
static Symbol UNQUOTE = Symbol.create("clojure.core", "unquote");
//static Symbol UNQUOTE_SPLICING = Symbol.create(null, "unquote-splicing");
static Symbol CONCAT = Symbol.create("clojure.core", "concat");
+static Symbol SEQ = Symbol.create("clojure.core", "seq");
static Symbol LIST = Symbol.create("clojure.core", "list");
static Symbol APPLY = Symbol.create("clojure.core", "apply");
static Symbol HASHMAP = Symbol.create("clojure.core", "hash-map");
@@ -61,7 +62,7 @@ static Var GENSYM_ENV = Var.create(null);
//sorted-map num->gensymbol
static Var ARG_ENV = Var.create(null);
-static
+ static
{
macros['"'] = new StringReader();
macros[';'] = new CommentReader();
@@ -702,20 +703,23 @@ public static class SyntaxQuoteReader extends AFn{
if(form instanceof IPersistentMap)
{
IPersistentVector keyvals = flattenMap(form);
- ret = RT.list(APPLY, HASHMAP, RT.cons(CONCAT, sqExpandList(keyvals.seq())));
+ ret = RT.list(APPLY, HASHMAP, RT.list(SEQ, RT.cons(CONCAT, sqExpandList(keyvals.seq()))));
}
else if(form instanceof IPersistentVector)
- {
- ret = RT.list(APPLY, VECTOR, RT.cons(CONCAT, sqExpandList(((IPersistentVector) form).seq())));
- }
+ {
+ ret = RT.list(APPLY, VECTOR, RT.list(SEQ, RT.cons(CONCAT, sqExpandList(((IPersistentVector) form).seq()))));
+ }
else if(form instanceof IPersistentSet)
- {
- ret = RT.list(APPLY, HASHSET, RT.cons(CONCAT, sqExpandList(((IPersistentSet) form).seq())));
- }
- else if(form instanceof ISeq)
+ {
+ ret = RT.list(APPLY, HASHSET, RT.list(SEQ, RT.cons(CONCAT, sqExpandList(((IPersistentSet) form).seq()))));
+ }
+ else if(form instanceof Sequence)
{
ISeq seq = RT.seq(form);
- ret = RT.cons(CONCAT, sqExpandList(seq));
+ if(seq == null)
+ ret = RT.cons(LIST,null);
+ else
+ ret = RT.list(SEQ, RT.cons(CONCAT, sqExpandList(seq)));
}
else
throw new UnsupportedOperationException("Unknown Collection type");
diff --git a/src/jvm/clojure/lang/PersistentList.java b/src/jvm/clojure/lang/PersistentList.java
index 7fa3e859..26f7fea3 100644
--- a/src/jvm/clojure/lang/PersistentList.java
+++ b/src/jvm/clojure/lang/PersistentList.java
@@ -114,7 +114,7 @@ public Object reduce(IFn f, Object start) throws Exception{
-static class EmptyList extends Obj implements IPersistentList, List{
+static class EmptyList extends Obj implements IPersistentList, List, Sequence{
public int hashCode(){
return 1;
diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java
index 9ec66cae..d64cfa7d 100644
--- a/src/jvm/clojure/lang/RT.java
+++ b/src/jvm/clojure/lang/RT.java
@@ -453,6 +453,15 @@ static public ISeq seq(Object coll){
return seqFrom(coll);
}
+static public Sequence sequence(Object coll){
+ if(coll == null)
+ return null;
+ else if(coll instanceof Sequence)
+ return (Sequence) coll;
+ else
+ return seq(coll);
+ }
+
static public IStream stream(final Object coll) throws Exception{
if(coll == null)
return EMPTY_STREAM;
@@ -568,12 +577,21 @@ static public ISeq rest(Object x){
}
static public Seqable more(Object x){
+ Seqable ret = null;
if(x instanceof ISeq)
- return ((ISeq) x).more();
- ISeq seq = seq(x);
- if(seq == null)
- return null;
- return seq.more();
+ ret = ((ISeq) x).more();
+ else
+ {
+ ISeq seq = seq(x);
+ if(seq == null)
+ ret = PersistentList.EMPTY;
+ else
+ ret = seq.more();
+ }
+ if(ret == null)
+ ret = PersistentList.EMPTY;
+// throw new IllegalStateException("nil more");
+ return ret;
}
static public ISeq rrest(Object x){
@@ -1226,7 +1244,7 @@ static public void print(Object x, Writer w) throws Exception{
}
if(x == null)
w.write("nil");
- else if(x instanceof ISeq || x instanceof IPersistentList)
+ else if(x instanceof Sequence || x instanceof IPersistentList)
{
w.write('(');
printInnerSeq(seq(x), w);
diff --git a/src/jvm/clojure/lang/Sequence.java b/src/jvm/clojure/lang/Sequence.java
new file mode 100644
index 00000000..688cec53
--- /dev/null
+++ b/src/jvm/clojure/lang/Sequence.java
@@ -0,0 +1,16 @@
+/**
+ * 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 Jan 29, 2009 */
+
+package clojure.lang;
+
+public interface Sequence {
+}