On Fri, Jun 5, 2009 at 5:26 PM, tsuraan<tsur...@gmail.com> wrote:
>
> I have a function to get the path out of a lucene searcher
> (documentation at
> http://lucene.apache.org/java/2_3_2/api/core/org/apache/lucene/search/IndexSearcher.html).
>  The searcher has a Reader, which has a Directory.  The Directory is
> abstract, but in my case I know that it's a FSDirectory, so I declare
> fsdir, and then use its getFile and getPath.  The actual code I'm
> using is:
>
> (defn searcher-path [ #^IndexSearcher searcher ]
>  (let [fsdir #^FSDirectory (.. searcher getIndexReader directory)
>        path  #^String (.. fsdir getFile getPath) ]
>    path))
>
> When I compile this with warn-on-reflection, I get that getField and
> getPath cannot be resolved.  Am I doing the hinting wrong somehow?  I
> do have imports in my file for IndexSearcher and FSDirectory, so I'm
> not sure what I'm missing.

I thought it might be fun to try out the new repl-utils expression-info fn on
this.

So first I had to recreate your 'import' line (you might consider including this
kind of detail next time you post a question):

  (import '(org.apache.lucene.search IndexSearcher)
          '(org.apache.lucene.store FSDirectory))

Then in order to use expression-info, I had to adjust your code to make it
a stand-alone expression that returns the value I care about.  Then I wrapped it
in a call to expression-info:

  (expression-info
    '(let [#^IndexSearcher searcher nil] ; replaced 'defn' with simple 'let'
       (let [fsdir #^FSDirectory (.. searcher getIndexReader directory)
             path  #^String (.. fsdir getFile getPath)]
         path)))

This just returns 'nil', which is what I'd expect since the reflection warning
already told us the compiler doesn't know the type.  So lets cut out the parts
producing the warning:

  (expression-info
    '(let [#^IndexSearcher searcher nil] ; replaced 'defn' with simple 'let'
       (let [fsdir #^FSDirectory (.. searcher getIndexReader directory)]
         fsdir)))

returns:

  {:class org.apache.lucene.store.Directory, :primitive? false}

Now this is interesting.  I thought we'd specifically told it fsdir was an
FSDirectory, but the complier seems to think it's just a Directory.  It appears
to be taking the actual return type of the directory() method over our type
hint.  I don't know if this is a feature or a bug, but perhaps we can be a bit
more insistent.  What happens if we type-hint the local directly instead of the
expression?

  (expression-info
    '(let [#^IndexSearcher searcher nil] ; replaced 'defn' with simple 'let'
       (let [#^FSDirectory fsdir (.. searcher getIndexReader directory)]
         fsdir)))

returns:

  {:class org.apache.lucene.store.FSDirectory, :primitive? false}

Well, that seems to have done it.  Using that style in the original expression,
we get:

  (defn searcher-path [#^IndexSearcher searcher]
    (let [#^FSDirectory fsdir (.. searcher getIndexReader directory)
          #^String      path  (.. fsdir getFile getPath)]
      path))

That compiles without reflection warnings.

Note also that hinting 'path' as 'String' doesn't really do any good when all we
do is return it:

  user=> (expression-info '(searcher-path nil))
  nil

If you want to promise that 'searcher-path' will always return a String so that
the compiler can make further type deductions based on that, you need to hint
the function itself:

  (defn #^String searcher-path [#^IndexSearcher searcher]
    (let [#^FSDirectory fsdir (.. searcher getIndexReader directory)]
      (.. fsdir getFile getPath)))

  user=> (expression-info '(searcher-path nil))
  {:class java.lang.String, :primitive? false}

--Chouser

--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to