magic
magic copied to clipboard
can't even farm out simple generic array ops
We should have a good intrinsic story for array operations, but it sounds like that might take a little while. An obvious stopgap until we can get that is to farm out the most basic array operations to a c# class that can at least preserve type information so we don't have to spastically box stuff:
using System;
namespace ArcadiaHacks
{
public static class ArrayHelper
{
public static T aget<T> (T[] arr, int i)
{
return arr[i];
}
public static T aset<T> (T[] arr, int i, T val)
{
arr[i] = val;
return val;
}
}
}
Even this innocuous class doesn't work well with magic, however:
(def float-ar (float-array 10))
(ArrayHelper/aget float-ar 0)
;; crashes unity!
(ArrayHelper/aget (type-args |System.Single|) float-ar 0)
;; returns 0.0: the correct behavior
(m/faster
(let [^|System.Single[]| float-ar float-ar]
(ArrayHelper/aget (type-args |System.Single|) float-ar 0)))
;; throws error
(m/faster
(let [^|System.Single[]| float-ar float-ar]
(ArrayHelper/aget float-ar 0)))
;; throws error
(m/faster
(let [^|System.Single[]| float-ar float-ar]
(ArrayHelper/aget float-ar (int 0))))
;; throws error
(m/faster
(let [^|System.Single[]| float-ar float-ar]
(ArrayHelper/aget (type-args |System.Single|) float-ar (int 0))))
;; throws error
Even if we find some other approach to arrays, these methods should work. If they don't, other stuff won't either.
It seems magic uses different syntax, but this doesn't work either:
(m/faster
(let [^|System.Single[]| float-ar float-ar]
(ArrayHelper/aget|[System.Single]| float-ar (int 0))))
;; throws error
changing to instance methods like so:
using System;
namespace ArcadiaHacks
{
public class ArrayHelper
{
public ArrayHelper ()
{
}
public T aget<T> (T[] arr, int i)
{
return arr[i];
}
public T aset<T> (T[] arr, int i, T val)
{
arr[i] = val;
return val;
}
}
}
also breaks:
(m/faster
(let [^|System.Single[]| float-ar float-ar
ah (ArrayHelper.)]
(.. ah (aget|[System.Single]| float-ar 0))))
;; throws error:
System.Exception: Could not find overload of instance method aget[System.Single] taking 2 arguments for type ArcadiaHacks.ArrayHelper while analyzing form (.. ah (aget[System.Single] float-ar 0))
at magic/analyzer/errors$fn__12525__12530.invokeStatic (System.Object , System.Object ) [0x00000] in <filename unknown>:0
at magic/analyzer/errors$fn__12525__12530.invoke (System.Object , System.Object ) [0x00000] in <filename unknown>:0
at clojure.lang.MultiFn.invoke (System.Object arg1, System.Object arg2) [0x00000] in <filename unknown>:0
at magic/analyzer/analyze_host_forms$analyze_generic_host_call__12668.invokeStatic (System.Object ) [0x00000] in <filename unknown>:0
at magic/analyzer/analyze_host_forms$analyze_generic_host_call__12668.invoke (System.Object ) [0x00000] in <filename unknown>:0
at magic/analyzer/analyze_host_forms$analyze_host_call__12700.invokeStatic (System.Object ) [0x00000] in <filename unknown>:0
at magic/analyzer/analyze_host_forms$analyze_host_call__12700.invoke
...
There's two issues here:
- magic should support ClojureCLR's
type-args
form - (the larger issue) method resolution is incomplete
#7 and #15 are related.
microsoft method resolution docs: https://t.co/28l3FWWHnW
Method resolution has improved with e16a644131a1ad2a9fc96e5d8e0232e74ef33b69, but generics still need work