Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve overload resolution for generics and templates #346

Open
al6x opened this issue Feb 25, 2021 · 3 comments
Open

Improve overload resolution for generics and templates #346

al6x opened this issue Feb 25, 2021 · 3 comments

Comments

@al6x
Copy link

al6x commented Feb 25, 2021

When multiple routines match the call - Nim tries to find the proc with the best match.

It could be improved, explicit type should have priority over generic type and generic over untyped.

func somefn*(v: int) = discard
func somefn*[T: SomeInteger](v: T) = discard
func somefn*[T](v: T) = discard
template somefn*(v: untyped) = discard

With this improvement it would be possible to combine generic and non generic procs and templates. And it should be a cheap check and not slow down the compilation.

Example:

playground

import sugar, algorithm, sequtils

func sortBy*[T, C](list: openarray[T], op: (T) -> C): seq[T] = list.sortedByIt(op(it))
template sortBy*[T](list: openarray[T], key: untyped): seq[T] = list.sortedByIt(it.key)

let people = @[(name: "Sarah"), (name: "Jim")]
echo people.sortBy((v) => v.name)
echo people.sortBy(name)

Details about Overloading resolution in Manual.

@timotheecour
Copy link
Member

timotheecour commented Feb 28, 2021

I have a better proposal: untyped(expr), see timotheecour/Nim#630

let people = @[(name: "Sarah"), (name: "Jim")]
echo people.sortBy((v) => v.name)
echo people.sortBy(name) # CT error
echo people.sortBy(name.untyped) # ok

explicit is better than implicit when it comes to untyped, and avoids many issues, eg if name is actually typed (eg due to an import) but user intended it to be used as untyped.

name.untyped (or untyped(name)) avoids this ambiguity by making this explicit.

See also nim-lang/Nim#17196 which will reduce need for untyped, but both iterable[T] and untyped(expr) are useful and work well together.

@Araq
Copy link
Member

Araq commented Mar 1, 2021

We can easily do both, it's certainly bad that untyped matches as well as a generic T.

@al6x al6x changed the title Improve overload resolution for untyped in generics and templates Improve overload resolution for generics and templates Mar 23, 2021
@al6x
Copy link
Author

al6x commented Jun 7, 2021

One more use case, currently it's impossible to override find to accept proc, with this change it should work.

func find[T](list: openarray[T], check: (T) -> bool, start = 0): int =
  if start <= (list.len - 1):
    for i in start..(list.len - 1):
      if check(list[i]): return i
  -1

assert @[(name: "Jim")].find((u) => u.name == "Jim") == 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants