basilisp icon indicating copy to clipboard operation
basilisp copied to clipboard

core proxy fn impl

Open ikappaki opened this issue 1 year ago • 1 comments

Hi,

could you please consider an attempt to implement the core proxy fn. It partially fixes #425 .

In addition to interfaces, the fn can implement/override fn of any python class (abstract or not), because classes in python can have method that throw the not-implemented exception or they are abstract.

There is an oddity when implementing the interfaces that basilisp demands method_arityN fn to be defined. We thus defined them as dummy nil fns.

Multiarity interface fns are defined as a single function with a case form that switches to the right arity based on the number of arguments supplied to the method.

I understand that a better implementation might be possible in pure python, but thought to give it a go in the lisp. Feel free to thoroughly scrutinize the implementation and suggest alternatives.

Thanks

ikappaki avatar Jan 16 '24 21:01 ikappaki

Hi @chrisrink10 ,

I've re-implemented the logic using let bindings, in which case the functions can be shared in the multi-arity setup, plus as you hinted there is no need to implemented my own switch fn, but can assign the multiarity fn directly to it which simplifies the logic a lot.

The new macro expansion for

(proxy [ITestProxySingleArg ITestProxyMultiVariadic] []
              (arg-simple [arg] arg)
              (multi-a
                ([] 0)
                ([one] one)
                ([one two three & more] [one two three more])))

now looks like

(basilisp.core/let
 [arg-simple_6493
  (basilisp.core/fn arg-simple [this arg] arg)
  _multi-a_arity0_6494
  (basilisp.core/fn _multi-a_arity0 [this] 0)
  _multi-a_arity2_6495
  (basilisp.core/fn _multi-a_arity2 [this one] one)
  _multi-a_arity_rest_6496
  (basilisp.core/fn
   _multi-a_arity_rest
   [this one two three & more]
   [one two three more])
  multi-a_6497
  (basilisp.core/fn
   multi-a
   ([this] (_multi-a_arity0_6494 this))
   ([this one] (_multi-a_arity2_6495 this one))
   ([this one two three & more]
    (basilisp.core/apply
     _multi-a_arity_rest_6496
     this
     one
     two
     three
     more)))]
 ((python/type
   "proxy--ITestProxySingleArg_6492"
   (python/tuple [ITestProxySingleArg ITestProxyMultiVariadic])
   (basilisp.core/lisp->py
    {"_multi_a_arity_rest" _multi-a_arity_rest_6496,
     "multi_a" multi-a_6497,
     "_multi_a_arity2" _multi-a_arity2_6495,
     "_multi_a_arity0" _multi-a_arity0_6494,
     "arg_simple" arg-simple_6493}))))

could you please have another look?

Thanks

ikappaki avatar Feb 12 '24 22:02 ikappaki

Closing this, as Chris prefers to handle it directly in the compiler

from @chrisrink10 in #895

I also have 2 practical concerns. First is that this relies on proxies, which are as yet unimplemented. I know you made an attempt to do so in Basilisp (as https://github.com/basilisp-lang/basilisp/pull/818), but it is my preference to actually do this work in the compiler using a special form since I don't prefer to spread the arity-mapping logic across core and the compiler (to the extent that is possible)

ikappaki avatar Aug 18 '24 21:08 ikappaki