I macro'd this out (macro's with type-hints are surprisingly tricky).

So, you end with this....

(with-types [val [String Double Boolean]]
    (C/met val)

Which calls C/met with the right thing without reflection (unless you
count "instance?").

The code is in tawny-owl.

https://github.com/phillord/tawny-owl/blob/master/src/tawny/util.clj

Phil

lvh <_...@lvh.io> writes:

> Hi Reid,
>
>
>> On May 21, 2016, at 11:44 PM, Reid McKenzie <m...@arrdem.com> wrote:
>> 
>> 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.
>
> Thanks! That confirms my suspicions. Unfortunately, I was hoping to solve this
> statically. Since some of these call sites are really only useful internally,
> I’ll deal with the multi-var version, because my library’s the only one to pay
> that cost.
>
>
> thanks!
> lvh
>
>> 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 <https://github.com/lvh/caesium> 
>> [2]: https://www.lvh.io/posts/nonce-misuse-resistance-101.html
>> <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
>> <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
>> <mailto:clojure+unsubscr...@googlegroups.com>.
>> For more options, visit https://groups.google.com/d/optout
>> <https://groups.google.com/d/optout>.

-- 
Phillip Lord,                           Phone: +44 (0) 191 208 7827
Lecturer in Bioinformatics,             Email: phillip.l...@newcastle.ac.uk
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
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