Correct.
Act on doc::Annotation using CoreMap’s “get” method to obtain a List called, e.g., sentences.
Not quite. Let’s break it down.
// Java
document.get(...)
Here we call method get
of object document
which has type Annotation
in Java. In Julia we have a handle to such an object in doc.jann
and its type, again in our Julia application, is JAnnotation
(while Julia’s Annotation
is a wrapper around this handle). In other words:
struct Annotation # <-- this is a Julia wrapper
jann::JAnnotation # <-- this is the handle to Java object or type edu.stanford.nlp.pipeline.Annotation
# which we aliased in Julia as JAnnotation
end
So the basic call should be:
jcall(
doc.jann, # <-- handle to Java object
"get", # <-- method name
..., # return type, ignore for now,
(...), # argument types
... # actual arguments
)
Note, that get
is a method inherited from ArrayCoreMap
and is defined here. It has signature:
<VALUE> VALUE get(Class<? extends Key<VALUE>> key)
Whoa! Looks unreadable for non-Java people, right? Let’s further break it down:
<VALUE>
is a type parameter, similar to <typename VALUE>
in C++ templates or ... where VALUE
in Julia
VALUE
means that we return this exact type
Class<VALUE>
(I simplified a bit) means that get
takes a single argument of Java type Class<VALUE>
We pass SentencesAnnotation.class
to this get
which is a value of type Class<SentencesAnnotation>
. From it we can infer that VALUE
in this case is SentencesAnnotation
! Method signature thus is:
SentencesAnnotation get(Class<SentencesAnnotation> key)
It’s interesting to note that SentencesAnnotation
actually implements interface List<CoreMap>
which we see as a return type in Java code:
List<CoreMap> sentences = document.get(SentencesAnnotation.class)
Ok, we understood what it all means in Java, but how should it look like in Julia? It’s a bit more tricky question that boils down to:
- what signature this method has in JVM itself (because type parameters don’t actually exist after compilation)
- how to specify type of
Class<SentencesAnnotation>
since JavaCall doesn’t support generics too
To answer these questions I need to inspect JAnnotation
object that I can’t do right now. Would you mind running the following for me?
JavaCall.listmethods(doc.jann, "get")
And while I wait for the result of the previous code I will address your questions (3) and (4) (I hope previous explanation shed some light on questions (1) and (2)).
How to distinguish between document.get, sentence.get, etc in the jcall?
As simple as
jcall(jann, ...)
jcall(jsentence, ...)
# etc.
The first argument is always an object you call method on. Literally, obj.method(...)
is translated into jcall(jobj, "method", ...)
.
How to construct the jcall so that it accepts a List< CoreMap > in return?
It depends on the actual method signature in JVM. The tricky part is that what you see in Java code doesn’t always correspond one-to-one to what is really created in JVM. As I mentioned earlier, JVM knows nothing about type parameters, so definitely there’s no information about CoreMap
in there. Moreover, there may be nothing about List
in JVMs signature for that method, but instead any interface that extends List
or any class that implements it.
It’s not the easiest part of working with JVM. Fortunately, it’s actually rarely needed to dive so deep - as you will see soon, most of the time you just construct objects and call jcall
on clear method signature from Java docs.