You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
whendefined case1:
#[ BUG:D20210609T174202:here doesn't honor func]#typeFoo=conceptfuncbar(x: Self): Selfprocbar(a: int): int= (echo"asdf"; 1)
doAssertintisnotFoo# assert fails, but should succeed because bar has sideeffectswhendefined case2:
#[ BUG:D20210609T174206:here doesn't work with auto]#typeFoo=conceptprocbar(x: Self): Selfprocbar(a: int|float): auto= a
doAssertintisFoo# failswhendefined case3:
#[ BUG: D20210609T175144:here doesn't work with overloaded symbols]#typeFoo=conceptprocbar(x: Self): intprocbar(a: int|float): int=1procbar(a: string): int=1doAssertstringisFoo# failswhendefined case4:
#[ BUG: D20210609T180457:here doesn't generic constraints]#typeFoo=conceptprocbar[T: SomeInteger](x: Self, b: T): T
procbar[T: SomeInteger](x: string, b: T): T =discarddoAssertstringisFoo# failswhendefined case5:
#[ BUG:D20210609T182307:here doesn't work with var]#typeFoo=conceptprocbar(a: seq[Self])
procbar(a: varseq[string]) =discardechostringisFoo# prints true, should print falseprocfn(a: Foo) =bar(@[a])
echocompiles(fn("x")) # prints false as expected because '@[a]' is immutable, not 'var'whendefined case6:
#[ BUG: D20210609T183337:here doesn't work with static params]#typeFoo=conceptprocbar(a: Self, b: staticint) =discardprocbar(a: string, b: staticint) =discarddoAssertstringisFoo# failswhendefined case7:
#[ BUG: D20210609T183337:here doesn't work with static params]#typeFoo=conceptprocbar(a: Self, b: typedesc) =discardprocbar(a: string, b: typedesc) =discarddoAssertstringisFoo# failswhendefined case8:
#[ BUG: D20210609T190543:here doesn't work with called iterators (iterables)]#typeSummable=concepttemplatesum(a: iterable[Self]): int=discard# doesn't help# proc sum(a: iterable[Self]): int # doesn't helpiteratoriota(n: int): int= (for i in0..<n: yield i)
templatesum[T](a: iterable[T]): T =var ret: T
for ai in a: ret += ai
ret
doAssertsum(iota(3)) ==0+1+2templatesum2(a: Summable): untyped=sum(a) *2echosum2(iota(3)) # Error: attempting to call routine: 'iota'
not to mention all the other concept issues already reported:
Concepts
(currently 42 open issues)
Current Output
all those cases fail
Expected Output
those cases should pass
Possible Solution
{.enableif.}, which I implemented in #12048 (which i will rename as {.where.}) , was wrongly closed.
It doesn't have any of the problems of concepts (whether old style or new style), is more flexible and is a much simpler solution leveraging the compiler's existing expression evaluator; it's also the solution adopted by these:
In short, enableif is the obvious, simpler, more flexible approach and we should use it.
Note that we could even define concepts on top of enableif (enableif subsumes concepts): type Foo = concept x {.enableif: bar(x) is int.} on top of {.enableif.}, to allow the same syntax where needed, eg:
typeFoo=concept x {.enableif: bar(x) isint.}
procfn(a: Foo)
procfn(a: auto) {.enableif: bar(a) isint.}
procfn[T](a, b: auto, c: int, d: T) {.enableif: bar(a, b, T).} # not possible with concepts
But it doesn't, concepts allow for type variable inference (container of T; infer the T) and enableif doesn't. Rust has traits and Swift protocols, comparable to concepts. They have both where and concepts!
Example
sample of 8 bugs with new style concepts:
not to mention all the other concept issues already reported: Concepts (currently 42 open issues)
Current Output
all those cases fail
Expected Output
those cases should pass
Possible Solution
{.enableif.}
, which I implemented in #12048 (which i will rename as{.where.}
) , was wrongly closed.It doesn't have any of the problems of concepts (whether old style or new style), is more flexible and is a much simpler solution leveraging the compiler's existing expression evaluator; it's also the solution adopted by these:
__attribute__((enable_if ...))
where
), refs https://doc.rust-lang.org/std/keyword.where.html, see corresponding RFC that was written at the time when it was introduced: https://github.com/rust-lang/rfcs/blob/master/text/0135-where.md and PR: Where clauses for more expressive bounds rust-lang/rfcs#135where
, https://docs.swift.org/swift-book/LanguageGuide/Generics.html#:~:text=%7D-,Generic%20Where%20Clauses,defining%20a%20generic%20where%20clause.etc
In short, enableif is the obvious, simpler, more flexible approach and we should use it.
Note that we could even define concepts on top of enableif (enableif subsumes concepts):
type Foo = concept x {.enableif: bar(x) is int.}
on top of{.enableif.}
, to allow the same syntax where needed, eg:Additional Information
1.5.1 21f3b85
The text was updated successfully, but these errors were encountered: