Good question. The idea started as a 'nameless method' with the same signature as the proposed 'apply' method.
value.apply(function)
// Becomes
value.(function)
From that perspective it's easy to answer your question. The parentheses are a function call, calling a method without a name.
However, the more I think about it, I like the other perspective better, seeing it as being able to use any function after .
. In that case I read the parentheses as saying: This is an expression. As opposed to an identifier that must be a member.
value.member // Identifier that must exist in the type's namespace.
value.(expression) // Can be anything (with the correct type).
Your question was specifically about the parentheses. Do you find the closure expression variant, value.{...}
, more acceptable?
Would using a different marker to indicate that we're not specifying a member make a difference? For example:
values
.map {...}
.::Set.init
I have shown how it does fit the language, so I can say the same but the other way around. It all depends on which part you assign more weight to, the part that fits or the part that doesn't fit. That doesn't make it a circular argument. We just have different perspectives.
As I've shown, we don't have to redefine .
, because it already performs function application. That's why this fits so nicely (in my perspective).
As I said earlier, I do understand the concerns. I'm just wondering (honestly don't know) if they are valid, or that perhaps in practice it will not be a big problem. Note that the meaning of value.identifier
will not change at all.
Giving |> the same precedence as .
It was suggested that with compiler support |>
could be given the same precedence as .
, but I don't think that's a solution either. Then you run into different problems:
foo.f() |> bar.g() // Will not do what you'd expect
This will be a problem with any solution that involves an operator, so I feel that if we want to make chaining into free functions work nicely with the existing chaining syntax, we need to base it on the dot syntax. Be it some special syntax to be able to chain into free functions, or by adding an 'apply' method to every type.
I also think that this will not fix everything. It creates a nice bridge between chaining member functions and free functions, but there's probably still room for operators like |>
and <|
, etc.