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

Reply via email to