diff options
author | Rich Hickey <richhickey@gmail.com> | 2007-10-18 13:50:06 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2007-10-18 13:50:06 +0000 |
commit | 5c4b0b8323fe091f5a6c5a0af041a41403fbf3fb (patch) | |
tree | 7046f9507b0763133b734530eb17b92220a0f8fb /src | |
parent | 0197214873330bffbdaa0b37da2cf95c6d40d3e0 (diff) |
made collections implement java.util.Collection read-only interface
Diffstat (limited to 'src')
-rw-r--r-- | src/jvm/clojure/lang/APersistentMap.java | 78 | ||||
-rw-r--r-- | src/jvm/clojure/lang/ASeq.java | 82 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Associative.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Compiler.java | 12 | ||||
-rw-r--r-- | src/jvm/clojure/lang/MapEntry.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentArrayMap.java | 4 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentHashMap.java | 7 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentQueue.java | 80 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentTreeMap.java | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/PersistentVector.java | 82 | ||||
-rw-r--r-- | src/jvm/clojure/lang/RT.java | 99 | ||||
-rw-r--r-- | src/jvm/clojure/lang/Var.java | 2 |
12 files changed, 381 insertions, 71 deletions
diff --git a/src/jvm/clojure/lang/APersistentMap.java b/src/jvm/clojure/lang/APersistentMap.java index eff4e294..b595a53b 100644 --- a/src/jvm/clojure/lang/APersistentMap.java +++ b/src/jvm/clojure/lang/APersistentMap.java @@ -10,7 +10,9 @@ package clojure.lang;
-public abstract class APersistentMap extends AFn implements IPersistentMap{
+import java.util.Collection;
+
+public abstract class APersistentMap extends AFn implements IPersistentMap, Collection{
int _hash = -1;
@@ -138,4 +140,78 @@ static public class ValSeq extends ASeq{ public Object invoke(Object arg1) throws Exception{
return valAt(arg1);
}
+
+// java.util.Collection implementation
+
+public Object[] toArray(){
+ return RT.seqToArray(seq());
+}
+
+public boolean add(Object o){
+ throw new UnsupportedOperationException();
+}
+
+public boolean remove(Object o){
+ throw new UnsupportedOperationException();
+}
+
+public boolean addAll(Collection c){
+ throw new UnsupportedOperationException();
+}
+
+public void clear(){
+ throw new UnsupportedOperationException();
+}
+
+public boolean retainAll(Collection c){
+ throw new UnsupportedOperationException();
+}
+
+public boolean removeAll(Collection c){
+ throw new UnsupportedOperationException();
+}
+
+public boolean containsAll(Collection c){
+ for(Object o : c)
+ {
+ if(contains(o))
+ return true;
+ }
+ return false;
+}
+
+public Object[] toArray(Object[] a){
+ if(a.length >= count())
+ {
+ ISeq s = seq();
+ for(int i = 0; s != null; ++i, s = s.rest())
+ {
+ a[i] = s.first();
+ }
+ if(a.length >= count())
+ a[count()] = null;
+ return a;
+ }
+ else
+ return toArray();
+}
+
+public int size(){
+ return count();
+}
+
+public boolean isEmpty(){
+ return count() == 0;
+}
+
+public boolean contains(Object o){
+ if(o instanceof IMapEntry)
+ {
+ IMapEntry e = (IMapEntry) o;
+ IMapEntry v = entryAt(e.key());
+ return (v != null && RT.equal(v.val(), e.val()));
+ }
+ return false;
+}
+
}
diff --git a/src/jvm/clojure/lang/ASeq.java b/src/jvm/clojure/lang/ASeq.java index 59206f1b..570977d7 100644 --- a/src/jvm/clojure/lang/ASeq.java +++ b/src/jvm/clojure/lang/ASeq.java @@ -10,7 +10,10 @@ package clojure.lang;
-public abstract class ASeq extends Obj implements ISeq{
+import java.util.Collection;
+import java.util.Iterator;
+
+public abstract class ASeq extends Obj implements ISeq, Collection{
transient int _hash = -1;
@@ -71,4 +74,81 @@ public ISeq cons(Object o){ return new Cons(o, this);
}
+// java.util.Collection implementation
+
+public Object[] toArray(){
+ return RT.seqToArray(seq());
+}
+
+public boolean add(Object o){
+ throw new UnsupportedOperationException();
+}
+
+public boolean remove(Object o){
+ throw new UnsupportedOperationException();
+}
+
+public boolean addAll(Collection c){
+ throw new UnsupportedOperationException();
+}
+
+public void clear(){
+ throw new UnsupportedOperationException();
+}
+
+public boolean retainAll(Collection c){
+ throw new UnsupportedOperationException();
+}
+
+public boolean removeAll(Collection c){
+ throw new UnsupportedOperationException();
+}
+
+public boolean containsAll(Collection c){
+ for(Object o : c)
+ {
+ if(contains(o))
+ return true;
+ }
+ return false;
+}
+
+public Object[] toArray(Object[] a){
+ if(a.length >= count())
+ {
+ ISeq s = seq();
+ for(int i = 0; s != null; ++i, s = s.rest())
+ {
+ a[i] = s.first();
+ }
+ if(a.length >= count())
+ a[count()] = null;
+ return a;
+ }
+ else
+ return toArray();
+}
+
+public int size(){
+ return count();
+}
+
+public boolean isEmpty(){
+ return count() == 0;
+}
+
+public boolean contains(Object o){
+ for(ISeq s = seq(); s != null; s = s.rest())
+ {
+ if(RT.equal(s.first(), o))
+ return true;
+ }
+ return false;
+}
+
+
+public Iterator iterator(){
+ return new SeqIterator(this);
+}
+
}
diff --git a/src/jvm/clojure/lang/Associative.java b/src/jvm/clojure/lang/Associative.java index 1de849d0..486fae4d 100644 --- a/src/jvm/clojure/lang/Associative.java +++ b/src/jvm/clojure/lang/Associative.java @@ -10,7 +10,7 @@ package clojure.lang; * You must not remove this notice, or any other, from this software.
*/
public interface Associative extends IPersistentCollection{
-boolean contains(Object key);
+boolean containsKey(Object key);
IMapEntry entryAt(Object key);
diff --git a/src/jvm/clojure/lang/Compiler.java b/src/jvm/clojure/lang/Compiler.java index 496bdedd..85179fb7 100644 --- a/src/jvm/clojure/lang/Compiler.java +++ b/src/jvm/clojure/lang/Compiler.java @@ -190,7 +190,7 @@ interface IParser{ } static boolean isSpecial(Object sym){ - return specials.contains(sym); + return specials.containsKey(sym); } static Symbol resolveSymbol(Symbol sym){ @@ -753,8 +753,10 @@ static class InstanceMethodExpr extends MethodExpr{ { List methods = Reflector.getMethods(target.getJavaClass(), args.count(), methodName, false); if(methods.isEmpty()) - throw new IllegalArgumentException("No matching method found"); - method = (java.lang.reflect.Method) ((methods.size() == 1) ? methods.get(0) : null); + method = null; + //throw new IllegalArgumentException("No matching method found"); + else + method = (java.lang.reflect.Method) ((methods.size() == 1) ? methods.get(0) : null); } else method = null; @@ -2008,7 +2010,7 @@ static class FnExpr implements Expr{ } private void emitLocal(GeneratorAdapter gen, LocalBinding lb){ - if(closes.contains(lb)) + if(closes.containsKey(lb)) { gen.loadThis(); gen.getField(fntype, lb.name, OBJECT_TYPE); @@ -2509,7 +2511,7 @@ private static Expr analyzeSeq(C context, ISeq form, String name) throws Excepti Integer line = (Integer) LINE.get(); try { - if(RT.meta(form) != null && RT.meta(form).contains(LispReader.LINE_KEY)) + if(RT.meta(form) != null && RT.meta(form).containsKey(LispReader.LINE_KEY)) line = (Integer) RT.meta(form).valAt(LispReader.LINE_KEY); Var.pushThreadBindings( RT.map(LINE, line)); diff --git a/src/jvm/clojure/lang/MapEntry.java b/src/jvm/clojure/lang/MapEntry.java index 1d99ace3..ae1207c3 100644 --- a/src/jvm/clojure/lang/MapEntry.java +++ b/src/jvm/clojure/lang/MapEntry.java @@ -36,7 +36,7 @@ public Object val(){ return _val;
}
-public boolean contains(Object key){
+public boolean containsKey(Object key){
return RT.equal(_key, key);
}
diff --git a/src/jvm/clojure/lang/PersistentArrayMap.java b/src/jvm/clojure/lang/PersistentArrayMap.java index 773ed158..35ca450e 100644 --- a/src/jvm/clojure/lang/PersistentArrayMap.java +++ b/src/jvm/clojure/lang/PersistentArrayMap.java @@ -26,7 +26,7 @@ import java.util.Iterator; public class PersistentArrayMap extends APersistentMap{
final Object[] array;
-static final int HASHTABLE_THRESHOLD = 16;
+static final int HASHTABLE_THRESHOLD = 8;
public static PersistentArrayMap EMPTY = new PersistentArrayMap();
@@ -65,7 +65,7 @@ public int count(){ return array.length / 2;
}
-public boolean contains(Object key){
+public boolean containsKey(Object key){
return indexOf(key) >= 0;
}
diff --git a/src/jvm/clojure/lang/PersistentHashMap.java b/src/jvm/clojure/lang/PersistentHashMap.java index 95c0399d..48d413f0 100644 --- a/src/jvm/clojure/lang/PersistentHashMap.java +++ b/src/jvm/clojure/lang/PersistentHashMap.java @@ -14,9 +14,6 @@ package clojure.lang; import java.util.*; //this stuff is just for the test main() -import java.util.regex.Pattern; -import java.io.File; -import java.io.FileNotFoundException; /* A persistent rendition of Phil Bagwell's Hash Array Mapped Trie @@ -95,7 +92,7 @@ public PersistentHashMap(IPersistentMap meta, int count, INode root){ this.root = root; } -public boolean contains(Object key){ +public boolean containsKey(Object key){ return entryAt(key) != null; } @@ -119,7 +116,7 @@ public Object valAt(Object key){ } public IPersistentMap assocEx(Object key, Object val) throws Exception{ - if(contains(key)) + if(containsKey(key)) throw new Exception("Key already present"); return assoc(key, val); } diff --git a/src/jvm/clojure/lang/PersistentQueue.java b/src/jvm/clojure/lang/PersistentQueue.java index eb3507f9..4d21fff3 100644 --- a/src/jvm/clojure/lang/PersistentQueue.java +++ b/src/jvm/clojure/lang/PersistentQueue.java @@ -12,6 +12,8 @@ package clojure.lang; import java.util.Queue;
import java.util.LinkedList;
+import java.util.Collection;
+import java.util.Iterator;
//import java.util.concurrent.ConcurrentLinkedQueue;
/**
@@ -21,7 +23,7 @@ import java.util.LinkedList; * so no reversing or suspensions required for persistent use
*/
-public class PersistentQueue extends Obj implements IPersistentList{
+public class PersistentQueue extends Obj implements IPersistentList, Collection{
final public static PersistentQueue EMPTY = new PersistentQueue(null, null, null);
@@ -144,6 +146,82 @@ static class Seq extends ASeq{ }
}
+// java.util.Collection implementation
+
+public Object[] toArray(){
+ return RT.seqToArray(seq());
+}
+
+public boolean add(Object o){
+ throw new UnsupportedOperationException();
+}
+
+public boolean remove(Object o){
+ throw new UnsupportedOperationException();
+}
+
+public boolean addAll(Collection c){
+ throw new UnsupportedOperationException();
+}
+
+public void clear(){
+ throw new UnsupportedOperationException();
+}
+
+public boolean retainAll(Collection c){
+ throw new UnsupportedOperationException();
+}
+
+public boolean removeAll(Collection c){
+ throw new UnsupportedOperationException();
+}
+
+public boolean containsAll(Collection c){
+ for(Object o : c)
+ {
+ if(contains(o))
+ return true;
+ }
+ return false;
+}
+
+public Object[] toArray(Object[] a){
+ if(a.length >= count())
+ {
+ ISeq s = seq();
+ for(int i = 0; s != null; ++i, s = s.rest())
+ {
+ a[i] = s.first();
+ }
+ if(a.length >= count())
+ a[count()] = null;
+ return a;
+ }
+ else
+ return toArray();
+}
+
+public int size(){
+ return count();
+}
+
+public boolean isEmpty(){
+ return count() == 0;
+}
+
+public boolean contains(Object o){
+ for(ISeq s = seq(); s != null; s = s.rest())
+ {
+ if(RT.equal(s.first(), o))
+ return true;
+ }
+ return false;
+}
+
+public Iterator iterator(){
+ return new SeqIterator(seq());
+}
+
/*
public static void main(String[] args){
if(args.length != 1)
diff --git a/src/jvm/clojure/lang/PersistentTreeMap.java b/src/jvm/clojure/lang/PersistentTreeMap.java index 73dd2846..8abbb69e 100644 --- a/src/jvm/clojure/lang/PersistentTreeMap.java +++ b/src/jvm/clojure/lang/PersistentTreeMap.java @@ -79,7 +79,7 @@ static public PersistentTreeMap create(Comparator comp, ISeq items){ return (PersistentTreeMap) ret; } -public boolean contains(Object key){ +public boolean containsKey(Object key){ return entryAt(key) != null; } diff --git a/src/jvm/clojure/lang/PersistentVector.java b/src/jvm/clojure/lang/PersistentVector.java index 328a0522..5896bdad 100644 --- a/src/jvm/clojure/lang/PersistentVector.java +++ b/src/jvm/clojure/lang/PersistentVector.java @@ -12,9 +12,11 @@ package clojure.lang; -import java.util.*; +import java.util.Collection; +import java.util.List; +import java.util.Iterator; -public class PersistentVector extends AFn implements IPersistentVector, Iterable{ +public class PersistentVector extends AFn implements IPersistentVector, Iterable, Collection{ final int cnt; final int shift; final Object[] root; @@ -185,6 +187,7 @@ public Iterator iterator(){ }; } + static class Seq extends ASeq implements IndexedSeq{ //todo - something more efficient final PersistentVector v; @@ -348,7 +351,8 @@ private Object[] doPop(int shift, Object[] arr){ return ret; } -public boolean contains(Object key){ + +public boolean containsKey(Object key){ if(!(key instanceof Number)) return false; int i = ((Number) key).intValue(); @@ -384,6 +388,78 @@ public Object valAt(Object key){ return null; } +// java.util.Collection implementation + +public Object[] toArray(){ + return RT.seqToArray(seq()); +} + +public boolean add(Object o){ + throw new UnsupportedOperationException(); +} + +public boolean remove(Object o){ + throw new UnsupportedOperationException(); +} + +public boolean addAll(Collection c){ + throw new UnsupportedOperationException(); +} + +public void clear(){ + throw new UnsupportedOperationException(); +} + +public boolean retainAll(Collection c){ + throw new UnsupportedOperationException(); +} + +public boolean removeAll(Collection c){ + throw new UnsupportedOperationException(); +} + +public boolean containsAll(Collection c){ + for(Object o : c) + { + if(contains(o)) + return true; + } + return false; +} + +public Object[] toArray(Object[] a){ + if(a.length >= count()) + { + ISeq s = seq(); + for(int i = 0; s != null; ++i, s = s.rest()) + { + a[i] = s.first(); + } + if(a.length >= count()) + a[count()] = null; + return a; + } + else + return toArray(); +} + +public int size(){ + return count(); +} + +public boolean isEmpty(){ + return count() == 0; +} + +public boolean contains(Object o){ + for(ISeq s = seq(); s != null; s = s.rest()) + { + if(RT.equal(s.first(), o)) + return true; + } + return false; +} + /* static public void main(String[] args){ if(args.length != 3) diff --git a/src/jvm/clojure/lang/RT.java b/src/jvm/clojure/lang/RT.java index 6de45959..26782f24 100644 --- a/src/jvm/clojure/lang/RT.java +++ b/src/jvm/clojure/lang/RT.java @@ -12,7 +12,6 @@ package clojure.lang; -import java.util.Iterator; import java.util.concurrent.atomic.AtomicInteger; import java.io.*; import java.lang.reflect.Array; @@ -51,47 +50,47 @@ final static IPersistentMap DEFAULT_IMPORTS = map( // Symbol.create("IPersistentMap"), "clojure.lang.IPersistentMap", // Symbol.create("IPersistentList"), "clojure.lang.IPersistentList", // Symbol.create("IPersistentVector"), "clojure.lang.IPersistentVector", - Symbol.create("Boolean"), "java.lang.Boolean", - Symbol.create("Byte"), "java.lang.Byte", - Symbol.create("Character"), "java.lang.Character", - Symbol.create("Class"), "java.lang.Class", - Symbol.create("ClassLoader"), "java.lang.ClassLoader", - Symbol.create("Compiler"), "java.lang.Compiler", - Symbol.create("Double"), "java.lang.Double", - Symbol.create("Enum"), "java.lang.Enum", - Symbol.create("Float"), "java.lang.Float", - Symbol.create("InheritableThreadLocal"), - "java.lang.InheritableThreadLocal", - Symbol.create("Integer"), "java.lang.Integer", - Symbol.create("Long"), "java.lang.Long", - Symbol.create("Math"), "java.lang.Math", - Symbol.create("Number"), "java.lang.Number", - Symbol.create("Object"), "java.lang.Object", - Symbol.create("Package"), "java.lang.Package", - Symbol.create("Process"), "java.lang.Process", - Symbol.create("ProcessBuilder"), "java.lang.ProcessBuilder", - Symbol.create("Runtime"), "java.lang.Runtime", - Symbol.create("RuntimePermission"), "java.lang.RuntimePermission", - Symbol.create("SecurityManager"), "java.lang.SecurityManager", - Symbol.create("Short"), "java.lang.Short", - Symbol.create("StackTraceElement"), "java.lang.StackTraceElement", - Symbol.create("StrictMath"), "java.lang.StrictMath", - Symbol.create("String"), "java.lang.String", - Symbol.create("StringBuffer"), "java.lang.StringBuffer", - Symbol.create("StringBuilder"), "java.lang.StringBuilder", - Symbol.create("System"), "java.lang.System", - Symbol.create("Thread"), "java.lang.Thread", - Symbol.create("ThreadGroup"), "java.lang.ThreadGroup", - Symbol.create("ThreadLocal"), "java.lang.ThreadLocal", - Symbol.create("Throwable"), "java.lang.Throwable", - Symbol.create("Void"), "java.lang.Void", - Symbol.create("Appendable"), "java.lang.Appendable", - Symbol.create("CharSequence"), "java.lang.CharSequence", - Symbol.create("Cloneable"), "java.lang.Cloneable", - Symbol.create("Iterable"), "java.lang.Iterable", - Symbol.create("Readable"), "java.lang.Readable", - Symbol.create("Runnable"), "java.lang.Runnable", - Symbol.create("Exception"), "java.lang.Exception" +Symbol.create("Boolean"), "java.lang.Boolean", +Symbol.create("Byte"), "java.lang.Byte", +Symbol.create("Character"), "java.lang.Character", +Symbol.create("Class"), "java.lang.Class", +Symbol.create("ClassLoader"), "java.lang.ClassLoader", +Symbol.create("Compiler"), "java.lang.Compiler", +Symbol.create("Double"), "java.lang.Double", +Symbol.create("Enum"), "java.lang.Enum", +Symbol.create("Float"), "java.lang.Float", +Symbol.create("InheritableThreadLocal"), +"java.lang.InheritableThreadLocal", +Symbol.create("Integer"), "java.lang.Integer", +Symbol.create("Long"), "java.lang.Long", +Symbol.create("Math"), "java.lang.Math", +Symbol.create("Number"), "java.lang.Number", +Symbol.create("Object"), "java.lang.Object", +Symbol.create("Package"), "java.lang.Package", +Symbol.create("Process"), "java.lang.Process", +Symbol.create("ProcessBuilder"), "java.lang.ProcessBuilder", +Symbol.create("Runtime"), "java.lang.Runtime", +Symbol.create("RuntimePermission"), "java.lang.RuntimePermission", +Symbol.create("SecurityManager"), "java.lang.SecurityManager", +Symbol.create("Short"), "java.lang.Short", +Symbol.create("StackTraceElement"), "java.lang.StackTraceElement", +Symbol.create("StrictMath"), "java.lang.StrictMath", +Symbol.create("String"), "java.lang.String", +Symbol.create("StringBuffer"), "java.lang.StringBuffer", +Symbol.create("StringBuilder"), "java.lang.StringBuilder", +Symbol.create("System"), "java.lang.System", +Symbol.create("Thread"), "java.lang.Thread", +Symbol.create("ThreadGroup"), "java.lang.ThreadGroup", +Symbol.create("ThreadLocal"), "java.lang.ThreadLocal", +Symbol.create("Throwable"), "java.lang.Throwable", +Symbol.create("Void"), "java.lang.Void", +Symbol.create("Appendable"), "java.lang.Appendable", +Symbol.create("CharSequence"), "java.lang.CharSequence", +Symbol.create("Cloneable"), "java.lang.Cloneable", +Symbol.create("Iterable"), "java.lang.Iterable", +Symbol.create("Readable"), "java.lang.Readable", +Symbol.create("Runnable"), "java.lang.Runnable", +Symbol.create("Exception"), "java.lang.Exception" // Symbol.create("Collection"), "java.util.Collection", // Symbol.create("Comparator"), "java.util.Comparator", // Symbol.create("Enumeration"), "java.util.Enumeration", @@ -117,13 +116,13 @@ final static IFn inNamespace = new AFn(){ CURRENT_NS_SYM.set(ns); Var refers = Var.intern(Symbol.intern(ns.name, "*refers*")); - Var imports = Var.intern(Symbol.intern(ns.name, "*imports*"), DEFAULT_IMPORTS,false); + Var imports = Var.intern(Symbol.intern(ns.name, "*imports*"), DEFAULT_IMPORTS, false); NS_REFERS.set(refers); NS_IMPORTS.set(imports); if(!refers.isBound()) { refers.bindRoot(PersistentHashMap.EMPTY); - Compiler.eval(list(Symbol.create("clojure","refer"),EXPORTS)); + Compiler.eval(list(Symbol.create("clojure", "refer"), EXPORTS)); } return RT.T; } @@ -320,7 +319,7 @@ static public Associative assoc(Object coll, Object key, Object val){ static public Object contains(Object coll, Object key){ if(coll == null) return false; - return ((Associative) coll).contains(key) ? T : null; + return ((Associative) coll).containsKey(key) ? T : null; } static public Object find(Object coll, Object key){ @@ -494,6 +493,8 @@ static public double doubleCast(Object x){ static public IPersistentMap map(Object... init){ + if(init != null && init.length == 2) + return new MapEntry(init[0], init[1]); return PersistentHashMap.create(init); } @@ -557,7 +558,7 @@ static public ISeq arrayToList(Object[] a) throws Exception{ return ret; } -static public Object[] seqToArray(ISeq seq) throws Exception{ +static public Object[] seqToArray(ISeq seq){ int len = length(seq); Object[] ret = new Object[len]; for(int i = 0; seq != null; ++i, seq = seq.rest()) @@ -569,11 +570,11 @@ static public Object seqToTypedArray(ISeq seq) throws Exception{ int len = length(seq); Object ret = Array.newInstance(len > 0 ? seq.first().getClass() : Object.class, len); for(int i = 0; seq != null; ++i, seq = seq.rest()) - Array.set(ret,i,seq.first()); + Array.set(ret, i, seq.first()); return ret; } -static public int length(ISeq list) throws Exception{ +static public int length(ISeq list){ int i = 0; for(ISeq c = list; c != null; c = c.rest()) { @@ -657,7 +658,7 @@ static public void print(Object x, Writer w) throws Exception{ { IPersistentMap meta = o.meta(); w.write("#^"); - if(meta.count() == 1 && meta.contains(TAG_KEY)) + if(meta.count() == 1 && meta.containsKey(TAG_KEY)) print(meta.valAt(TAG_KEY), w); else print(meta, w); diff --git a/src/jvm/clojure/lang/Var.java b/src/jvm/clojure/lang/Var.java index 1a0952fb..7e355c76 100644 --- a/src/jvm/clojure/lang/Var.java +++ b/src/jvm/clojure/lang/Var.java @@ -129,7 +129,7 @@ private Var(Symbol sym, Object root){ } public boolean isBound(){ - return hasRoot() || dvals.get().bindings.contains(this); + return hasRoot() || dvals.get().bindings.containsKey(this); } final public Object get(){ |