Hi,
Thanks for the experience report. This kind of feedback is *really
helpful*.
1. Purity, or lack thereof.
The idea of purity by default is interesting. I am not sure whether it
makes sense or not, I guess that depends on experience. I have some
ideas around allowing local mutable state; it will require some type
system extensions to make it work well. This is very important for
parallelism as well (as you pointed out).
2. Mutable locals
I tend to agree that locals should be immutable by default. There is
this proposal: https://github.com/graydon/rust/issues/1273
3. Ownership of unique-ptr
I find that it's quite common to want to say "this is a pointer to a
heap box that is both uniquely owned, and will never change owner".
I think you can achieve this with an immutable field of unique type.
Also, I had a few instance where I wanted to work with unique pointers
in a bit more flexible way than just passing them to a function, but
I didn't want to copy or take ownership of them. E.g. in kd-tree
tracing you want to traverse the two sub-spaces in different orders
depending on which is closest to the ray origin, the rest of the code
is the same so it's nice to say something like:
let (near,far) = origin< splitter ? (node.left_tree, node.right_tree)
: (node.right_tree, node.left_tree);
You can do this with references. Something like:
if origin < splitter {
process(*node.left_tree, *node.right_tree);
} else {
process(*node.right_tree, *node.left_tree);
}
where |process| is defined |fn process(&&fst: tree, &&snd: tree) { ...
}| (actually the |&&| are the default for non-trivial types). It would
also be possible to permit such borrowing using |let|; the effect would
be that |node.left_tree| and |node.right_tree| are not accessible for
the remainder of the scope.
4. I got tripped up by the mandatory literal postfixes about a million
times. This may be just a habit thing.
I find I can remember signed vs unsigned but I always forget i32 or u32
etc. I've been thinking about suggesting something like what D does,
where the type of "x & 0xFF" would be u8, "x >> 16" would be u16, and u8
can be promoted to u32 and so forth (it only works with literals). It's
neat. On the other hand, I *really* appreciate knowing explicitly what
is happening, unlike in C and Java where things are implicitly promoted
and so forth. I particularly like keeping a strong division between
signed and unsigned.
5. Linear algebra looks really clunky without operator overloading. I
mean, look at this:
add(scale(n, dot(view_vec, n)*2f), view_vec)
I think there is general agreement on supporting operator overloading
for a limited set of operators, including the arithmetic operators, []
and so forth.
6. I seriously couldn't figure out how to use the pow function. No
amount of importing/using seemed to bring it into scope. :-/
Not sure what's going on here!
Overall, I found Rust to be quite enjoyable to work with, even though
I'm used to a higher level of tooling support (oh how I miss
intellisense). Look forward to seeing where it goes in the future!
Great to hear!
Niko
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev