Live data from Hacker News

Announcing Rust 1.20

blog.rust-lang.org

101–110 of 277 posts

Re: Announcing Rust 1.20

#101

So are these associations (functions and constants) just using the object type as a name space? Or is there something more to it?

Only that they are members of a trait, so you can use it in Rust's generic programming (bounded polymorphism).

Re: Announcing Rust 1.20

#102

Earlier quoted context omitted.

> I am imagining a special way to construct cyclical structures where everything inside would have the same lifetime and be destructed at once. The simple way to do that would be to allocate an array, and use indices into the array rather than pointers/references. Doing it with pointers isn't so much harder in Rust than C as it is that Rust is making you deal with how hard it is to get this right , whereas in C the c…

But in my example this is not hard to get right in C. The tree is constructed (on the stack would be fine), then used for a while without mutating it, then freed all at once. The thing that makes this hard in rust is destructors. If there's a cycle between A and B, and you destruct A first, then B, then B's destructor would see a dangling reference to A. And vice versa if you destruct B first. But I don't need destru…

Since you want to use the C method, have you tried using raw pointers?

Re: Announcing Rust 1.20

#103
post #59

Earlier quoted context omitted.

You get something similar to with static methods and properties on class definitions. In plain ES2017-ish class syntax: class Test { static value = 1; static someStaticMethod = () => { return 5; } } console.log(Test.value) // 1 console.log(Test.someStaticMethod()) // 5 Edit: Sorry, this actually a Stage 3 TC39 feature. Not sure if you can use it with flowtype (I think you can), but you might be able to if you enable…

Yeah, either way it is objects. Traits feel so much more flexible though; and more natural a layer over JS object-orientedness. It also makes it a pain that there are some important semantics missing while using classes in JS. Someitmes Java feels much better.

The real problem is that ES classes map onto a paradigm of prototypal inheritance rather than traditional inheritance (as in Java). The discrepancies between the two cause a leaky abstraction, like how a class still has a prototype chain, for example.

Re: Announcing Rust 1.20

#104

So are these associations (functions and constants) just using the object type as a name space? Or is there something more to it?

It may be easier to see their significance when they're associated with a trait, rather than a struct.

For a simple example, imagine I've got a trait Number, and every implementation of Number is supposed to have a zero constant. Then I could let that constant be Number::ZERO, and refer to it as such in generic code, with each implementation of Number having a different value for Number::ZERO.

Re: Announcing Rust 1.20

#105
post #75

Earlier quoted context omitted.

Regarding traits: you can have Rc (by casting from Rc ), but not RefCell . The reason is that Rc is a pointer, so the size of Rc can be constant regardless of the size of the type implementing the trait. But if you actually want a weak reference inside a refcell (as opposed to the other way around), RefCell > should work fine. Also consider the Cell type, which has a more limited API than RefCell but zero overhead. R…

Arenas have more to do with the allocation pattern, they don't solve the cycle problem, right?

You're correct, that crate doesn't solve the cycle problem. There is a different way of doing arenas in Rust that does though.

What you do is you put all of your tree nodes in a big Vec and instead of referring to children and parents via pointers, you do so via indices. It's less convenient because you have to pass around a reference to your "arena" everywhere (the Vec or a slice of it), and it incurs bounds checks (pretty cheap though). But, it solves the problem in a way that is guaranteed safe.

Re: Announcing Rust 1.20

#106

Earlier quoted context omitted.

> I am imagining a special way to construct cyclical structures where everything inside would have the same lifetime and be destructed at once. The simple way to do that would be to allocate an array, and use indices into the array rather than pointers/references. Doing it with pointers isn't so much harder in Rust than C as it is that Rust is making you deal with how hard it is to get this right , whereas in C the c…

But in my example this is not hard to get right in C. The tree is constructed (on the stack would be fine), then used for a while without mutating it, then freed all at once. The thing that makes this hard in rust is destructors. If there's a cycle between A and B, and you destruct A first, then B, then B's destructor would see a dangling reference to A. And vice versa if you destruct B first. But I don't need destru…

> But I don't need destructors, or at least ones that can see these references, so it's frustrating.

If you bound it so that it only accepts Copy types, then you can know there are no destructors.

Re: Announcing Rust 1.20

#107

So are these associations (functions and constants) just using the object type as a name space? Or is there something more to it?

Only that they are members of a trait, so you can use it in Rust's generic programming (bounded polymorphism).

is bounded another word for ad-hoc? I always considered Rust's polymorphism implementation like Haskell's, and AFAIK they call it ad hoc polymorphism.

Re: Announcing Rust 1.20

#108

I've been having a little trouble using rust for a little project: I need a tree with uplinks (meaning there are cycles). I asked on IRC a couple times and I think what I need is a weak reference inside a refcell, but it's not very easy to make it work cleanly. For one thing, it doesn't look like refcell works well with traits (the nodes in the tree are traits, not plain structs). I'm a bit frustrated because this is…

Frankly, I'd just use unsafe pointers for the backrefs, and wrap the tree API up in a typesafe layer, and build on top of that.

RefCells seem to add unnecessary redundancy here. You'll take a hit for runtime borrow for every pointer chase up the tree. If walking from a leaf to the root is important, you don't want to add an extra compare/branch/set to every pointer chase. Turns a single memory read into a branch, a write, and two reads. Probably about 5x slower at least.

Re: Announcing Rust 1.20

#109

So are these associations (functions and constants) just using the object type as a name space? Or is there something more to it?

In the most basic sense you can view it like that. When combined with the typical behavior of traits it gets more interesting. Say you have some data:

    struct Foo;
Then we can make a trait, that defines an interface that we can give to data later:

    trait Bar {
        const BAR_CONSTANT: i32;
        fn some_function();
        fn some_method(self);
    }
Then we can actually implement that trait for our data:

    impl Bar for Foo {
        const BAR_CONSTANT: i32 = 42;
        fn some_function() {
            println!("foo's associated function, and the const is {}", Self::BAR_CONSTANT);
        }
        fn some_method(self) {
            println!("foo's method, and the const is still {}", Self::BAR_CONSTANT);
        }
    }
Then we can use it like so:

    Foo::some_function();  // foo's associated function, and the const is 42
    let foo = Foo;
    foo.some_method();  // foo's method, and the const is still 42
And now we can take it further. Imagine that you have another piece of data, `struct Qux`. Then you can do the same and `impl Bar for Qux`. And now you can write a generic function like so:

    fn bar_taker(something_that_impls_bar: T) {
        T::some_function();
        something_that_impls_bar.some_method();
        // And of course we can refer to T::BAR_CONSTANT in here as well.
    }
And call it like so:

    bar_taker(foo);
    bar_taker(qux);
AFAIK, the big deal with associated consts is specifically that it allows generic code like that to refer to different values on a per-type basis.

Here's all this code on the Rust interactive playground if you'd like to poke at it: https://play.rust-lang.org/?gist=60bd64e1b2f52bb91ed0b0cb428...

Re: Announcing Rust 1.20

#110
post #15
post #6

Earlier quoted context omitted.

You've misread the announcement; Rust has had associated functions since time immemorial. Associated consts aren't class variables, because constants can't vary (that's sort of the whole point of constants...). Rust also doesn't have classes in any recognizable sense (we can argue all day about whether Rust supports "OOP", but the separation of data and behavior into structs and impls respectively pretty thoroughly s…

>Associated consts aren't class variables, because constants can't vary That's why I wrote "limited version of". Rust's "associated constants" are a subset of C++'s class variables feature. Namely you can only have variables qualified "const" i.e. constants. >Rust also doesn't have classes in any recognizable sense What? If you have instantiatable abstract data types with associated methods you have a "class". Callin…

It's not though, AFAIK the x.foo() syntax is just sugar for

let a = Foo; Foo::bar(&a); // if bar takes &self

Plus, there is no concept of inheritance. I don't see how that meets any definition of OOP unless you make the definition so weak as to be meaningless.

Post reply on HN