Miiao
October 4, 2022, 6:37pm
1
Rust already has associated functions and methods - why not to implement dissociated ones? The main idea of this topic is following syntax:
fn bar(_x: &str) {}
"foo".(bar)
=> bar("foo")
(*"foo).(bar)
=> bar(&*foo)
fn bar(_x: &str, _y: u8) {}
"foo".(bar, 1)
=> bar("foo", 1)
Our answer to functional programming’s |>
1 Like
I'll ask the obvious question (even though I know ambiguity is a problem): why not use normal method call syntax ("foo".bar()
)?
Miiao
October 4, 2022, 6:45pm
3
Because bar is not associated with str
As I understand, Rust will never see UFCS. And imho Rust doesn’t need UFCS. I think this syntax would be a nice addition tho.
Rust already have UFCS, although it's the opposite of what you're asking: it allows to call methods as if they were functions, instead of allowing functions to be called as if they were methods.
8573
October 4, 2022, 9:43pm
5
I think I've seen this called "UMCS", for "universal method call syntax".
Yoric
October 5, 2022, 3:21am
6
fn bar(_x: &str) {}
"foo".(bar)
=> bar("foo")
(*"foo).(bar)
=> bar(&*foo)
fn bar(_x: &str, _y: u8) {}
"foo".(bar, 1)
=> bar("foo", 1)
Rewriting this in a manner that I feel is a bit easier to parse for the human eye (or at least for my sleepy brain):
// Single argument
fn foo(_x: &str) {
// ...
}
"sna".(foo) // Alternate syntax for `foo("sna")`.
(*&foo).(sna) // Alternate syntax for `foo(&*sna)`
// Two arguments
fn bar(_x: &str, _y: u8) {
// ...
}
"sna".(bar, 1) // Alternate syntax for bar("sna", 1)
6 Likes
cmpute
October 5, 2022, 10:16pm
7
This syntax looks really unfamiliar to me, and I would definitely thought foo.(bar)
is foo(bar)
.
Why not just use a trait to make it a method?
trait Bar {
fn bar(self);
}
impl Bar for &str {
fn bar(self) {
unimplemented!()
}
}
"foo".bar();
1 Like
Miiao
October 6, 2022, 10:11am
8
Because
"foo".(bar)
is easier than
trait Bar {
fn bar(self);
}
impl Bar for &str {
fn bar(self) {
unimplemented!()
}
}
"foo".bar();
Dissociated functions should be an analogue of pipe operator from functional languages.
cmpute
October 6, 2022, 1:40pm
9
I understand your motivation, I think postfix macros (if supported in future) will be the best solution here, instead of introducing a new syntax
I'll be straightforward here. I don't like it, and there is no plausible way you'll change my mind here. The syntax is foreign, unclear, and seemingly without purpose. The rationale is unclear. I do not believe a beginner would have even the slightest chance of understanding what code like this would do.
4 Likes
Somehow similar:
use apply::Apply;
fn single_param(_x: &str) { /* ... */ }
"s".apply(single_param); // single_param("s")
// two arguments must be combined into tuple
fn tuple_param((_x, _y): (&str, u8)) { /* ... */ }
("s", 1).apply(tuple_param); // tuple_param(("s", 1))
Edit: or create Apply1
similar to Apply
:
trait Apply1<Res> {
fn apply1<P, F: FnOnce(Self, P) -> Res>(self, f: F, p: P) -> Res
where
Self: Sized,
{
f(self, p)
}
}
impl<T, Res> Apply1<Res> for T {
// use default definition
}
fn baz(_x: &str, _y: u8) { /* ... */ }
"s".apply1(baz, 1); // baz("s", 1)
system
Closed
January 4, 2023, 7:06pm
12
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.