Proposal: reflection for struct parameters

I was amazed how well the reflection API worked for building generic Python wrappers of Mojo structs. With the current reflection API, this already works well for types that have Scalar attributes. However, when building conversion methods for attributes such as InlineArray (or now: Array), I hit a wall, because I could not infer the type and size / length parameters without some nasty string parsing.

What would be of great help to me (and IMHO a great addition to the language), would be an addition to the reflection API that allows to infer the parameters of a type. An example for how this could look like:

def convert_from_python[T: ConvertibleFromPython](value: PythonObject) raises -> T:
   comptime if reflect[T].base_name == "Array":
      # Infer the parameters and call a specialized conversion function
      comptime for i in range(reflect[T].param_count):
         if reflect[T].param_names[i] == "length":
            comptime length = reflect[T].param[i]
            comptime for j in range(reflect[T].param_count):
               if reflect[T].param_names[i] == "T":
                  comptime Type = reflect[T].param[j]
                  return convert_to_array[Array[T, length]](value)
   
   # Now cover other types, too
   comptime if reflect[T].base_name == "SIMD":
      ...

I am certain there would be other good usecases as well.

What do people think about this? Are there alternative ways to achieve this already available?

This actually seems like a very useful thing to have.

Another thought I had: an alternative way of achieving this would be to change the overload resolution from favouring generic functions to favouring specific functions.

def do_something[T: Copyable](arg: T):
   pass

def do_something[T: Copyable, length: Int](arg: Array[T, length]):
   pass

var a: Array[Int] = [1, 2, 3]
do_something(a) # will call the first function. Calling the second function would resolve the issue I have

Though this would enable some cool stuff, it may be too dramatic of a change to be feasible. I am not sure.

This is definitely something we want to add to reflection - and is in our backlog :slight_smile:
Reflection is very much so still in its infancy so it has a while to go and a bunch of features we want to add, it just hasn’t been a priority for 1.0 as its not explicitly needed for anything ATM.

Post 1.0 release, we’ll likely have some more leeway to poke at adding support for this (and other reflection capabilities).