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

range is not a valid generic parameter type, while not range is #22878

Open
PhilippMDoerner opened this issue Oct 27, 2023 · 2 comments
Open

Comments

@PhilippMDoerner
Copy link
Contributor

PhilippMDoerner commented Oct 27, 2023

Description

Given how almost everything in nim can be used as a generic parameter type (e.g. distinct) I would have assumed that this also holds true for range to make a generic proc for any range type.

However, this is not possible.

proc isRange(r: range) = echo "is range" can not compile.

Thus this code-snippet can not compile:

proc isRange(r: range) = echo "is range"
let y: 1..10 = 5
y.isRange()

Nim Version

Nim Compiler Version 2.0.0 [Linux: amd64]
Compiled at 2023-08-01
Copyright (c) 2006-2023 by Andreas Rumpf

git hash: a488067
active boot switches: -d:release

Current Output

Error: invalid type: 'range' in this context: 'proc (r: range)' for proc

Expected Output

No compiler error

Possible Solution

I only have a temporary solution for anyone running into this:
You can use a concept (Thanks to ElegantBeef for the suggestion!)

type Range = concept r
  r is range
proc isRange(r: Range) = echo "is range"
let y: range[0..10] = 5
y.isRange()

Additional Information

I am not 100% certain if this is actually a bug or me not having deep enough an understanding of typeclasses etc.
I currently assume it is a bug, because inverse of range (not range) somehow does act as a valid generic parameter type.

proc isRange(r: not range) = echo "is not range"
let y = 5
y.isRange()

This further solidified my assumption that proc isRange(r: range) should be possible.

Also this may be related to #17423 ?
I don't fully understand it but very distantly the issue seems maybe similar enough?

@metagn
Copy link
Collaborator

metagn commented Oct 27, 2023

Works with [T: range](r: T). Likely range by itself is erroneously considered a concrete type and not lifted to implicit generic

@PhilippMDoerner
Copy link
Contributor Author

Sadly that is only a solution as long as you don't define a version of that with auto.

proc isRange[T: range](r: T) = echo "is range"
proc isRange(r: auto) = echo "is not range"
let y: 1..10 = 5
y.isRange()

This for example will run into

 Error: ambiguous call; both playground.isRange(r: T: range) [proc declared in /home/philipp/dev/playground/src/playground.nim(1, 6)] and playground.isRange(r: GenericParam) [proc declared in /home/philipp/dev/playground/src/playground.nim(2, 6)] match for: (range 1..10(int))

Same for

proc isRange[T: range](r: T) = echo "is range"
proc isRange[T](r: T) = echo "is not range"
let y: 1..10 = 5
y.isRange()

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

2 participants