[Pre? RFC] Partial types and partial mutability

I must admit that initially, I wasn't very convinced by this thread but after reading the discussion, I quite like the proposal.

@VitWW I think you should gather all the comments and ideas and put them into a well-organized document. Here, it is more of a brain-storming session rather than a RFC. It feels very chaotic, which, I believe, can turn off a lot of people.

1 Like

The syntax is also unlike anything in the language. Bikeshedding, I would prefer enum variant types with the existing pattern syntax (or something like it).

enum E4 {A (i32), B(i32), C (i32), D(i32)}

fn do_ac(e: E4::A | E4::C) { /* .. */ }

As for partial borrows, I think the primary reason it hasn't already been addressed is because existing workarounds are sufficient (once you know about them [1]). So there isn't much incentive to extend the language.


  1. IMHO, the discoverability of these workarounds is quite poor, and causes the same kinds of questions to appear on URLO and SO. I don't know if that's enough to warrant an entire alien syntax, though. It doesn't feel like it. Worst case, the same amount of questions will continue to appear, but the answers will change from "use this workaround" to "use this language feature". ↩︎

2 Likes

Thanks for feedback!

Ok, lets make partiality looks more Rust-friendly:

  1. For Structs and Enum Types partiality is written ::{ /*fields */ } as "use" declaration
enum E4 {A (i32), B(i32), C (i32), D(i32)}
// for Enums
fn do_eac(e: E4::{A, C}) { /* .. */ } 

struct S4 {a : i32, b : i32, c : i32, d : i32}
// for Structs
fn do_sac(s: S4::{a, c}) { /* .. */ } 
  1. For Tuple Types use %lock( or lock) before field instead of unified syntax:
fn do_t23(t: (lock i32, lock &u32, f64, &f32)) { /* .. */ } 
// same as
fn do_t23(t: (i32, &u32, f64, &f32)::{2,3}) { /* .. */ } 
  1. For Partial Expression for Struct and Tuples use .{ /* fields*/ } syntax, which is similar with "get 1 field" s.x and Struct declaration "{}":
let ref_sxy = & s.{x, y};
// same as 
let ref_sxy : & S4::{x, y} = & s.{x, y};
  1. All not fully filed initialization for Structs are Partly Typed:
struct S4 {a : i32, b : i32, c : i32, d : i32}

let sac = S4{a : 5, c : 7}; 
    // sac : S4::{a, c}
  1. For Tuple Types initialization we could use %lock( or lock) before field instead of unified syntax:
let t23 = ( lock 2i32, lock & 8u32, 6.0f64, 7.0f32); 
    // t23 : (lock i32, lock &u32, f64, f32)
    // same as
    // t23 : (i32, &u32, f64, f32)::{2, 3}
  1. For partial mutability we also use .{ /* fields*/ } syntax:
let mut.{a} s = S4{a: 5, b: 7};
let refmut_sa = &mut.{a} s;

Is this look better now?

Thank you for support and understanding!

That is my goal.

From my point of view, main reason is not a minor change is needed for that.

And this Proposal is not only "how to add syntax", but it is also a road-map "how to implement into the language".

I've looked into the Rust source, and I agree, I was focused on Type changes, not to borrow changes needed for that. We need to add "Proxy Borrowing":

struct S4 {a : i32, b : i32, c : i32, d : i32}
let s = S4 {a : 5, b: 6, c: 7, d: 8};
    // s : S4

let r_sd = & s.{d};
    // r_sd : & S4::%{d}
    //
    // r_sd  ~ Link(s);
    // borrow-checker borrows ProxyLink(s.d)

let mut mr_sabc = &mut s.{a, b, c};
    // mr_sabc : &mut S4::%{a, b, c}
    //
    // mr_sabc  ~ mut Link(s);
    // borrow-checker: mut ProxyLink(s.a), mut ProxyLink(s.b), mut ProxyLink(s.c)

let rr_sbc = & mr_sabc.{b, c};
    // rr_sbc : && S4::%{b, c}
    //
    // rr_sbc  ~ Link(mr_sabc);
    // borrow-checker: ProxyLink(ProxyLink(s.b)), ProxyLink(ProxyLink(s.c))

let mut mrr_sa = &mut mr_sabc.{a};
    // mrr_sa : &&mut S4::%{a}
    //
    // mrr_sa  ~ mut Link(mr_sabc);
    // borrow-checker: mut ProxyLink(ProxyLink(s.a))

When we write a code for partial borrow, the link of object itself returns, but borrow-checker, borrows proxy of permitted fields only.

When we write a code for full (or partial) borrow of a partial borrowed reference, the link of object itself returns again, but borrow-checker, borrows proxy of proxy of permitted fields only.

This new mechanism of Proxy Borrowing is simple and universal.

I used this discussion to create new Pre-Proposal:

Partial Types (v3)

It is still missing Reference-level explanation.

Feedback is welcome!

2 Likes

I add "Reference-level explanation" to the proposal Partial Types (v3) and make it even more simpler!

Do you have any advise or question?

1 Like

This is ambiguous with closures. Closure with a typed function argument and top level struct constructor break in nightly · Issue #107461 · rust-lang/rust · GitHub happened when rustc added even a subset of it for diagnostics.

That's too bad! Maybe there's an unambiguous alternative that doesn't stray too much from existing pattern syntax in argument position.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.