empirical-soft / empirical-lang

A language for time-series analysis
https://www.empirical-soft.com/
Other
167 stars 13 forks source link

Interactions among generics, templates, and overloading #56

Open chrisaycock opened 4 years ago

chrisaycock commented 4 years ago

Empirical's new metaprogramming features don't work well with each other.

Specializations

Imagine a generic function:

func foo(a, b):
  return a + b
end

This allows an overload if the number of arguments is different:

func foo(a, b, c):
  return a + b + c
end

However, a specialization is not permitted because we don't recognize the types as being different:

func foo(a: Int64, b: Int64):
  return a * b
end

Overloaded templates

Consider a templated function:

func foo{T}(a: T, b: T):
  return a + b
end

Overloading the template parameters is not permitted because sema would need to choose the proper id before instantiating:

func foo{T, U}(a: T, b: U):
  return a * b
end

Similarly, overloading the function arguments is also not permitted because sema would need to instantiate both functions before selecting the overload:

func foo{T}(a: T, b: T, c: T):
  return a + b + c
end

Template on a generic function

This currently results in a seg fault:

func foo{x: Int64}(a, b):
  return a + b + x
end

Solutions

Specialized functions must be appended to the instances of a generic. If an overload fails (because the types aren't recognized as different since a generic type matches anything), then check for specialization (a generic def is being shadowed by a regular func def). Store the mangled name after appending the instance.

Overloaded template parameters require choosing the OverloadedId first, and then going through the TemplatedId logic.

There is no solution currently to overloaded function parameters in a template. The wrong answer is to instantiate both functions because the user could get a compile error on an unintended target. This is an open question currently.

As for a template on a generic, the template logic has to recognize that generic defs are different from function defs. Ie., don't assume that non-func is a data def.