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 upFromLiteral #143
Conversation
This comment has been minimized.
This comment has been minimized.
mcpherrinm
commented
Jun 26, 2014
|
Using integer/float literals in a similar system may be useful for, eg, bigint libraries, or various integer-like types: Ones checking overflow, range-limited, etc. |
This comment has been minimized.
This comment has been minimized.
|
This works for strings, but it definitely doesn't work for vector literals. The |
This comment has been minimized.
This comment has been minimized.
|
This also should cover numeric literals, as @mcpherrinm suggested. For string literals, the proposed trait works. For vector literals, I think a trait needs to be designed that effectively does what the |
This comment has been minimized.
This comment has been minimized.
|
If we would push each element onto a collection, perhaps FromVectorLiteral could take an Iterator, consuming it? |
This comment has been minimized.
This comment has been minimized.
|
Please use markdown syntax, or else the RFC is not rendered nicely. This includes
which renders as
(This is particularly important for anything with |
XMPPwocky
added some commits
Jun 26, 2014
huonw
reviewed
Jun 27, 2014
|
|
||
| Before, this compiles: | ||
|
|
||
| ```let x = "Hello, world!".to_string();``` |
This comment has been minimized.
This comment has been minimized.
huonw
Jun 27, 2014
Member
The fences need to be on their own lines, i.e.
```
let x = "Hello, world!".to_string();
```
This comment has been minimized.
This comment has been minimized.
|
@XMPPwocky How is the compiler supposed to generate an iterator? That also doesn't allow for placement new. I think it has to look something like trait FromVectorLiteral<T> {
fn init(capacity: uint) -> Self;
fn push(x: T);
}with a vector literal expression that ends up being typed as something that conforms to this protocol evaluating to the equivalent of As written this still doesn't support placement new, but that could be added once we have the capability of doing placement new. |
This comment has been minimized.
This comment has been minimized.
|
@kballard That looks workable. Another possibility, which translates directly to placement new, would be a method taking a size and returning a mutable slice. Of course, this burdens collections that are not contiguous in memory with the task of constructing a buffer and moving out of it, but it would be zero-cost for Vec and other contiguously-laid-out collections. |
This comment has been minimized.
This comment has been minimized.
|
@XMPPwocky That approach is problematic when considering how to handle task failure in the middle of evaluating the vector literal. My general feeling is we should wait and see how |
chris-morgan
reviewed
Jun 27, 2014
| } | ||
| trait FromVectorLiteral<T> { | ||
| fn from_vector_literal(lit: &[T]) -> Self; |
This comment has been minimized.
This comment has been minimized.
chris-morgan
Jun 27, 2014
Member
Why &[T] and &'static str? Seems to me that either both should be 'static or neither.
This comment has been minimized.
This comment has been minimized.
|
I can imagine I also agree with @kballard that something like |
This comment has been minimized.
This comment has been minimized.
jsanders
commented
Jun 27, 2014
|
|
This comment has been minimized.
This comment has been minimized.
|
@kballard I think an underlying problem here is that fixed-size vectors can't have their length erased and then be moved out of (unless you go through Box and friends, thus incurring heap allocation for no good reason); I suspect FromVectorLiteral might want to be postponed until we have something like an "owning slice" (not Box, but something that could take a pointer and length of something on the stack and pass it down to other functions). Probably postponable to 1.0 at least, since vec! is sufficient for the most common case. FromStringLiteral shouldn't be quite as much of a pain conceptually, and the "meow".to_string() menace must be stopped. |
This comment has been minimized.
This comment has been minimized.
|
@XMPPwocky Even without their length being erased, you can't move out of a fixed-length vector multiple times. And even if you could, that's still the wrong approach, because it requires evaluating all the expressions before trying to construct the collection, which makes it impossible to use placement-new to construct the values inside the collection. |
This comment has been minimized.
This comment has been minimized.
|
Many |
This comment has been minimized.
This comment has been minimized.
|
As embarrassed as I am at the look of |
This comment has been minimized.
This comment has been minimized.
|
@bstrie: I'd prefer doing nothing to hardcoding String and Vec. It's awkward enough having Box hardcoded, and there's at least a reason for that. Having String/Vec special-cased would annoy the low-level folks (who aren't using std) and generally be impure. |
This comment has been minimized.
This comment has been minimized.
|
+1 to no hardcoding. |
This comment has been minimized.
This comment has been minimized.
|
The proper solution to moving in is |
This comment has been minimized.
This comment has been minimized.
bvssvni
commented
Jun 27, 2014
|
+1 |
This comment has been minimized.
This comment has been minimized.
|
@eddyb As kballard mentioned when I proposed that, it is not friendly with placement new. A Vec-like interface is really growing on me, since data structures that are not contiguous in memory would work flawlessly (as would placement new), and judicious inlining should add no cost to data structures that are contiguous. |
steveklabnik
reviewed
Jun 27, 2014
| ```rust | ||
| trait FromStringLiteral { | ||
| fn from_string_literal(lit: &'static str) -> Self; |
This comment has been minimized.
This comment has been minimized.
steveklabnik
Jun 27, 2014
Member
Not that this really matters in an RFC, but Rust style is four spaces, no tabs.
This comment has been minimized.
This comment has been minimized.
|
@XMPPwocky well, here's the perfect placement new interface: fn from_vector_literal<T, static N: uint>(f: impl FnOnce<(), [T, ..N]>) -> Self; |
This comment has been minimized.
This comment has been minimized.
Ape
commented
Jun 27, 2014
|
C++11 uniform initialization (with initialization lists and constructors) is really useful and one of the features that still make me prefer C++ over Rust. For example consider this simple example case: std::map<std::string, std::vector<int>> playerScores = {
{"Athos", {1, 4, 2}},
{"Porthos", {}},
{"Aramis", {9, 2}},
};What is currently the best way to define a similar data structure in Rust? Would it be nicer with this new RFC? |
This comment has been minimized.
This comment has been minimized.
|
With let player_scores: HashMap<String, Vec<int>> = box [
(box "Athos", box [1, 4, 2]),
(box "Porthos", box []),
(box "Aramis", box [9, 2])
];@Ape IIUC this RFC is similar, but without the explicit As an aside, I was originally quite hyped about |
kvark
reviewed
Jun 27, 2014
|
|
||
| # Summary | ||
|
|
||
| Create new traits, FromStringLiteral, FromVectorLiteral<T>. Types implementing these traits can be automatically constructed from literals automatically. Literals will effectively have their actual types inferred statically. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
If/when Rust has a more complex notion of phases (thought I once read @pcwalton saying he wanted to do something like in Racket) this would all need to be revised. But that is probably a long way off. Just something to keep in mind if this is post 1.0 either way. |
XMPPwocky
added some commits
Jun 27, 2014
This comment has been minimized.
This comment has been minimized.
|
Yes, this RFC would allow what eddyb mentioned. Note that Rust already supports the case of struct Foo {
x: [i32, ..4]
}
fn gimme_a_foo() -> Foo {
Foo {x: [1, 2, 3, 4]}
}It only works for arrays, though, because they are primitive types and have special syntax for it. This RFC extends this syntax to arbitrary types that opt-in to it. |
This comment has been minimized.
This comment has been minimized.
|
One thing that doesn’t appear to be covered in the RFC is how the compiler would infer the type of a string/vector literal. Would it fall back to One must also take into account what would happen in a case such as this: fn str_fn<S: Str>(s: S) { ... }
str_fn("hello world");Today, this works, but with the proposed change, even with a fallback to |
This comment has been minimized.
This comment has been minimized.
|
@P1start I don't think the reason the int/float fallbacks were removed applies here. If you get the wrong numeric type in a case where the true type cannot be inferred, this is unlikely to actually fail to compile; instead it will appear to work, until you get unexpected overflow behavior at runtime. If you get an &'static str and try to call .append, that will not compile; in fact, I believe that all methods shared between &'static str and String behave identically; the same applies to [T, ..N] and Vec. I think the second case could be soluble by enhancing inferrence to better support fallbacks with generics, but it is certainly a problem. |
This comment has been minimized.
This comment has been minimized.
|
int/float fallbacks were removed because numeric primitives have limitations that aren't reflected in the type system, namely the bounds of the type and the resulting overflow behavior. So getting the wrong numeric type can lead to unexpected overflow. It also de-emphasizes None of that applies to values constructible from string/vector literals, so our current behavior for those literals is perfectly fine as a default. |
huonw
reviewed
Jun 28, 2014
| fn from_string_literal(lit: &'static str) -> Self; | ||
| } | ||
| trait FromVectorLiteral<T> { |
This comment has been minimized.
This comment has been minimized.
huonw
Jun 28, 2014
Member
This should probably be called FromArrayLiteral. Rust uses the following names:
[T, .. n](fixed sized) array&[T]sliceVec<T>vector
This comment has been minimized.
This comment has been minimized.
|
This kind of thing is OK in Haskell, but in Rust I think we should stick to the property that things are what they look like, i.e. what looks like a literal isn't actually a call to a user-defined function. |
This comment has been minimized.
This comment has been minimized.
|
@glaebhoerl |
This comment has been minimized.
This comment has been minimized.
|
@eddyb: At that point why not just use a macro? It doesn't work for string literals, but for e.g. |
This comment has been minimized.
This comment has been minimized.
tailhook
commented
Jul 18, 2014
It would be very nice if python-style Decimal could be created like:
(i.e. without turning it into floating point first, and keeping precision) |
treeman
referenced this pull request
Jul 27, 2014
Closed
Add hashmap, hashset, treemap, and treeset macros #14726
This comment has been minimized.
This comment has been minimized.
|
Conversions and implicit conversions are in important ergonomic concern right now. We want to get the ergonomics here right without sacrificing Rust's other qualities like predictability. This proposal has some shortcomings that lead us to think that it alone is not the answer: it's limited to two use cases while there are potentially others, the signatures are probably not correct, interaction with the compiler is unspecified (these two traits appear to be lang items). In general we want to put more and careful thought into this subject before moving forward, and there are several major language changes in the pipeline with higher priority. Closing and postponing. |
XMPPwocky commentedJun 26, 2014
literally the best RFC related to literals.