Re: type hinting overloaded methods
Phillip Lord phillip.l...@newcastle.ac.uk writes: Mikera mike.r.anderson...@gmail.com writes: On Wednesday, 11 December 2013 14:50:36 UTC, Phillip Lord wrote: Macros that generate type hints can get pretty ugly. Yes, I notice that! I ran into the same problem with vectorz-clj The following pattern ended up working for me: the trick to to create a local symbol that you can tag (defmacro tag-symbol [tag form] (let [tagged-sym (vary-meta (gensym res) assoc :tag tag)] `(let [~tagged-sym ~form] ~tagged-sym))) Will try, thanks for the pointer! That is the strangest macro ever. It expands to something like (let [x y] x) yet still actually does something useful. My end solution looks like this: (defmacro with-types [spec body] Given a spec of the form [symbol [types]] evaluate body if and only the value of symbol is an instance? of one of types. The symbol is type-hinted to the type of the first of types to match. The main aim for this is to avoid reflective calls to overloaded methods in Java. So if we have an overloaded static method call: C.met(String) C.met(Double) C.met(Boolean) (with-types [val [String Double Boolean]] (C/met val) will call met without reflection, so long as val is one of String, Double or Boolean. If none of the types are matched, an IllegalArgumentException will be thrown. (let [hint-var# (first spec) types# (second spec)] (if (seq types#) (let [type# (first types#)] `(let [~hint-var# (tawny.util/tag-symbol ~type# ~hint-var#)] (if (instance? ~type# ~hint-var#) ~@body (with-types [~hint-var# ~(vec (rest types#))] ~@body `(throw (IllegalArgumentException. No types have been matched) Which works nicely and seems to compile down to code without reflection. Thanks again! Phil -- -- 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/groups/opt_out.
Re: type hinting overloaded methods
You can't really avoid the instance checks: the underlying mechanic is that the JVM needs to figure out somehow at runtime which overloaded method version to call, since all it knows at compile time is that it has an arbitrary Object. instance? is the simplest way to do this. There are some fancier ways (e.g. using reflection or invokedynamic) but your case doesn't have very complex dispatch requirements so instance? checks are almost certainly the best option. The good news is that instance? checks are extremely fast on the JVM so performance will still be great (certainly far better than if you used any kind of reflection) On Tuesday, 10 December 2013 10:25:48 UTC, Phillip Lord wrote: I want to type hint an overloaded Java method. I used to have a function like so (defn iri [name] (IRI/create name)) Where IRI.create is one of IRI.create(String) IRI.create(URL) IRI.create(File) Type hinting the return value of this is straight-forward, but the parameter is one of three types. The only way I seem to be able to get this to work is to do lots of instance? checks... (defn ^IRI iri [name] (cond (instance? String name) (IRI/create ^String name) (instance? java.net.URL name) (IRI/create ^java.net.URL name) (instance? java.io.File name) (IRI/create ^java.io.File name))) which is a lot longer and, well, just not very nice. I could make this neater with a macro -- something like... (with-types [String, URL, File] (IRI/create name)) which would expand into the cond form above. But the instance? checks seem not ideal. Is there a better solution? Phil -- -- 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/groups/opt_out.
Re: type hinting overloaded methods
Hi, Am Mittwoch, 11. Dezember 2013 14:27:01 UTC+1 schrieb Mikera: You can't really avoid the instance checks: the underlying mechanic is that the JVM needs to figure out somehow at runtime which overloaded method version to call, since all it knows at compile time is that it has an arbitrary Object. instance? is the simplest way to do this. There are some fancier ways (e.g. using reflection or invokedynamic) but your case doesn't have very complex dispatch requirements so instance? checks are almost certainly the best option. The good news is that instance? checks are extremely fast on the JVM so performance will still be great (certainly far better than if you used any kind of reflection) Implementing a clojure protocol will give you fast dispatch on the first argument's type. -billy. -- -- 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/groups/opt_out.
Re: type hinting overloaded methods
On Wednesday, 11 December 2013 13:37:24 UTC, Philipp Meier wrote: Hi, Am Mittwoch, 11. Dezember 2013 14:27:01 UTC+1 schrieb Mikera: You can't really avoid the instance checks: the underlying mechanic is that the JVM needs to figure out somehow at runtime which overloaded method version to call, since all it knows at compile time is that it has an arbitrary Object. instance? is the simplest way to do this. There are some fancier ways (e.g. using reflection or invokedynamic) but your case doesn't have very complex dispatch requirements so instance? checks are almost certainly the best option. The good news is that instance? checks are extremely fast on the JVM so performance will still be great (certainly far better than if you used any kind of reflection) Implementing a clojure protocol will give you fast dispatch on the first argument's type. Very true... it's a tradeoff: - protocols allow open extension (which doesn't appear to be needed here?) - instance? checks are even faster (although protocol dispatch is still pretty fast) - protocols have some other quirks (e.g. not allowing primitive arguments) In the case we have here (a small fixed number of types, no open dispatch required) I think I would prefer instance? checks (especially given a nice macro to remove the boilerplate). -- -- 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/groups/opt_out.
Re: type hinting overloaded methods
Mikera mike.r.anderson...@gmail.com writes: On Wednesday, 11 December 2013 13:37:24 UTC, Philipp Meier wrote: Implementing a clojure protocol will give you fast dispatch on the first argument's type. Very true... it's a tradeoff: - protocols allow open extension (which doesn't appear to be needed here?) - instance? checks are even faster (although protocol dispatch is still pretty fast) - protocols have some other quirks (e.g. not allowing primitive arguments) In the case we have here (a small fixed number of types, no open dispatch required) I think I would prefer instance? checks (especially given a nice macro to remove the boilerplate). Yeah, unfortunately I do need dispatch on primitive arguments, so protocols fail for me. I've been trying to get this to work as a macro, but am having problems with this. The instance? check is easy to do, but adding the type hint is much harder; I think that the ^macro expands at read time, so before the macro expands, so it's not possible to construct the type hint. I've tried to rewrite this with `with-meta' but can't get this to work either since I think the meta is being added to the value. My hope was to get something like this... (defn ^IRI iri [name] (with-type-hint [name [String java.net.URL java.io.File]] (IRI/create name))) Am I really the first person to get this problem? Phil -- -- 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/groups/opt_out.
Re: type hinting overloaded methods
On Wednesday, 11 December 2013 14:50:36 UTC, Phillip Lord wrote: Mikera mike.r.an...@gmail.com javascript: writes: On Wednesday, 11 December 2013 13:37:24 UTC, Philipp Meier wrote: Implementing a clojure protocol will give you fast dispatch on the first argument's type. Very true... it's a tradeoff: - protocols allow open extension (which doesn't appear to be needed here?) - instance? checks are even faster (although protocol dispatch is still pretty fast) - protocols have some other quirks (e.g. not allowing primitive arguments) In the case we have here (a small fixed number of types, no open dispatch required) I think I would prefer instance? checks (especially given a nice macro to remove the boilerplate). Yeah, unfortunately I do need dispatch on primitive arguments, so protocols fail for me. I've been trying to get this to work as a macro, but am having problems with this. The instance? check is easy to do, but adding the type hint is much harder; I think that the ^macro expands at read time, so before the macro expands, so it's not possible to construct the type hint. I've tried to rewrite this with `with-meta' but can't get this to work either since I think the meta is being added to the value. My hope was to get something like this... (defn ^IRI iri [name] (with-type-hint [name [String java.net.URL java.io.File]] (IRI/create name))) Am I really the first person to get this problem? Phil Macros that generate type hints can get pretty ugly. I ran into the same problem with vectorz-clj The following pattern ended up working for me: the trick to to create a local symbol that you can tag (defmacro tag-symbol [tag form] (let [tagged-sym (vary-meta (gensym res) assoc :tag tag)] `(let [~tagged-sym ~form] ~tagged-sym))) -- -- 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/groups/opt_out.
Re: type hinting overloaded methods
Mikera mike.r.anderson...@gmail.com writes: On Wednesday, 11 December 2013 14:50:36 UTC, Phillip Lord wrote: Macros that generate type hints can get pretty ugly. Yes, I notice that! I ran into the same problem with vectorz-clj The following pattern ended up working for me: the trick to to create a local symbol that you can tag (defmacro tag-symbol [tag form] (let [tagged-sym (vary-meta (gensym res) assoc :tag tag)] `(let [~tagged-sym ~form] ~tagged-sym))) Will try, thanks for the pointer! Phil -- -- 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/groups/opt_out.
type hinting overloaded methods
I want to type hint an overloaded Java method. I used to have a function like so (defn iri [name] (IRI/create name)) Where IRI.create is one of IRI.create(String) IRI.create(URL) IRI.create(File) Type hinting the return value of this is straight-forward, but the parameter is one of three types. The only way I seem to be able to get this to work is to do lots of instance? checks... (defn ^IRI iri [name] (cond (instance? String name) (IRI/create ^String name) (instance? java.net.URL name) (IRI/create ^java.net.URL name) (instance? java.io.File name) (IRI/create ^java.io.File name))) which is a lot longer and, well, just not very nice. I could make this neater with a macro -- something like... (with-types [String, URL, File] (IRI/create name)) which would expand into the cond form above. But the instance? checks seem not ideal. Is there a better solution? Phil -- -- 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/groups/opt_out.
Re: type hinting overloaded methods
On Tue, Dec 10, 2013 at 4:25 AM, Phillip Lord phillip.l...@newcastle.ac.ukwrote: (defn ^IRI iri [name] (cond (instance? String name) (IRI/create ^String name) (instance? java.net.URL name) (IRI/create ^java.net.URL name) (instance? java.io.File name) (IRI/create ^java.io.File name))) which is a lot longer and, well, just not very nice. I could make this neater with a macro -- something like... (with-types [String, URL, File] (IRI/create name)) which would expand into the cond form above. But the instance? checks seem not ideal. Is there a better solution? You could create and extend an IIriCreate protocol to String, URL, and File. I'd like to point out that Java doesn't provide a clean way to handle this either. -- -- 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/groups/opt_out.