You should be able to do this:

(defn f [a ^bytes b ^bytes c]
   (if (instance? ByteBuffer a)
     (.f binding ^ByteBuffer a b c)
     (.f binding ^bytes a b c)))


You have a bimorphic function and yes there isn't a way to express that 
with Clojure's calling convention and consequent hinting support. So 1) 
yes, 2) no but no promises there, 3) see above.

I don't have a Clojure instance handy, but this should compile to
1) load the a argument
2) check instanceof against the class ByteBuffer
3) branch to the appropriate instance invoke
4) load b, c, a, from the arguments (as Objects), checkcasting 
appropriately to get typed as hinted values on the stack
5) invoke (fully type qualified, no reflection).

On Saturday, May 21, 2016 at 4:57:43 PM UTC-5, lvh ‌ wrote:
>
> Hi, 
>
>
>
> I’m working on caesium[1], Clojure bindings for libsodium using jnr-ffi. 
> Up until recently, I was able to stick to byte arrays for all APIs; but 
> I’ve started writing new nonce-misuse resistant cryptosystems[2], so I need 
> to have some byte-level layout within a byte array. I’m using 
> java.nio.ByteBuffer to provide mutable byte array “views” on top of an 
> existing byte array. 
>
> The underlying C API takes (const) char *s. jnr-ffi understands how to 
> translate both byte[] and ByteBuffer to char *. Previously, I had functions 
> like: 
>
> (defn f 
>   [^bytes a ^bytes b ^bytes c] 
>   (.f binding a b c)) 
>
> All was well; no reflection. However, now `binding` has two signatures for 
> f:  [byte[] byte[] byte[]] and [ByteBuffer byte[] byte[]]. If I remove the 
> first ^byte annotation, everything works well, but this generates 
> reflection warnings. 
>
> 1. Does this reflection warning mean that there will be actual reflection 
> if the type is known at the call site? (I believe the answer is “yes”.) 
> 2. Does that change with AOT? 
> 3. Is there a way to keep the same fn name, e.g. have: 
>
> (defn f 
>   [a ^bytes b ^bytes c] 
>   (.f binding a b c)) 
>
> … without reflection, as long as all callers of f have the type of `a` 
> statically determined? Again, I’m assuming the answer here is “no”, because 
> this resolution is done locally. 
>
> I can solve this in a macro since the two definitions are identical except 
> for the type hint, but I’d first just like to check that I’m not missing 
> some of the finer points of Java interop/type hinting. Also, does this mean 
> that I necessarily have two fns with different names, one for each 
> signature? E.g.: 
>
> (defn f-bytes 
>   [^bytes a ^bytes b ^bytes c] 
>   (.f binding a b c)) 
>
> (defn f-bytebuffer 
>   [^java.nio.ByteBuffer a ^bytes b ^bytes c] 
>   (.f binding a b c)) 
>
> I know that having two overloads with the same arity doesn’t work, so I’m 
> guessing the answer is “no" there as well :-( 
>
>
> Thanks in advance! 
> lvh 
>
> [1]: https://github.com/lvh/caesium 
> [2]: https://www.lvh.io/posts/nonce-misuse-resistance-101.html

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