diff options
-rw-r--r-- | src/boot.clj | 4 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Delay.java | 23 |
2 files changed, 13 insertions, 14 deletions
diff --git a/src/boot.clj b/src/boot.clj index a842d933..d9b12f8e 100644 --- a/src/boot.clj +++ b/src/boot.clj @@ -354,7 +354,9 @@ (spread (cons item more))) (defmacro delay - {:private true} + "Takes a body of expressions and yields a function than will invoke + the body only the first time it is called, and will cache the result + and return it on all calls" [& body] (list 'new 'clojure.lang.Delay (list* `fn [] body))) diff --git a/src/jvm/clojure/lang/Delay.java b/src/jvm/clojure/lang/Delay.java index 3698417b..ae1cfa2e 100644 --- a/src/jvm/clojure/lang/Delay.java +++ b/src/jvm/clojure/lang/Delay.java @@ -12,27 +12,24 @@ package clojure.lang; -public class Delay extends AFn{ -public volatile Object val; +public class Delay extends AFn implements IRef{ +Object val; IFn fn; - public Delay(IFn fn){ this.fn = fn; - this.val = this; + this.val = null; } public Object invoke() throws Exception{ - if(val == this) + return get(); +} + +synchronized public Object get() throws Exception{ + if(fn != null) { - synchronized(this) - { - if(val == this) - { - val = fn.invoke(); - fn = null; - } - } + val = fn.invoke(); + fn = null; } return val; } |