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

Implicit generics come back to bite you #2177

Closed
def- opened this issue Feb 20, 2015 · 6 comments
Closed

Implicit generics come back to bite you #2177

def- opened this issue Feb 20, 2015 · 6 comments

Comments

@def-
Copy link
Member

def- commented Feb 20, 2015

type Rational*[T] = tuple[num, den: T]
  ## a rational number, consisting of a numerator and denominator

proc toRational*[T](x: SomeInteger): Rational[T] =
  ## Convert some integer `x` to a rational number.
  result.num = x
  result.den = 1

assert toRational[int](5) == (5,1)
# assert toRational[int, int](5) == (5,1) # this works

Fails with:

Error: cannot instantiate: toRational[int]; got 1 type(s) but expected 2

If you leave away the [T] generics of Rational everywhere, then the [int] of x can be determined automatically. Can this be achieved while still using generic Rationals?

@Araq
Copy link
Member

Araq commented Feb 20, 2015

The compiler needs to become smarter and allow for both. That doesn't look too hard to do, implicit type parameters already have some anonymous flag iirc.

@zah zah self-assigned this Feb 22, 2015
@andreaferretti
Copy link
Collaborator

Why would toRational[int, int](5) ever work? What are those two ints bound to, given that there is only one generic parameter in toRational?

In any case, I have met a similar issue here. The linked issue is actually about a compiler crash, but when I try to make it generic I probably run into the same issue described here (see the second comment)

@andreaferretti
Copy link
Collaborator

Still open, and I still don't understand why toRational[int, int](5) works, given that toRational only has one generic parameter

@zah zah added the Generics label Jun 19, 2018
@zah
Copy link
Member

zah commented Jun 19, 2018

@andreaferretti, the second generic parameter is what gets bound to the SomeInteger type class. Each type class used in the signature introduces such implicit generic parameters. I think the best solution is to allow partial application of the generic parameters, but another reasonable option is support both "all explicit" and "all in total" as Araq has suggested.

@narimiran
Copy link
Member

proc toRational*[T](x: SomeInteger): Rational[T] =

Shouldn't this be either proc toRational*[T](x: T): Rational[T] = or if you want to restrict yourself to integers proc toRational*[T: SomeInteger](x: T): Rational[T] =?

The way it was originally written, toRational[float, int](5) would make float -> T, int -> SomeInteger.

Can this be closed?

@krux02
Copy link
Contributor

krux02 commented Feb 20, 2019

Everything works intentional, even though it might be a bit confusing at times. I am closing this, as this was a quesiton that got solved, and there isn't any activity left anymore..

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

No branches or pull requests

6 participants