Proxy vs. glue class

170 views
Skip to first unread message

Anvar Karimson

unread,
Apr 4, 2014, 3:58:58 AM4/4/14
to clo...@googlegroups.com
Hi,

I am trying to understand what the best course of action would be in the following scenario:

I have a Java base class that I need to extend. The class is fundamental to my application and will be running fairly hot compared to other bits of code in the application. Therefore I want it to execute as fast as possible. The way I see it there are two options;

1) Use proxy
2) Create a class in Java that provides the glue between Java and Clojure and removes the need for extending the base class in Clojure.

I would prefer to use option 1 but I am a little bit worried about the performance implications of doing so, especially adding a level of indirection by using map-lookup for accessing methods so I suspect I will have to go with option 2.

Any recommendations or alternatives?

Thanks!

Phillip Lord

unread,
Apr 4, 2014, 10:03:00 AM4/4/14
to clo...@googlegroups.com
Or Option 3, create a class in Clojure which extends the Java.

My suggestion, try number 1 which is easy, then performance test it.

Phil

Anvar Karimson

unread,
Apr 4, 2014, 10:17:25 AM4/4/14
to clo...@googlegroups.com
Is that via gen-class? I have to admit that I am not very familiar with gen-class, is it still possible to use the class from Clojure?

Yes, that is probably the most pragmatic choice, premature optimization and all that.

Phillip Lord

unread,
Apr 4, 2014, 11:43:20 AM4/4/14
to clo...@googlegroups.com

Yeah, gen-class is the thing. Proxy, well, proxies, but genclass
produces a statically compiled ahead of time class. It's a real Java
class, so yes, you can use it from Clojure like any other Java class.

Genclass is a little more painful than proxy, but probably a little less
painful than having a combined Java/Clojure build.

Phil

Anvar Karimson <an...@karimson.com> writes:

> Is that via gen-class? I have to admit that I am not very familiar with
> gen-class, is it still possible to use the class from Clojure?
>
> Yes, that is probably the most pragmatic choice, premature optimization and
> all that.
>
> On Friday, 4 April 2014 15:03:00 UTC+1, Phillip Lord wrote:
>>
>> Anvar Karimson <an...@karimson.com <javascript:>> writes:
>> > I am trying to understand what the best course of action would be in the
>> > following scenario:
>> >
>> > I have a Java base class that I need to extend. The class is fundamental
>> to
>> > my application and will be running fairly hot compared to other bits of
>> > code in the application. Therefore I want it to execute as fast as
>> > possible. The way I see it there are two options;
>> >
>> > 1) Use proxy
>> > 2) Create a class in Java that provides the glue between Java and
>> Clojure
>> > and removes the need for extending the base class in Clojure.
>> >
>> > I would prefer to use option 1 but I am a little bit worried about the
>> > performance implications of doing so, especially adding a level of
>> > indirection by using map-lookup for accessing methods so I suspect I
>> will
>> > have to go with option 2.
>> >
>> > Any recommendations or alternatives?
>>
>> Or Option 3, create a class in Clojure which extends the Java.
>>
>> My suggestion, try number 1 which is easy, then performance test it.
>>
>> Phil
>>

--
Phillip Lord, Phone: +44 (0) 191 222 7827
Lecturer in Bioinformatics, Email: philli...@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

Anvar Karimson

unread,
Apr 4, 2014, 11:47:36 AM4/4/14
to clo...@googlegroups.com
Ok, thanks! I will have a look!

Colin Fleming

unread,
Apr 4, 2014, 8:08:13 PM4/4/14
to clo...@googlegroups.com
FWIW, in Cursive, which is a big ball of mixed Clojure + Java, I've given up trying to use gen-class and have started using Java shims for everything. I like it a lot more than gen-class, which I always feel like I'm fighting. With the new Java->Clojure API in 1.6 (or the equivalent using RT.var() and friends for earlier versions) it's really not that hard, tool support is much better and IMO it's much cleaner. gen-class will always indirect method calls through a var but if you're worried about performance you can get the underlying function object with Java and call it directly, with the caveat that you then lose the ability to update it dynamically at the REPL.

I'd dearly love a deftype-style extend-type or similar which would allow base class extension. I know it's not encouraged in Clojure but one of Clojure's fundamental principles is exposing the host where it's pragmatic to do so, and both proxy and gen-class have some pretty serious warts for this purpose.


--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Mikera

unread,
Apr 5, 2014, 3:20:52 AM4/5/14
to clo...@googlegroups.com
On Saturday, 5 April 2014 08:08:13 UTC+8, Colin Fleming wrote:
FWIW, in Cursive, which is a big ball of mixed Clojure + Java, I've given up trying to use gen-class and have started using Java shims for everything. I like it a lot more than gen-class, which I always feel like I'm fighting. With the new Java->Clojure API in 1.6 (or the equivalent using RT.var() and friends for earlier versions) it's really not that hard, tool support is much better and IMO it's much cleaner. gen-class will always indirect method calls through a var but if you're worried about performance you can get the underlying function object with Java and call it directly, with the caveat that you then lose the ability to update it dynamically at the REPL.

I'd dearly love a deftype-style extend-type or similar which would allow base class extension. I know it's not encouraged in Clojure but one of Clojure's fundamental principles is exposing the host where it's pragmatic to do so, and both proxy and gen-class have some pretty serious warts for this purpose.

+LOTS for this. I have wanted to extend a Java abstract base class *many* times in Clojure. It's a real pain point, right now. Especially for interop with Java libraries that expect you to extend base classes in order to write plugins etc. Currently when this comes up I just forget about Clojure and write this stuff in Java.

IMHO extending reify to support abstract base classes as well as interfaces would be the simplest way to achieve this.

FWIW here's the (as yet unaddressed) issue I raised about this on JIRA: http://dev.clojure.org/jira/browse/CLJ-1255

Colin Fleming

unread,
Apr 5, 2014, 7:03:02 AM4/5/14
to clo...@googlegroups.com
Yeah, it's annoying, no doubt. I have a bunch of classes that do nothing but override a protected method with a public one so I can proxy without warnings, some that I have to use because I can't create a non-trivial constructor, and so forth.

Re: your proposal, I think I'd prefer to leave reify et al as they were now, and that continue to be the "encouraged" path. I prefer the idea of having a separate interop form (extend-type, or whatever) although I think it should be able to natively reify protocols etc. Such a form would get pretty complicated if you wanted to be able to do everything a Java class can (create arbitrary constructors or whatever), but a form that works like deftype but:

a) can extend a concrete class
b) allows me to call supertype methods, including protected ones
c) has the generated code inline in the method body (I'll delegate through a var if I want to)
d) can reify protocols directly
e) can optionally cause its namespace to be require'd in a static initialiser (so the class can be used in IoC containers etc)

would be fantastic. I don't think it's unreasonable to expect people to write some Java for more esoteric things (multiple constructors, non-public class access, non-Clojuresque fields, static methods etc), but simple class extension along the lines of the existing interop support doesn't seem like such a bad idea.


--

Phillip Lord

unread,
Apr 7, 2014, 7:04:23 AM4/7/14
to clo...@googlegroups.com
Mikera <mike.r.an...@gmail.com> writes:
> +LOTS for this. I have wanted to extend a Java abstract base class *many*
> times in Clojure. It's a real pain point, right now. Especially for interop
> with Java libraries that expect you to extend base classes in order to
> write plugins etc. Currently when this comes up I just forget about Clojure
> and write this stuff in Java.

Having said that I would use proxies, actually, I think you have a
point. The last time I wanted to build a plugin, I did it in Java and
invoked clojure from within that.

In that case, I needed a two part build anyway. The plugin uses OSGI,
and came with a sample mvn script. So, in the end, I build the plugin in
Java and pull in the clojure as a maven dependencies, with a tiny bit of
glue to make launch leiningen.

Phil
Reply all
Reply to author
Forward
0 new messages