summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-06-28 13:45:55 +0000
committerRich Hickey <richhickey@gmail.com>2007-06-28 13:45:55 +0000
commit58d22d11d8313d630a43da8bf716bf0212227505 (patch)
tree1bae79cc0e55ac11acbfe348e4356ee468c9ed5b
parentbbe9d7ace49db4e368443818220e5268c3e3a367 (diff)
factored out delayed eval to Delay class
-rw-r--r--src/jvm/clojure/lang/Delay.java38
-rw-r--r--src/jvm/clojure/lang/FnSeq.java34
2 files changed, 50 insertions, 22 deletions
diff --git a/src/jvm/clojure/lang/Delay.java b/src/jvm/clojure/lang/Delay.java
new file mode 100644
index 00000000..fb1278fc
--- /dev/null
+++ b/src/jvm/clojure/lang/Delay.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) Rich Hickey. All rights reserved.
+ * The use and distribution terms for this software are covered by the
+ * Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
+ * which can be found in the file CPL.TXT 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 Jun 28, 2007 */
+
+package clojure.lang;
+
+public class Delay{
+volatile Object val;
+IFn fn;
+
+
+public Delay(IFn fn){
+ this.fn = fn;
+}
+
+public Object force() throws Exception{
+ if(val == this)
+ {
+ synchronized(this)
+ {
+ if(val == this)
+ {
+ val = fn.invoke();
+ fn = null;
+ }
+ }
+ }
+ return val;
+}
+}
diff --git a/src/jvm/clojure/lang/FnSeq.java b/src/jvm/clojure/lang/FnSeq.java
index 476145c0..236448db 100644
--- a/src/jvm/clojure/lang/FnSeq.java
+++ b/src/jvm/clojure/lang/FnSeq.java
@@ -12,14 +12,12 @@ package clojure.lang;
public class FnSeq extends ASeq{
-Object _first;
-IFn restFn;
-volatile ISeq _rest;
+final Object _first;
+final Delay _rest;
-public FnSeq(Object first, IFn restFn) {
+public FnSeq(Object first, Delay rest) {
this._first = first;
- this.restFn = restFn;
- this._rest = this;
+ this._rest = rest;
}
public Object first() {
@@ -27,21 +25,13 @@ public Object first() {
}
public ISeq rest() {
- if(_rest != this)
- return _rest;
- synchronized(this){
- if(_rest == this)
- {
- try{
- _rest = (ISeq) restFn.invoke();
- }
- catch(Exception ex)
- {
- throw new Error(ex.toString());
- }
- restFn = null;
- }
- return _rest;
- }
+ try
+ {
+ return (ISeq) _rest.force();
+ }
+ catch(Exception e)
+ {
+ throw new Error(e.toString());
+ }
}
}