summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Hickey <richhickey@gmail.com>2007-10-27 12:07:21 +0000
committerRich Hickey <richhickey@gmail.com>2007-10-27 12:07:21 +0000
commit7b1999c497f9e39c01a2b9f5d628f22df701c0e3 (patch)
treef3a7b08546b0911f0631c20cf3fcb8e5ec01be3d /src
parenta90826fc6f3cba8f4541a2a4e02739de6e7954a1 (diff)
rename new-proxy to implement, rename .-> to doto, rename dolist to doseq, added into, memfn, fnseq. Made FnSeq not use Delay
Diffstat (limited to 'src')
-rw-r--r--src/boot.clj46
-rw-r--r--src/jvm/clojure/lang/Compiler.java2
-rw-r--r--src/jvm/clojure/lang/FnSeq.java41
3 files changed, 60 insertions, 29 deletions
diff --git a/src/boot.clj b/src/boot.clj
index 04031be6..587d7098 100644
--- a/src/boot.clj
+++ b/src/boot.clj
@@ -108,8 +108,12 @@
(defmacro delay [& body]
(list 'new 'clojure.lang.Delay (list* 'fn [] body)))
+(defn fnseq [x restfn]
+ (new clojure.lang.FnSeq x restfn))
+
(defmacro lazy-cons [x & body]
- (list 'new 'clojure.lang.FnSeq x (list* 'delay body)))
+ (list 'fnseq x (list* 'fn [] body)))
+
(defn concat
([] nil)
@@ -493,7 +497,7 @@
(defn defimports [& imports-maps]
(def *imports* (apply merge imports-maps)))
-(defmacro dolist [item list & body]
+(defmacro doseq [item list & body]
`(loop [list# (seq ~list)]
(when list#
(let [~item (first list#)]
@@ -511,21 +515,21 @@
(let [#^clojure.lang.Var imps *ns-imports*
pkg (ffirst import-lists)
classes (rfirst import-lists)]
- (dolist c classes
+ (doseq c classes
(. imps (bindRoot (assoc (. imps (get)) c (strcat pkg "." c))))))
(apply thisfn (rest import-lists))))
(defn unimport [& names]
(let [#^clojure.lang.Var imps *ns-imports*]
- (dolist name names
+ (doseq name names
(. imps (bindRoot (dissoc (. imps (get)) name))))))
(defn refer [& refer-lists]
- (dolist rlist refer-lists
+ (doseq rlist refer-lists
(let [#^clojure.lang.Var refers *ns-refers*
ns (first rlist)
names (rest rlist)]
- (dolist name names
+ (doseq name names
(when (. clojure.lang.Var (find (sym (str *current-namespace*) (str name))))
(throw (new Exception (strcat "Name conflict: " name " already exists in this namespace"))))
(let [varsym (sym (str ns) (str name))
@@ -540,7 +544,7 @@
(defn unrefer [& names]
(let [#^clojure.lang.Var refers *ns-refers*]
- (dolist name names
+ (doseq name names
(. refers (bindRoot (dissoc (. refers (get)) name))))))
(defn unintern [varsym]
@@ -549,6 +553,12 @@
(defn into-array [aseq]
(. clojure.lang.RT (seqToTypedArray (seq aseq))))
+(defn into [to from]
+ (let [ret to items (seq from)]
+ (if items
+ (recur (conj ret (first items)) (rest items))
+ ret)))
+
(defn array [& items]
(into-array items))
@@ -558,7 +568,7 @@
(into-array classes)
(new clojure.lang.ProxyHandler method-map))))
-(defmacro new-proxy [classes & fs]
+(defmacro implement [classes & fs]
`(make-proxy
~(apply vector (map (appl list 'class) classes))
~(loop [fmap {} fs fs]
@@ -594,16 +604,21 @@
([stream eof-error? eof-value recursive?]
(. clojure.lang.LispReader (read stream eof-error? eof-value recursive?))))
-(defmacro .-> [x & members]
+(defmacro doto [x & members]
(let [gx (gensym)]
`(let [~gx ~x]
(do
~@(map (fn [m] (list '. gx m))
members)))))
+
+(defmacro memfn [name & args]
+ `(fn [target# ~@args]
+ (. target# (~name ~@args))))
+
(defmacro time [expr]
`(let [start# (. System (nanoTime))
ret# ~expr]
- (prn (strcat "Elapsed time: " (/ (- (. System (nanoTime)) start#) 1000000.0)" msecs"))
+ (prn (strcat "Elapsed time: " (/ (- (. System (nanoTime)) start#) 1000000.0) " msecs"))
ret#))
(def *exports*
@@ -615,7 +630,7 @@
nil? not first rest second
ffirst frest rfirst rrest
eql? str strcat gensym cond
- apply list* delay lazy-cons concat
+ apply list* delay lazy-cons fnseq concat
and or + * / - == < <= > >=
inc dec pos? neg? zero?
complement constantly identity seq count
@@ -630,12 +645,13 @@
map mapcat filter take take-while drop drop-while
zipmap
cycle split-at split-with repeat replicate iterate range
- dolist dotimes
+ doseq dotimes into
eval import unimport refer unrefer in-namespace unintern
into-array array
- make-proxy new-proxy
- prn print newline *out* *current-namespace* .->
- read *in*
+ make-proxy implement
+ prn print newline *out* *current-namespace*
+ doto memfn
+ read *in*
time
))
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java
index 13a7fcf3..fa3a0e52 100644
--- a/src/jvm/clojure/lang/Compiler.java
+++ b/src/jvm/clojure/lang/Compiler.java
@@ -825,7 +825,7 @@ static class StaticMethodExpr extends MethodExpr{
List methods = Reflector.getMethods(Class.forName(className), args.count(), methodName, true);
if(methods.isEmpty())
- throw new IllegalArgumentException("No matching method found");
+ throw new IllegalArgumentException("No matching method: " + methodName);
method = (java.lang.reflect.Method) ((methods.size() == 1) ? methods.get(0) : null);
}
diff --git a/src/jvm/clojure/lang/FnSeq.java b/src/jvm/clojure/lang/FnSeq.java
index 48211217..99f8429e 100644
--- a/src/jvm/clojure/lang/FnSeq.java
+++ b/src/jvm/clojure/lang/FnSeq.java
@@ -13,17 +13,20 @@ package clojure.lang;
public class FnSeq extends ASeq{
final Object _first;
-final Delay _rest;
+IFn _restFn;
+volatile ISeq _rest;
-public FnSeq(Object first, Delay rest){
+public FnSeq(Object first, IFn restFn){
this._first = first;
- this._rest = rest;
+ this._restFn = restFn;
+ this._rest = this;
}
-public FnSeq(IPersistentMap meta, Object first, Delay rest){
+public FnSeq(IPersistentMap meta, Object first, IFn restFn, ISeq rest){
super(meta);
this._first = first;
this._rest = rest;
+ this._restFn = restFn;
}
public Object first(){
@@ -31,17 +34,29 @@ public Object first(){
}
public ISeq rest(){
- try
- {
- return (ISeq) _rest.invoke();
- }
- catch(Exception e)
- {
- throw new Error(e.toString());
- }
+ if(_restFn != null)
+ synchronized(this)
+ {
+ if(_restFn != null)
+ {
+ try
+ {
+ _rest = (ISeq) _restFn.invoke();
+ }
+ catch(Exception ex)
+ {
+ throw new Error(ex);
+ }
+ _restFn = null;
+ }
+ }
+ return _rest;
}
public FnSeq withMeta(IPersistentMap meta){
- return new FnSeq(meta, _first, _rest);
+ if(meta == meta())
+ return this;
+ return new FnSeq(meta, _first, _restFn, _rest);
}
+
}