Acessing parent object fields/methods in Clojure - reflection

I have a java.awt.Frame that is a descendent of java.awt.Component. I'm trying to get the peer field of the Component, or else call .getPeer on it.
(def f (new Frame "AWT test"))
(. f setSize 400 400)
(. f setLayout (new GridLayout 3 1))
(class f) ;;java.awt.Frame
(supers (class f)) ;; #{java.awt.Container java.io.Serializable java.awt.Window java.awt.image.ImageObserver java.awt.Component java.awt.MenuContainer java.lang.Object javax.accessibility.Accessible}
I can see that Component is a superclass, but can't figure out how to access it.
(filter #(instance? java.awt.Component %) (supers (class f))) ;; () - it returns empty
Yes, I know getPeers is deprecated. I'll likely need to do some reflection work after I get the Component. And I already have the requisite add-opens in play.

You just call (.getPeer f), like any other method. No fancy business is required to call a public method, whether declared in this class or in a superclass. Of course, this only works if you're using a version of Java old enough to support this method.

I still don't have a clear answer of how to filter by the class, but I did find a way to get the peer component:
(def acc (AWTAccessor/getComponentAccessor))
(.getPeer acc f);; #object[sun.awt.X11.XFramePeer 0x2fa3dc81 "sun.awt.X11.XFramePeer#2fa3dc81(7600007)"]
That's good enough for now.

Related

Clojure's disappearing reflection warnings

A simple reflection warning example:
lein repl
user=> (set! *warn-on-reflection* true)
true
user=> (eval '(fn [x] (.length x)))
Reflection warning, NO_SOURCE_PATH:1:16 - reference to field length can't be resolved.
#object[user$eval2009$fn__2010 0x487ba4b8 "user$eval2009$fn__2010#487ba4b8"]
I want to make this into a function. But where do reflection warnings go?
//clojure/compile.java 63
RT.errPrintWriter()
.format("Reflection warning, %s:%d:%d - reference to field %s can't be resolved.\n",
SOURCE_PATH.deref(), line, column, fieldName);
//clojure/RT.java 269
public static PrintWriter errPrintWriter(){
Writer w = (Writer) ERR.deref();
//clojure/RT.java 188
final static public Var ERR =
Var.intern(CLOJURE_NS, Symbol.intern("*err*"),
new PrintWriter(new OutputStreamWriter(System.err), true)).setDynamic();
Ok so they go to System.err. Lets capture it's output:
(def pipe-in (PipedInputStream.))
(def pipe-out (PipedOutputStream. pipe-in))
(System/setErr (PrintStream. pipe-out))
(defn reflection-check [fn-code]
(binding [*warn-on-reflection* true]
(let [x (eval fn-code)
;_ (.println (System/err) "foo") ; This correctly makes us return "foo".
n (.available pipe-in)
^bytes b (make-array Byte/TYPE n)
_ (.read pipe-in b)
s (apply str (mapv char b))]
s)))
However, calling it gives no warning, and no flushing seems to be useful:
(println "Reflection check:" (reflection-check '(fn [x] (.length x)))) ; no warning.
How can I extract the reflection warning?
You have correctly discovered how *err* is initialized, but since vars are rebindable this is no guarantee about its current value. The REPL often rebinds it to something else, e.g. a socket. If you want to redirect it yourself, you should simply rebind *err* to a Writer of your choosing.
Really I'm not sure your approach would work even if *err* were never rebound. The Clojure runtime has captured a pointer to the original value of System.err, and then you ask the Java runtime to use a new value for System.err. Clojure certainly won't know about this new value. Does the JRE maintain an extra level of indirection to allow it to do these swaps behind the scenes even for people who have already captured System.err? Maybe, but if so it's not documented.
I ran into a similar problem a while back and created some helper functions modelled on with-out-str. Here is a solution to your problem:
(ns tst.demo.core
(:use tupelo.core tupelo.test) )
(defn reflection-check
[fn-code]
(let [err-str (with-err-str
(binding [*warn-on-reflection* true]
(eval fn-code)))]
(spyx err-str)))
(dotest
(reflection-check (quote (fn [x] (.length x)))))
with result:
-------------------------------
Clojure 1.10.1 Java 14
-------------------------------
err-str => "Reflection warning, /tmp/form-init3884945788481466752.clj:12:36
- reference to field length can't be resolved.\n"
Note that binding and let forms can be in either order and still work.
Here is the source code:
(defmacro with-err-str
"Evaluates exprs in a context in which *err* is bound to a fresh
StringWriter. Returns the string created by any nested printing
calls."
[& body]
`(let [s# (new java.io.StringWriter)]
(binding [*err* s#]
~#body
(str s#))))
If you need to capture the Java System.err stream, it is different:
(defmacro with-system-err-str
"Evaluates exprs in a context in which JVM System/err is bound to a fresh
PrintStream. Returns the string created by any nested printing calls."
[& body]
`(let [baos# (ByteArrayOutputStream.)
ps# (PrintStream. baos#)]
(System/setErr ps#)
~#body
(System/setErr System/err)
(.close ps#)
(.toString baos#)))
See the docs here.
There are 5 variants (plus clojure.core/with-out-str):
with-err-str
with-system-out-str
with-system-err-str
discarding-system-out
discarding-system-err
Source code is here.

How to use method reference in Java 8 for Map merge?

I have following 2 forms of calling a collect operation, both return same result, but I still cannot depend fully on method references and need a lambda.
<R> R collect(Supplier<R> supplier,
BiConsumer<R,? super T> accumulator,
BiConsumer<R,R> combiner)
For this consider the following stream consisting on 100 random numbers
List<Double> dataList = new Random().doubles().limit(100).boxed()
.collect(Collectors.toList());
1) Following example uses pure lambdas
Map<Boolean, Integer> partition = dataList.stream()
.collect(() -> new ConcurrentHashMap<Boolean, Integer>(),
(map, x) ->
{
map.merge(x < 0.5 ? Boolean.TRUE : Boolean.FALSE, 1, Integer::sum);
}, (map, map2) ->
{
map2.putAll(map);
});
2) Following tries to use method references but 2nd argument still requires a lambda
Map<Boolean, Integer> partition2 = dataList.stream()
.collect(ConcurrentHashMap<Boolean, Integer>::new,
(map, x) ->
{
map.merge(x < 0.5 ? Boolean.TRUE : Boolean.FALSE, 1, Integer::sum);
}, Map::putAll);
How can I rewrite 2nd argument of collect method in java 8 to use method reference instead of a lambda for this example?
System.out.println(partition.toString());
System.out.println(partition2.toString());
{false=55, true=45}
{false=55, true=45}
A method reference is a handy tool if you have an existing method doing exactly the intended thing. If you need adaptations or additional operations, there is no special syntax for method references to support that, except, when you consider lambda expressions to be that syntax.
Of course, you can create a new method in your class doing the desired thing and create a method reference to it and that’s the right way to go when the complexity of the code raises, as then, it will get a meaningful name and become testable. But for simple code snippets, you can use lambda expressions, which are just a simpler syntax for the same result. Technically, there is no difference, except that the compiler generated method holding the lambda expression body will be marked as “synthetic”.
In your example, you can’t even use Map::putAll as merge function, as that would overwrite all existing mappings of the first map instead of merging the values.
A correct implementation would look like
Map<Boolean, Integer> partition2 = dataList.stream()
.collect(HashMap::new,
(map, x) -> map.merge(x < 0.5, 1, Integer::sum),
(m1, m2) -> m2.forEach((k, v) -> m1.merge(k, v, Integer::sum)));
but you don’t need to implement it by yourself. There are appropriate built-in collectors already offered in the Collectors class:
Map<Boolean, Long> partition2 = dataList.stream()
.collect(Collectors.partitioningBy(x -> x < 0.5, Collectors.counting()));

Why does binding affect the type of my map?

I was playing around in the REPL and I got some weird behavior:
Clojure 1.4.0
user=> (type {:a 1})
clojure.lang.PersistentArrayMap
user=> (def x {:a 1})
#'user/x
user=> (type x)
clojure.lang.PersistentHashMap
I thought that all small literal maps were instances of PersistentArrayMap, but apparently that's not the case if it's been bound with def. Why would using def cause Clojure to choose a different representation for my litte map? I know it's probably just some strange implementation detail, but I'm curious.
This question made me dig into the Clojure source code. I just spent a few hours putting print statements in the source in order to figure this out.
It turns out the two map expressions are evaluated through different code paths
(type {:a 1}) causes Java byte-code to be emitted and ran. The emitted code use clojure.lang.RT.map() to construct the map which returns a PersistentArrayMap for small maps:
static public IPersistentMap map(Object... init){
if(init == null)
return PersistentArrayMap.EMPTY;
else if(init.length <= PersistentArrayMap.HASHTABLE_THRESHOLD)
return PersistentArrayMap.createWithCheck(init);
return PersistentHashMap.createWithCheck(init);
}
When evaluating (def x {:a 1}) at least from the REPL there's no byte-code emitted. The constant map is parsed as a PersistentHashMap in clojure.lang.Compiler$MapExpr.parse() which returns it warpped it in a ConstantExpr:
else if(constant)
{
IPersistentMap m = PersistentHashMap.EMPTY;
for(int i=0;i<keyvals.length();i+= 2)
{
m = m.assoc(((LiteralExpr)keyvals.nth(i)).val(), ((LiteralExpr)keyvals.nth(i+1)).val());
}
//System.err.println("Constant: " + m);
return new ConstantExpr(m);
}
The def expression when evaluated binds the value of the ConstantExpr created above which as as said is a PersistentHashMap.
So why is it implemented this way?
I don't know. It could be simple oversight or the PersistentArrayMap optimization may not really be worth it.

Converting a org.w3c.dom.NodeList to a Clojure ISeq

I am trying to get a handle on the new defprotocol, reify, etc.
I have a org.w3c.dom.NodeList returned from an XPath call and I would like to "convert" it to an ISeq.
In Scala, I implemented an implicit conversion method:
implicit def nodeList2Traversable(nodeList: NodeList): Traversable[Node] = {
new Traversable[Node] {
def foreach[A](process: (Node) => A) {
for (index <- 0 until nodeList.getLength) {
process(nodeList.item(index))
}
}
}
}
NodeList includes methods int getLength() and Node item(int index).
How do I do the equivalent in Clojure? I expect that I will need to use defprotocol. What functions do I need to define to create a seq?
If I do a simple, naive, conversion to a list using loop and recur, I will end up with a non-lazy structure.
Most of Clojure's sequence-processing functions return lazy seqs, include the map and range functions:
(defn node-list-seq [^org.w3c.dom.NodeList node-list]
(map (fn [index] (.item node-list index))
(range (.getLength node-list))))
Note the type hint for NodeList above isn't necessary, but improves performance.
Now you can use that function like so:
(map #(.getLocalName %) (node-list-seq your-node-list))
Use a for comprehension, these yield lazy sequences.
Here's the code for you. I've taken the time to make it runnable on the command line; you only need to replace the name of the parsed XML file.
Caveat 1: avoid def-ing your variables. Use local variables instead.
Caveat 2: this is the Java API for XML, so there objects are mutable; since you have a lazy sequence, if any changes happen to the mutable DOM tree while you're iterating, you might have unpleasant race changes.
Caveat 3: even though this is a lazy structure, the whole DOM tree is already in memory anyway (I'm not really sure about this last comment, though. I think the API tries to defer reading the tree in memory until needed, but, no guarantees). So if you run into trouble with big XML documents, try to avoid the DOM approach.
(require ['clojure.java.io :as 'io])
(import [javax.xml.parsers DocumentBuilderFactory])
(import [org.xml.sax InputSource])
(def dbf (DocumentBuilderFactory/newInstance))
(doto dbf
(.setValidating false)
(.setNamespaceAware true)
(.setIgnoringElementContentWhitespace true))
(def builder (.newDocumentBuilder dbf))
(def doc (.parse builder (InputSource. (io/reader "C:/workspace/myproject/pom.xml"))))
(defn lazy-child-list [element]
(let [nodelist (.getChildNodes element)
len (.getLength nodelist)]
(for [i (range len)]
(.item nodelist i))))
;; To print the children of an element
(-> doc
(.getDocumentElement)
(lazy-child-list)
(println))
;; Prints clojure.lang.LazySeq
(-> doc
(.getDocumentElement)
(lazy-child-list)
(class)
(println))

How are closures used in functional languages

For some reason, I tend to associate closures with functional languages. I believe this is mostly because the discussions I've seen concerning closures is almost always in an environment that is focused around functional programming. That being said, the actual practical uses of closures that I can think are are all non-functional in nature.
Are there practical uses of closures in functional languages, or is the association in my mind mostly because closures are used to program in a style that's also common to functional programming languages (first class functions, currying, etc)?
Edit: I should clarify that I refering to actual functional languages, meaning I was looking for uses that preserve referential transparency (for the same input you get the same output).
Edit: Adding a summary of what's been posted so far:
Closures are used to implement partial evaluation. Specifically, for a function that takes two arguments, it can be called with one argument which results in it returning a function that takes one argument. Generally, the method by which this second function "stores" the first value passed into it is a closure.
Objects can be implemented using closures. A function is returned that has closes around a number of variables, and can then use them like object attributes. The function itself may return more methods, which act as object methods, which also have access to these variables. Assuming the variables aren't modified, referential transparency is maintained.
I use lots of closures in Javascript code (which is a pretty functional language -- I joke that it is Scheme with C clothing). They provide encapsulation of data that is private to a function.
The most ubiquitous example:
var generateId = function() {
var id = 0;
return function() {
return id++;
}
}();
window.alert(generateId());
window.alert(generateId());
But that's the hello, world of Javascript closures. However there are many more practical uses.
Recently, in my job, I needed to code a simple photo gallery with sliders. It does something like:
var slide = function() {
var photoSize = ...
var ... // lots of calculations of sizes, distances to scroll, etc
var scroll = function(direction, amout) {
// here we use some of the variables defined just above
// (it will be returned, therefore it is a closure)
};
return {
up: function() { scroll(1, photoSize); },
down: function() { scroll(-1, photoSize); }
}
}();
slide.up();
// actually the line above would have to be associated to some
// event handler to be useful
In this case I've used closures to hide all the up and down scrolling logic, and have a code which is very semantic: in Javascript, "slide up" you will write slide.up().
One nice use for closures is building things like decision trees. You return a classify() function that tests whether to go down the left or right tree, and then calls either its leftClassify() or rightClassify() function depending on the input data. The leaf functions simply return a class label. I've actually implemented decision trees in Python and D this way before.
They're used for a lot of things. Take, for example, function composition:
let compose f g = fun x -> f (g x)
This returns a closure that uses the arguments from the function environment where it was created. Functional languages like OCaml and Haskell actually use closures implicitly all over the place. For example:
let flip f a b = f b a
Usually, this will be called as something like let minusOne = flip (-) 1 to create a function that will subtract 1 from its argument. This "partially applied" function is effectively the same as doing this:
let flip f a = fun b -> f b a
It returns a closure that remembers the two arguments you passed in and takes another argument of its own.
Closures can be used to simulate objects that can respond to messages and maintain their own local state. Here is a simple counter object in Scheme:
;; counter.ss
;; A simple counter that can respond to the messages
;; 'next and 'reset.
(define (create-counter start-from)
(let ((value start-from))
(lambda (message)
(case message
((next) (set! value (add1 value)) value)
((reset) (set! value start-from))
(else (error "Invalid message!"))))))
Sample usage:
> (load "counter.ss")
> (define count-from-5 (create-counter 5))
> (define count-from-0 (create-counter 0))
> (count-from-5 'next)
6
> (count-from-5 'next)
7
> (count-from-0 'next)
1
> (count-from-0 'next)
2
> (count-from-0 'reset)
> (count-from-0 'next)
1

Resources