logoalt Hacker News

skittertoday at 7:49 AM2 repliesview on HN

Although not part of the goal, it also mentions `!Destruct`/"must-move types", aka linear types: Instead of there always being a way to drop values without providing any arguments, if you wanna get rid of a value of a linear type you have to call a function that takes it by value.


Replies

simonasktoday at 8:31 AM

For context, the reason this would be really nice is that it would enable API designs that catch certain kinds of errors.

    let txn = create_transaction();
    // do something with the transaction
    txn.commit(); // consume the txn
Right now, you can't implement this API without choosing between either silently rolling back unless the user calls `commit()`, or panicking in the Drop impl for the transaction if the user didn't explicitly call either `commit()` or `rollback()`.

Your only current choice is to use closures, which are much less composable, because you need a variant for each flavor: infallible, fallible, async fallibe, etc.

    start_transaction_async(async || { /* ... */ TransactionResult::Commit });
    start_transaction_async_try(async || { /* ... */ Ok(TransactionResult::Commit });
Ick.

If instead the transaction is a must-move type, you would get a compiler error if you fail to call exactly one of either commit or rollback, and particularly you would be forced to consider what happens at every exit point (early-out via `?` no longer just forgets the transaction). Very nice.

show 1 reply
melodyogonnatoday at 9:05 AM

Linear types requires significant work to incorporate into the core built-in collections and types. I've been following the work on Mojo to enable Linear type support for built-in types and collections, I don't think Rust's language semantics will allow for the same level of integration (Rust is already stable).

show 2 replies