Hacker News new | ask | show | jobs
by shaklee3 2457 days ago
I know how these things work in Rust, and I'm still failing to see your point. It's not at all as complicated as what you are saying given that you can find many blog articles that explain it succinctly in a couple paragraphs.

It's not at all helpful to say that there's something so complicated on these other languages that you can't possibly get the idea across without using them.

2 comments

Try doing any of this with variant and visit

    enum A { Foo{ x: i32, y: f32 }, Bar(B), Baz([u32; 4]), Moo(i32), Mooz(i32) }
    struct B { z: f32, w: (f64, f32) }

    let b = B { z: 42.0, ..}; // create a b with z == 42 and default w
    let B{ w: (first, _), .. } = b; // get B.w.0 field
    let a = A::Foo{ x: 42.0, ..};
    if let A::Bar(Bar { z, ..}) = a {
      // if a is an A::Bar, get b.z field of A::Bar(b)
    }
    if let A::Baz([0, 1, 2, 3]) = a {
      // if a is an A::Baz containing an array 
      // with value [0, 1, 2, 3]
    }
    match a {
        A::Moo(1..3 @ v) => {
           // if a is an A::Moo where x in A::Moo(x) is in range [0, 3) and put the value in the local v variable
        }
        A::Moo(x) | A::Mooz(x) => { 
           // Either A::Moo or A::mooz, gives you the value of x
        }
        // ERROR: I forgot to match some patterns
    }

    foo(b);

    fn foo(B{ z, ..}: B) -> f64 { 
      // get the z field of the first function argument
      z
    }
What in Rust are one liners, and can be used anywhere (let bindings, constructors, match, if-let, while-let, function arguments, ...) is a pain to write in C++ using `std::visit` and `std::variant`. The error messages of `std::visit` + `std::variant` are quite bad as well. And well, then there are also other fundamental problems with variant like `variant<int>` having two variants, `variant<int, int>` having 3 variants, but you can't reach the second `int`, etc.

You can translate all the code above to C++ to use std::visit + std::variant instead. I personally find that C++ is unusable for programming like this, and almost never use std::variant in C++ as a consequence, while I use ADTs in Rust all the time.

One difference is that std::variant is run-time dispatched and uses memory equal to the max of all the variants, while Rust's sum types could potentially be compile-time dispatched and memory optimized to the exact type being used through various code paths.