-
Notifications
You must be signed in to change notification settings - Fork 23
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
Attach routines to concepts #529
Comments
fwiw, we quite consistently use a similar style already to avoid polluting the global namespace, ie: type MyType = object
proc someHelper(T: type MyType, ...) = ... Canonical example here is proc hash(_: concept Hashable, ...): ... that said, the above syntaxes are fine too, writing this merely to highlight the similarity / option ;) |
Well the way the compiler would interpret it is more like var s = @[3, 2, 1]
s.sort(Comparable.cmp) I didn't consider that this could break the method call syntax for calls that take a concept type for the first parameter as above, at least for the cases where we can find such a So I'm not sure, either we break existing code that contains |
In the most recent version of my proposal I also removed the restriction to the first parameter as it works better without it. |
I don't agree. I think the "clarity" is already there in the existing code when you write Also, when you do attach procs to types my way then you can also clean up the whole scope override story that happens in generics but shouldn't. But that's a story for another day... |
What I meant to say was, it helps with clarity, with the current scoping rules. When you write That being said this isn't necessarily exclusive from #380 or dependent on the scoping rules. If it still has additional benefits, like binding to complex types, it might be useful. |
This was sitting in my Obsidian notes for a while so might have some issues.
Abstract
Allow declaring routines with an attached (atomic) concept/interface type that they implement for certain types.
Motivation
Kind of the same problem as #380: It's possible to have types in scope, but not their adjacent implementations of common interfaces like
$
orhash
. This causes problems for generic procs that need these implementations in scope in order to use them. Instead of making this a problem of scope, we could use the type system to link these implementations with atomic descriptions of these interfaces. Currently in the language this can be represented with the "atomic" concept types added in 1.6.In addition to this, there is the problem of concepts depending on specific routine names. This can cause problems when different concepts use the same name for different intended behavior. It would be nice to include disambiguating information at the declaration site for situations like these.
Description
Say we have a
Hashable
concept as above. Then, allow writing something like (syntax for this whole post is temporary):The conditions for this to compile are:
hash
) for some typeT
T
implementing the concept is a nominal type declared in the current scope/package, or is a type "containing" such a nominal type (i.e.ref T
,seq[T]
,Atomic[T]
,(int, T)
)proc hash[T: Nominal](x: seq[T])
Table[int | float, T]
,seq[T and Comparable]
,seq[T | U]
whereU
is another such nominal type are fine, butTable[int | T, string]
,seq[not T]
are notThis proc can be used like any other proc, with a few additional behaviors:
Then, when we do something like
Hashable.hash(x)
, thehash
overloads in the "namespace" ofHashable
are considered as well as the procs in scope to find a matching overload ofhash
forx
, with the procs in scope receiving priority (the syntax might be misleading for this though).How this is different from #380:
The compiler can even make use of this to simplify and expose certain builtin overloading mechanisms if we declare special concepts in
system
that the compiler recognizes. Use cases might be:items
andpairs
iterators=destroy
,=copy
,=sink
...), without the "scope" behaviordefault
if we needed itYes this is like traits/typeclasses in other languages. But the meat of the feature is still Nim's overloading. We don't need it for every place that we use overloads.
Examples
The text was updated successfully, but these errors were encountered: