Ah yes. I didn't consider that.

On Wednesday, January 15, 2020 at 12:31:13 PM UTC-5, Alex Miller wrote:
>
> 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/b9597e05-be8d-4213-a33c-acc90a17c4ad%40googlegroups.com.

Reply via email to