magic icon indicating copy to clipboard operation
magic copied to clipboard

can't even farm out simple generic array ops

Open timsgardner opened this issue 7 years ago • 4 comments

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.

timsgardner avatar Apr 23 '17 22:04 timsgardner

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 
...

timsgardner avatar Apr 23 '17 23:04 timsgardner

There's two issues here:

  1. magic should support ClojureCLR's type-args form
  2. (the larger issue) method resolution is incomplete

#7 and #15 are related.

nasser avatar Apr 24 '17 02:04 nasser

microsoft method resolution docs: https://t.co/28l3FWWHnW

timsgardner avatar Apr 29 '17 20:04 timsgardner

Method resolution has improved with e16a644131a1ad2a9fc96e5d8e0232e74ef33b69, but generics still need work

nasser avatar Aug 18 '17 20:08 nasser