Hacker News new | ask | show | jobs
by MichaelGG 3625 days ago
The annoying part there is the repeated "|x| x.". Rust should have syntax to reference a method of an object, instead of having to write a wrapper. So it'd look like .map_err(???.to_string()).
4 comments

Groovy and Kotlin use the implicit "it" parameter for lambdas that take just one parameter, which is very convenient:

    listOf(1, 2, 3, 4).filter { it % 2 == 0 }
Scala allows underscores, and sequential underscores refer to the next element, so you can do e.g.

    list(1, 2, 3, 4).reduce(_ + _) == 10
Doesn't that make the parameter anonymous, though? Can you println that _ and see the value of the current element?
Use a function that prints then returns its parameter:

  list(1, 2, 3, 4).reduce{print(_) + _} == 10
Use it if you or your language hasn't defined such a function:

  list(1, 2, 3, 4).reduce{it:= _; println(it); it + _} == 10
In fact, any name for it will do.
Yeah, that's the tradeoff–gain the ability to work with multiple parameters but lose the ability to reuse a single one.
And Haskell uses operator sections: (==0) would be similar to { it == 0 }. Alas, the section syntax get a bit cumbersome when you want to compose two or more of them, like in this translation of your example:

    filter ((0==) . (%2)) [1, 2, 3, 4]
so does LiveScript
It does. This could have been written

    .map_err(ToString::to_string)
as well. Works just fine with methods.
Why can't it be written as:

    .map_err(to_string)
When using the lambda the type is inferred, so why should there be a need for the ToString?
It'd need syntax to distinguish from a local function called to_string. Anything less allows ambiguity and wouldn't be equivalent (like using type::method won't do auto-borrow). So it'd need to be "\to_string", "|to_string" or something. Ample opportunity for bikeshedding.

Functional style is hampered by excessive verbosity. (Non functional style is so verbose a bit of extra noise doesn't hurt _as much_.) Rust could use a lot more inference, custom operators[1], and so on. They seem to sort of agree, with auto-deref, auto-borrow, some type inference, but won't go all the way. I suppose being conservative can be defended -- can't go back without breaking code. Hopefully, in the future, the verbosity will annoy more people and there will be enough support to head in a more Haskell/ML direction. But they seem very opposed to it at the moment.

1: The rationale apparently being "someone might abuse it!" instead of "it makes good libraries even better". Parser combinators, UI toolkit code do great with custom operators. Require a method name (i.e. operator !!= as foo) if it's too great a concern. Can't save yourself from bad writers. Crippling yourself to avoid this seems like a poor tradeoff.

If `to_string` was a function that was imported into the local namespace, you could. But since it's a method, you can't; you need to provide the trait name.
If there's a function and a method named to_string the user would've to be explicit about which one he uses by adding a namespace, like ToString.

If there's only one to_string function or method, the compiler could just take this one.

To follow up on this slightly, it's not really that this is special syntax. It's that map_err takes a function as an argument, and this is how you refer to this method by name.
But that's actually longer. It does look a bit better though, maybe.
Yeah, it's not about saving characters to me, it's about clarity.
Actually, this suggestion does not even work. Writing trait::method is not equivalent to writing "|x|x.method()". The latter will use method lookup rules, the former requires the programmer to decide which impl. For instance, in the above example, if the type impl'd to_string, that would be the one used, not ToString's implementation. From what I can tell anyways: https://is.gd/E8pdWc

Edit: Also, auto-borrow does not seem to work with this syntax.

This is a common enough pattern that reducing the visual noise will increase clarity.

Yes, this is correct. It's what I was getting at in the other thread; this is choosing a method manually.
Rust does have such a syntax: map_err(ToString::to_string).
It's not the same though; it can resolve to different methods based on non-local code. It also doesn't do autoborrow.
The method whose to_string method you want to reference isn't in scope. You need a function that calls the method on the argument it's called with.

Why add a feature for this - worse syntax, if you can just use an anonymous function?

Rust is already not the simplest of languages, adding further syntax and features of questionable benefit won't make the language any simpler or easier to understand.

Because repeated "|x| x" is a common noise pattern.