The problem is that I don't know what others know. Another problem is that I cannot explain everything — method cascading was taken as an axiom. And yet another is that talking too much about method cascading would be either misleading, since my feature differs in many critical aspects. Moreover, method cascading in its previous form has no sense in Rust: there is quite old proposal for it which resulted in cascade! macro which is rather unpopular and reuses weird ..
operator that's ambiguous with range syntax — I didn't wanted dragging all of that in this thread for being criticised again. Also, in the past I've tried to open discussion about a similar feature almost in the way as it "ought to be" and, honestly, the current thread feels more productive.
Prior art
The fluent interface pattern in the current Rust as well as in many other languages was probably the biggest source of inspiration and the attempt to improve it in Kotlin was influential as well. Then some criticisms of fluent interfaces and method chaining [1, 2, 3] were helpful in validating prototypes and establishing the further design direction — it seems that many people have an intuition that programming languages misses here an important part.
It's hard to say that a regular infix method notation that could be known from languages like R, Kotlin, Haskell and Scala contributed anything besides the fact that its shape can be readable enough and compose well with the rest of the code. This thread also seems to confirm importance of well-defined associativity which cascadable method call has.
Up to this date probably the most successful implementation of method cascading as a dedicated construct happened in Dart language — the general lack of a negative response about that feature was very motivating during writing this RFC. And their new formatting rules seems to provide a bit similar aesthetics.
Many other languages have something similar e.g. Smalltalk, Clojure, Pascal, Nim and there were proposals to add it to C#, Python, Swift, CoffeeScript and who knows to what else language missing in this list. Even Rust has it implemented in cascade! crate which people recommend to use [1, 2], moreover, the tap crate seems to be closely related here. That's enough to demonstrate the demand and how many use cases for cascading there could be.
What's also relevant, there was proposal to rename &mut
so it'll denote uniqueness instead of mutability and with that remove mut
annotations (this was named "mutpocalypse" by the community). And recently another proposal appeared to just relax missing mut
from hard error to suppressable warnings. That said, people really think that mutability isn't as useful concept as it's supposed to be — hopefully the current RFC will transform it into "shared state" and that will become an acceptable compromise for everyone.
Right, initially Copy
was derived for X
and the example was valid, but after some time I've reviewed it and for some reason removed that derive. This is good catch — fixed it.
Consider this pattern:
let mut x = ...;
if ... {
x y
}
x.z();
It's expected to be very common — exactly as mutating values with methods in if
expressions. An important point (which also seems to be missed by everyone ITT and I must figure out a proper way to clarify it) is that instead of x y
you won't be able to use x = x.y()
or x.y()
which mutates — compiler will complain about that because cascadable notation is more appropriate and must be always used for mutating. So, if x
here was propagated then it must be moved into cascadable y
call, but then x.z()
wouldn't be possible and that isn't really any useful behavior of the code — there's either mut
which is rather useless then cascade which steals values without an obvious reason, and a compiler error instead of what user most likely will expect.