Using vars lets you iterate on the impl functions without invalidating the 
proxy instances. I'm not sure if that was the reason, but that would be one 
advantage.

On Wednesday, January 15, 2020 at 10:46:36 AM UTC-6, Mike Rodriguez wrote:
>
> Do you have any idea about the reason that the Clojure implementation was 
> done this way - when it obviously seems a bit limited and also slower than 
> necessary? Just curious if there's some historical context.
>
> On Tuesday, January 14, 2020 at 11:58:17 AM UTC-5, Nathan Marz wrote:
>>
>> The speedup comes from proxy+ directly overriding methods with the 
>> provided implementation, while Clojure's proxy has additional indirection. 
>> For example, if you do (proxy [Object] [] (toString [] "hello")), the 
>> bytecode for toString is:
>>
>>   public java.lang.String toString();
>>
>>      0  aload_0 [this]
>>
>>      1  getfield user.proxy$java.lang.Object$ff19274a.__clojureFnMap : 
>> clojure.lang.IPersistentMap [16]
>>
>>      4  ldc <String "toString"> [52]
>>
>>      6  invokestatic clojure.lang.RT.get(java.lang.Object, 
>> java.lang.Object) : java.lang.Object [36]
>>
>>      9  dup
>>
>>     10  ifnull 28
>>
>>     13  checkcast clojure.lang.IFn [38]
>>
>>     16  aload_0 [this]
>>
>>     17  invokeinterface clojure.lang.IFn.invoke(java.lang.Object) : 
>> java.lang.Object [55] [nargs: 2]
>>
>>     22  checkcast java.lang.String [57]
>>
>>     25  goto 33
>>
>>     28  pop
>>
>>     29  aload_0 [this]
>>
>>     30  invokespecial java.lang.Object.toString() : java.lang.String [59]
>>
>>     33  areturn
>>
>> Clojure keeps the implementations in a map, and for every dispatch it 
>> does a map lookup by the method name. This is also why it can't handle 
>> overriding the same method name with different arities.
>>
>> For (proxy+ [] Object (toString [this] "hello")), the bytecode is:
>>
>>   public java.lang.String toString();
>>
>>      0  aload_0 [this]
>>
>>      1  getfield user.proxy_plus5358.toString5357 : clojure.lang.IFn [19]
>>
>>      4  aload_0 [this]
>>
>>      5  invokeinterface clojure.lang.IFn.invoke(java.lang.Object) : 
>> java.lang.Object [30] [nargs: 2]
>>
>>     10  checkcast java.lang.String [32]
>>
>>     13  areturn
>>
>> The implementation function is stored as a field, so the cost of dispatch 
>> is a field get rather than a map lookup.
>>
>> Clojure's proxy also overrides *every* available method in all 
>> superclasses/interfaces, while proxy+ only overrides what you specify. So 
>> proxy+ generates much smaller classes than proxy.
>>
>>
>> On Tuesday, January 14, 2020 at 10:30:32 AM UTC-5, Brent Millare wrote:
>>>
>>> I skimmed the code, I don't really understand how it makes it faster 
>>> over proxy. Is it the generated ASM is better? What's the in-a-nutshell 
>>> description of how it works?
>>>
>>> On Monday, January 13, 2020 at 1:28:46 PM UTC-5, Nathan Marz wrote:
>>>>
>>>> No differences in behavior except for API being like reify. It 
>>>> integrates with AOT and can be consumed just like any other class. No idea 
>>>> how it interacts with Graal.
>>>>
>>>> On Monday, January 13, 2020 at 12:29:35 PM UTC-5, John Newman wrote:
>>>>>
>>>>> Bravo 👏👏👏👏👏
>>>>>
>>>>> Are there any differences in behavior to be aware of? AOT, Graal, 
>>>>> consuming proxy+ classes from vanilla clojure classes?
>>>>>
>>>>> On Mon, Jan 13, 2020, 11:47 AM Nathan Marz <natha...@gmail.com> wrote:
>>>>>
>>>>>> proxy+ is a replacement for Clojure's proxy that's faster and more 
>>>>>> usable. proxy has a strange implementation where it overrides every 
>>>>>> possible method and uses a mutable field to store a map of string -> 
>>>>>> function for dispatching the methods. This causes it to be unable to 
>>>>>> handle 
>>>>>> methods with the same name but different arities.
>>>>>>
>>>>>> proxy+ fixes these issues with proxy. Usage is like reify, and it's 
>>>>>> up to 10x faster.
>>>>>>
>>>>>> *Repository: *https://github.com/redplanetlabs/proxy-plus
>>>>>>
>>>>>> -- 
>>>>>> 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
>>>>>> clo...@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 clo...@googlegroups.com.
>>>>>> To view this discussion on the web visit 
>>>>>> https://groups.google.com/d/msgid/clojure/6d9bf48a-c5b5-417a-9f66-aa494cc38346%40googlegroups.com
>>>>>>  
>>>>>> <https://groups.google.com/d/msgid/clojure/6d9bf48a-c5b5-417a-9f66-aa494cc38346%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>> .
>>>>>>
>>>>>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/58693a5a-6753-434e-a54b-d946c1c23b8c%40googlegroups.com.

Reply via email to