I have two minor minor suggestions for Clojure changes.
1) Consider this function:
user> (set! *warn-on-reflection* true)
true
user> (defn reader-from-classpath [s]
(-> (.getResourceAsStream java.lang.String s)
(java.io.InputStreamReader.)
(java.io.BufferedReader.)))
Reflection warning, NO_SOURCE_PATH:2 - call to getResourceAsStream
can't be resolved.
#'user/reader-from-classpath
In general, I think every call of form (.instanceMember Classname
args*) will generate such a warning since it expands to, e.g.,
user> (macroexpand ' (.getResourceAsStream java.lang.String s))
(. (clojure.core/identity java.lang.String) getResourceAsStream s)
user>
And identity doesn't have any type information. A simple fix would be.
user> (defn #^Class class-identity [#^Class c] c)
#'user/class-identity
and then expanding (.instanceMember Classname args*) to
(. (class-identity Classname) instanceMember args*)
-------
2) I can do:
user> (into {} '([:k :v]))
{:k :v}
This works for two-element vectors. However, I cannot do the same for
two-element arrays:
user> (def str_array (.split "k=v" "="))
#'user/str_array
user> (into {} (list str_array))
; Evaluation aborted.
It would be a simple addition to clojure.lang.ATransientMap:
import java.lang.reflect.Array;//change
...
public ITransientMap conj(Object o) {
ensureEditable();
if(o instanceof Map.Entry)
{
Map.Entry e = (Map.Entry) o;
return assoc(e.getKey(), e.getValue());
}
else if(o instanceof IPersistentVector)
{
IPersistentVector v = (IPersistentVector) o;
if(v.count() != 2)
throw new IllegalArgumentException("Vector arg
to map conj must be
a pair");
return assoc(v.nth(0), v.nth(1));
}//begin change
else if(o != null && o.getClass().isArray())
{
if(Array.getLength(o) != 2)
throw new IllegalArgumentException("Array arg
to map conj must
have exactly two elements");
return assoc(Array.get(o,0), Array.get(o,1));
}//end change
ITransientMap ret = this;
for(ISeq es = RT.seq(o); es != null; es = es.next())
{
Map.Entry e = (Map.Entry) es.first();
ret = ret.assoc(e.getKey(), e.getValue());
}
return ret;
}
After this change I have:
user> (def str_array (.split "k=v" "="))
#'user/str_array
user> (into {} (list str_array))
{"k" "v"}
user>
The use-case arose from wanting to create a map from a properties file
using split ("=") on each line of the properties file (and not wanting
to copy the array into []).
N.B. the cost is an additional null-check and o.getClass().isArray().
What do you guys think?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---