Pre-RFC: Cascadable method call

Well, I'm terrible at explaining concepts, sorry for that. I assume readers here are familiar with modern features in programming languages and saying "method cascading like in Dart" would be sufficient introduction, or they'll just do their own research on that topic — it's very googleable and other people explained it much better than me. I think just becoming familiar with this would remove the need in guessing too much at once.

Probably I should have provide more links to make the feature better discoverable...

I'm also surprised that examples provided here are confusing and people asking for something simpler.

So, here's summary section from my pre-RFC that should make the mechanics behind the proposed syntax more obvious (also requires a lot of guessing but still that's the best summary I've been able to provide)

Summary

EDITED: @SkiFire13 found a mistake — now it's fixed.

Add cascadable method call syntax that performs operations like "move|copy|mutably borrow here => mutate => then result in if required" and basically allows to group mutations made in sequence at the same value with methods by that making them more explicit while isolated in a separate scope. Unlike with the traditional concept of method cascading, its usages will be imposed by the compiler as Rust's type system is apt to infer always appropriate places, while another substantial difference is that the syntax is much simpler — there's no symbol-operators whatsoever and it's rather reminiscent of either an infix method call or of a postfix operator:

// Dummy struct that provides methods for demonstration:
#[derive(Clone, Copy)]
struct X;
impl X {
    fn new() -> Self { Self {} }

    // Some cascadable signatures:
    fn foo(&mut self) {}
    fn bar(self) -> Self { self }
    fn baz(&mut self, _: i32) {}
    fn qux(self, _: i32, _: i32) -> Self { self }
    fn quux(&mut self, _: i32, _: i32) -> bool { true }
}

// Possible usages

let on_mut_ref = &mut X::new();
let on_mut_ref: &mut X = on_mut_ref foo bar baz (0) qux (1) quux (2,3) foo bar;
on_mut_ref foo bar baz (0) qux (1) quux (2, 3) foo bar;

let mut on_mut_val: X = X::new();
let mut on_mut_val: X = on_mut_val foo bar baz (0) qux (1) quux (2, 3) foo bar;
on_mut_val foo bar baz (0) qux (1) quux (2, 3) foo bar;

let on_val: X = X::new();
let on_val: X = (on_val) foo bar baz (0) qux (1) quux (2, 3) foo bar;
(on_val) foo bar baz (0) qux (1) quux (2, 3) foo bar;

let on_temp = X::new() foo bar baz (0) qux (1) quux (2, 3) foo bar;
let on_temp = (X {}) foo bar baz (0) qux (1) quux (2, 3) foo bar;

// Note: 
// - A heavy reliance on syntax highlighting is expected
// - Using a regular method call will result in compiler warning
// - Without `X:Copy` methods `bar` and `qux` would be unavailable `on_mut_ref`

This RFC also introduces annotation-like formatting for cascadable method calls that are spanned for multiple lines, where alignment of blocks may somehow distantly remind the same of markdown and configuration files:

// These structs provides a primitive eDSL for demonstration:
struct A;
struct B;
struct C;
impl A {
    fn begin() -> Self { Self {} }
    fn multiline(&mut self, _: B) {}
    fn multiline_multiarg(self, _: B, _: B) -> Self { self }
    fn finish(self) {}
}
fn function(b: B) -> B {
    b
}
impl B {
    fn new() -> Self { Self {} }
    fn oneline(&mut self, _: C) {}
}

// This formatting is impossible to break:
A::begin()
    multiline (          // <- "header"
    B::new()
        oneline (C {})
        oneline (C {})
        oneline (C {})
    , )                  // <- a closing "tag"
    multiline (
    function(B::new()
        oneline (C {})
    ) )
    multiline_multiarg (
    B::new()
        oneline (C {})
        oneline (C {}),
    function(B::new()
        oneline (C {})
        oneline (C {})
    )
        oneline (C {
            //inner block expanded
        } )
    , )
    .finish();

An important difference from regular method calls is that cascadable method calls aren't allowed after {} braces in order to preserve backwards compatibility of "scope followed by a function call" ambiguous expressions like if x {} y () — an extra parenteses like (if x {}) y (z) are required in such situations to make them available.




I've put a lot of effort into that and the motivation guide level explanation section contains 7 subsections with examples, explanations, real world use cases, etc. etc and it's so big that I don't remember any other RFC like that and I'm really anxious to post it all at once without being sure that people are ready for it.

Thank you for support. Probably I'll post it here but only by parts, since it's very large and complicated and that may cause a lot of chaos which I do not want. People may ask questions, I'll respond, and in this way we may also gain a valuable knowledge on how a complete newcommer will react to it without knowing enough context.

Already it's clear for me that for many people the syntax isn't as intuitive as I've expected and that it should have been introduced in quite a different way