Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upParameterize types over numerics / type level integers #1038
Comments
brson
referenced this issue
Apr 6, 2015
Closed
Allow types to be parameterized by integer (and bool) constant values. #884
quantheory
referenced this issue
Apr 14, 2015
Closed
Constants that depend on type parameters in generic code #1062
mdinger
referenced this issue
May 27, 2015
Open
IntoIterator should be implemented for [T; N] not just references #25725
This was referenced May 29, 2015
This comment has been minimized.
This comment has been minimized.
Binero
commented
Jun 24, 2015
|
Is there any update on this? |
This comment has been minimized.
This comment has been minimized.
|
Checking types which depend on constants which depend on types is a thorny issue, and I think that that's where we are at right now. See #1062. If we could work out how to use associated constants in generic code better, that would get us a lot closer to type-level numbers (or constants in general). |
This comment has been minimized.
This comment has been minimized.
burdges
commented
Jun 24, 2015
|
It's maybe worth signaling @edwinb and @david-christiansen here, although Idris itself takes a far more drastic solution. |
This comment has been minimized.
This comment has been minimized.
|
I would be interested if they have any comments. Rust has a couple of considerations that are different from some other languages that already have dependent types (including Idris):
|
This comment has been minimized.
This comment has been minimized.
yongqli
commented
Jun 25, 2015
|
I would love to see this as well. My particular use case would be implementing something like:
|
This comment has been minimized.
This comment has been minimized.
david-christiansen
commented
Jun 26, 2015
|
I'm saying this as someone who is merely an enthusiastic observer of Rust, having never actually used it. So please take it with a major grain of salt. I wouldn't think that Idris-style dependent types would work particularly well in a language that isn't designed for them from the get-go - especially not in a language with side effects! I would imagine that, instead of automatically promoting user-written functions to the type level, it would be better to have a sub-language of allowed operations on the numeric types. Then, you can use techniques like Presburger arithmetic solvers or SMT solvers that know how to solve equality constraints over these expressions that arise during type checking. @yav somewhat-recently extended GHC to support type checker plugins that can do whatever they want with equality constraints. He's used this to implement type-level naturals at https://github.com/yav/type-nat-solver - this is probably a better place to look than Idris. |
This comment has been minimized.
This comment has been minimized.
aepsil0n
commented
Jun 29, 2015
|
@david-christiansen There is still the idea to allow parametrization over values of more general types. So we may want to avoid doing too much special-casing that works for type-level numerics only. Maybe this is too ambitious altogether. But even if we do it for numerics using some specialized solver first, I'd prefer to keep it extensible, so that the option to move to something more general is available. |
This comment has been minimized.
This comment has been minimized.
edwinb
commented
Jun 29, 2015
|
I don't know how well this would work for Rust (my instinct is that This isn't even that different from what we do in Idris, in the sense It's also a bit like what happens in programs using the Idris effects There's probably a PhD or two in this if anyone fancies having a go :) On 29/06/2015 10:01, Eduard Bopp wrote:
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
I have been busy most of the last week, really the last few weeks, so I'll give a few belated responses now. (I'll spare you the full details, but the punchline is a car accident last week, in which I was luckily not injured.) I regret that I can't really connect my thoughts to Idris, since I haven't learned it all that well yet; however I hope that my experience with Haskell bridges the gap a bit. @yongqli I believe that #1062 would be a good start toward using constants this way. If it was accepted and implemented, you could use associated constants as a "workaround" until the dependent type situation improved. However, treating 3x3 matrices specially would require other changes to Rust. I am interested in some similar problems, like specialization for SIMD. (Operations on 2D/4D/8D vectors might be sped up relative to other sizes.) It's not clear how Rust will handle that kind of specialization. @david-christiansen I appreciate your input (and I hope I'm not too verbose in replying). I think that @aepsil0n has given a similar response to what I would have said. Even though Rust 1.0 has (mostly) stabilized the language, the relatively new and unstable I've gradually come around to @freebroccolo's point of view (as I understand it, which may not be very well). For backwards compatibility, the compiler presumably has to evaluate constant expressions as completely as possible (under our current understanding of "evaluation", i.e. where you can literally get some primitive value at the end). But past that, we need some kind of solver to deal with generic code, and we aren't very constrained by compatibility. It is possible, but not ideal, to build an SMT solver directly into the compiler without a detailed explanation. (The problem being that any "obvious" generalization of Rust's current arithmetic capability is probably undecidable, and in any case, the effect on compile times would be unpredictable in practice. For a systems language, of course, for most code a sufficiently dedicated/intelligent/experienced human should be able to tell whether it will compile, and roughly how it will scale, without knowing the gory details of the internals of a specific compiler. One awkward aspect in developing a new systems language is that we want the reference compiler to be excellent, while simultaneously wanting the language to be specified clearly enough that other compilers can arise and work well.) It's almost certainly better to do something like what @yav has done with GHC and allow plugins to deal with arithmetic during type-checking (though this may be a ways off for Rust, since we have only vaguely planned a stable API for syntax-phase plugins, and don't support type-checking-phase plugins yet at all). But if a particular representation and set of operations for type-nats can be defined at the plugin/library level, we can define types/traits in the standard library that provide a standard representation. At least in theory, this provides the opportunity for a decent standard solution for users like @yongqli and I, who have specific use cases that only need simple checks, while more advanced users can pick different plugins/solvers if for some reason the standard implementation fails on certain cases. @edwinb I'm thinking that that was mostly just an offhand comment, but I'm about to go back to school for an applied maths PhD, so maybe we should talk. Having been both a physicist-in-training (think Fortran 95) and the amateur developer of Rust's associated constant capability, I've certainly thought about imperative languages plus dependent types. =) Actually, something like Haskell's DataKinds might not be a bad approach. The difficulty seems to be that we already allow primitives (particularly |
This comment has been minimized.
This comment has been minimized.
aepsil0n
commented
Jun 30, 2015
|
@quantheory interesting, our background and interests seems to be very similar. i have actually been thinking a lot about applying more advanced type system features such as this or full dependent types to numerical simulation techniques. I'm mostly approaching this from a numerical fluid dynamics point of view. Rust's type system is not quite powerful enough to do too fancy things, but using Idris for this application domain appears to be out of the question for performance reasons (although that last statement probably requires some benchmarking). There are things like compile-time physical units (fairly straight-forward, once this feature is implemented) or efficient numerical solvers for certain kinds of equations that make use of information available compile-time for code generation. I'd love to talk about these things in more detail and share ideas at some point (perhaps independent of Rust). But, for now, just file this under motivation and use cases ;) |
This was referenced Jul 7, 2015
This comment has been minimized.
This comment has been minimized.
droundy
commented
Aug 21, 2015
|
I think it might be worth pointing out here that @paholg has already implemented signed Peano numbers at the type level in rust: http://paholg.com/doc/dimensioned/peano/index.html Personally, I'd love to have type-level numbers not so much for new features (since we can already implement them ourselves) but for good error messages and in order to be able to write generic code that works with arrays. I feel like comparison, equality and addition and subtraction would by themselves be sufficient for a whole lot of benefit, without danger of adding (much) to the complexity of a human understanding rust code, or the dangers of undecideable code. |
This comment has been minimized.
This comment has been minimized.
Yamakaky
commented
Aug 21, 2015
|
Wow, this crate is awesome! |
This comment has been minimized.
This comment has been minimized.
|
For floating-point numbers in types, @mrmonday started a discussion about it in the Idris community, which ended up as the issue idris-lang/Idris-dev#2609 where type unification in the presence of floating-point numbers allows you to prove Not having reflexive type equality might hurt rustc's type-handling performance, which is why I was against it, but it turns out that affects the type system itself, not just the implementation. |
This comment has been minimized.
This comment has been minimized.
mrmonday
commented
Sep 12, 2015
|
There's also some discussion of this over in the D forums, if anyone's interested: http://forum.dlang.org/thread/rvgslgwzvqwchpowhntg@forum.dlang.org. |
This comment has been minimized.
This comment has been minimized.
|
@eddyb honestly the thing with floats in the Idris issue shouldn't be surprising because they are just poorly behaved with respect to equality and algebraic properties. Personally, I think the only reasonable approach here is to use a proper (co)algebraic or topological encoding of real numbers and force the types/specifications to be approximate. Something like Abstract Stone Duality (see Baeur's Marshall and Taylor's slides) would probably be the way to go. This would probably make them less convenient to use but it would be better than doing something unsound with the type system. |
steveklabnik
changed the title
Parameterize types over numerics
Parameterize types over numerics / type level integers
Sep 24, 2015
This comment has been minimized.
This comment has been minimized.
|
Adding "type level integers" to the title because I can never find this RFC with search |
This comment has been minimized.
This comment has been minimized.
alexchandel
commented
Oct 22, 2015
|
If and when Rust adds syntax for dependent typing, including "type-level numbers", it should be very generic. The syntax should be compatible with the promotion of suitable datatypes and traits like Haskell's, although of course Idris's type-level values are much cleaner. Permitting only the pure, total subset of the language is suitable for this. |
glaebhoerl
referenced this issue
Dec 8, 2015
Closed
Add a `pod` language item and marker trait. #1387
This comment has been minimized.
This comment has been minimized.
dbrgn
commented
Feb 9, 2016
|
Is there anything that is being done in this area? I'm not well versed in the area of type systems, so I can't really judge the feasibility of this feature. But right now I see the following not-so-nice things in Rust:
Please point out the mistakes in my statements, if there are any :) |
This comment has been minimized.
This comment has been minimized.
KalitaAlexey
commented
May 1, 2016
•
|
What does prevent it from implementation? |
This comment has been minimized.
This comment has been minimized.
ERnsTL
commented
May 4, 2016
•
|
Just hit this issue the other day as well when I wanted to simply clone an |
This comment has been minimized.
This comment has been minimized.
Binero
commented
May 4, 2016
|
@ERnsTL It is implemented for arrays up to size 32 if I'm not mistaken. |
This comment has been minimized.
This comment has been minimized.
|
@ERnsTL as a hack, you can use |
This comment has been minimized.
This comment has been minimized.
|
@ticki I thought all |
This comment has been minimized.
This comment has been minimized.
|
Copy requires a Clone bound. |
This comment has been minimized.
This comment has been minimized.
|
@ticki Yes, but the compiler returns "implemented" without checking anything other than the contained type. |
This comment has been minimized.
This comment has been minimized.
|
Oh, cool. I thought that'd result in type unsafety. |
This comment has been minimized.
This comment has been minimized.
|
@ticki It does result in type unsafety, well, it results in ICEs anyway, especially around trait objects. I personally get around the issue by wrapping the array in another type, and implementing |
This comment has been minimized.
This comment has been minimized.
|
Here you go: #1657 It is a general solution to type-level values (Π-constructors). |
This comment has been minimized.
This comment has been minimized.
iqualfragile
commented
Nov 27, 2016
|
@pcwalton |
genbattle
referenced this issue
Dec 7, 2016
Open
Survey: Crates / libraries / tools you need / want #22
This comment has been minimized.
This comment has been minimized.
genbattle
commented
May 11, 2017
|
I'm consistently disappointed every three months when I come back to this RFC and it's still languishing in the backlog. This papercut makes it very painful to use fixed-length arrays with generics in Rust. |
This comment has been minimized.
This comment has been minimized.
ketsuban
commented
May 11, 2017
|
@genbattle The reason this RFC specifically is "languishing" is because the discussion has moved on as a result of @ticki's work none of which I understand a word of, and which to the best of my understanding appears to now be focused on this meta-RFC. (Should this RFC be closed as it addresses a subset of that one?) |
This comment has been minimized.
This comment has been minimized.
golddranks
commented
May 11, 2017
•
|
Here's a link to a more recent update on how the Language team thinks about the matter. https://internals.rust-lang.org/t/lang-team-minutes-const-generics/5090 I think of the RFCs @ketsuban linked, the first one is the relevant one, but it's pending on an update based on the discussion and the mentoring. |
This comment has been minimized.
This comment has been minimized.
genbattle
commented
May 11, 2017
|
I'm glad some updates have been provided, it's very reassuring to know that this issue is being worked on in the background (and that the name has changed slightly). I'll keep an eye out for further news on const generics, hopefully they land by the end of the year as planned! |
withoutboats
added
the
T-lang
label
May 13, 2017
This comment has been minimized.
This comment has been minimized.
|
See RFC #2000 |
This comment has been minimized.
This comment has been minimized.
|
RFC 2000 was accepted |
This comment has been minimized.
This comment has been minimized.
|
Closing in favor of #2424 and rust-lang/rust#44580. |
brson commentedApr 6, 2015
This is a postponement issue tracking postponed RFCs in the general area of "functions generic over a constant" or "generic constants" and so forth.
Example use cases for items parameterized by a constant:
[T; N]for anyNSmallVec<32>)Example use cases for generic constants:
const FOO<T> = SomeType { value: None::<T> };(const fncan also address this)Here is a list of relevant RFCs: