First of all, remember that Clojure usually assumes that the programmer is
right and the program is correct, especially when not doing so would incur
a performance penalty.

It's important to remember what we are doing here. The Clojure compiler
wants to emit the correct method call, and lets the Java runtime deal with
type errors. So the point of type inference and type hints is to select the
correct method.

In most (?) cases, the method name is known. This leaves only two potential
problems: unknown class, or, if the class is known and the method has
multiple definitions, unknown parameter types.

There is no inference at all in your two working examples, just the
assumption that the programmer is infaillible.

As to what Clojure infers: basically nothing. I don't think there is any
inference at all in the compiler; it simply trusts type hints and assumes
Object otherwise. It does *locally* respect Java interop return types, but
this is strictly local (remembe that the unit of compilation is essentially
a single function - if you don't type hint its return value, Clojure will
not try to do it for you).

I would personally solve your problem by isolating the interop call inside
a function:

(defn get-owl-equivalent-classes-action
  [^OWLDataFactory fact ^java.util.Set arg1 ^java.util.Set arg2]
  (.getOWLEquivalentClassesActions arg1 arg2))

If the factory is not shared/reused you could of course create it inside
the method.


On a related note, Clojure itself does not rely on type hints or type
inference for (Clojure) function calls, so the vast majority of Clojure
functions are not type hinted. I have no idea whether this is deliberate
(i.e. whether there would be a cost to doing it beside the man-hours it
would take). Maybe you could suggest that as an enhancement?

On Wednesday, 5 November 2014, Phillip Lord <phillip.l...@newcastle.ac.uk>
wrote:

>
> Ah, okay. I thought it might be this.
>
> Not that I don't trust you, though, but how do you know this? Is there a
> good way of finding out what clojure has infered or not? tools.analyzer?
> I'm thinking from a point of view of the developer trying to get his
> type hints sorted.
>
> Phil
>
> Nicola Mometto <brobro...@gmail.com <javascript:;>> writes:
>
> > The reason why that call doesn't require reflection is that
> > Collection.unmodifiableSet has no overloaded methods, it only takes a
> > Set so the compiler doesn't have to disambiguate between different
> > signatures.
> >
> > Phillip Lord writes:
> >
> >> Yes, I checked the code.
> >>
> >> (defn set
> >>   "Returns a set of the distinct elements of coll."
> >>   {:added "1.0"
> >>    :static true}
> >>   [coll] (clojure.lang.PersistentHashSet/create (seq coll)))
> >>
> >> And that was my first assumption. But if clojure doesn't know the return
> >> type, then why does this:
> >>
> >> (defn two []
> >>   (java.util.Collections/unmodifiableSet
> >>    (set [])))
> >>
> >> Not require reflection? Clojure should not know which method to call.
> >> Unless it is just because unmodifiableSet has an arity of one and it's
> >> the only arity of one, so it doesn't try to disambiguate.
> >>
> >> I guess even if set was type hinted (to IPersistentSet) it would still
> >> not work since, IPersistentSet is not assignable from java.util.Set.
> >>
> >> Phil
> >>
> >>
> >>
> >> Nicola Mometto <brobro...@gmail.com <javascript:;>> writes:
> >>
> >>> Actually `set` and a lot of other clojure.core functions are neither
> >>> inlineable nor have type hints.
> >>>
> >>> Phillip Lord writes:
> >>>
> >>>> I have a piece of code that looks like this
> >>>>
> >>>> (.getOWLEquivalentClassesAxiom
> >>>>       (owl-data-factory)
> >>>>       (set classlist)
> >>>>       (union-annotations classlist))
> >>>>
> >>>> The method signature is
> >>>>
> >>>> getOWLEquivalentClassesAxiom(Set,Set)
> >>>>
> >>>> On runing lein check I get
> >>>>
> >>>>
> >>>> Reflection warning, tawny/owl.clj:2219:6 - call to method
> >>>> getOWLEquivalentClassesAxiom on
> >>>> org.semanticweb.owlapi.model.OWLDataFactory can't be resolved
> (argument
> >>>> types: unknown, java.util.Set).
> >>>>
> >>>> which makes no sense. Surely, the return type of clojure.core/set is
> >>>> known to be java.util.Set? I have quite a few calls like this in my
> >>>> code, which is why I don't want to type hint the return of set
> >>>> individually.
> >>>>
> >>>> If I add a function like so:
> >>>>
> >>>> (defn ^java.util.Set hset [coll]
> >>>>   (set coll))
> >>>>
> >>>> and call like this:
> >>>>
> >>>> (.getOWLEquivalentClassesAxiom
> >>>>       (owl-data-factory)
> >>>>       (hset classlist)
> >>>>       (union-annotations classlist))
> >>>>
> >>>> The reflection warning goes away.
> >>>>
> >>>>
> >>>> I've tried to reproduce this with simpler cases, like so:
> >>>>
> >>>>
> >>>> (defn one []
> >>>>   (java.util.Collections/unmodifiableSet
> >>>>    (java.util.HashSet.)))
> >>>>
> >>>>
> >>>> (defn two []
> >>>>   (java.util.Collections/unmodifiableSet
> >>>>    (set [])))
> >>>>
> >>>> But both of these pass lein check just fine. Which suggests that
> clojure
> >>>> knows set returns a java.util.Set object.
> >>>>
> >>>> Now, given that I can't give a simple test case, I realise that it's
> >>>> hard for anyone to work out what is happening. But, worse, I don't
> know
> >>>> how to debug this at all. So, how I find out what clojure things the
> >>>> return type of a function is? Or probe any further why this is
> failing?
> >>>>
> >>>> Phil
> >>>
> >>> --
> >>
> >> --
> >> Phillip Lord,                           Phone: +44 (0) 191 222 7827
> >> Lecturer in Bioinformatics,             Email:
> phillip.l...@newcastle.ac.uk <javascript:;>
> >> School of Computing Science, http://homepages.cs.ncl.ac.uk/phillip.lord
> >> Room 914 Claremont Tower,               skype: russet_apples
> >> Newcastle University,                   twitter: phillord
> >> NE1 7RU
> >
> > --
>
> --
> Phillip Lord,                           Phone: +44 (0) 191 222 7827
> Lecturer in Bioinformatics,             Email:
> phillip.l...@newcastle.ac.uk <javascript:;>
> School of Computing Science,
> http://homepages.cs.ncl.ac.uk/phillip.lord
> Room 914 Claremont Tower,               skype: russet_apples
> Newcastle University,                   twitter: phillord
> NE1 7RU
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> <javascript:;>
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com <javascript:;>
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com <javascript:;>.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to