It doesn’t, but I was arguing that object.method
syntax is useful for other reasons. Here are my reasons in support of such a syntax:
1. There are many instances when it is easier to read / write in the reverse order.
Consider
eigenvalues(laplacian(transitive_reduction(fill_from(A, edge_list))))
vs.
A.fill_from(edge_list).transitive_reduction().laplacian().eigenvalues()
The very existence of piping serves as a testament that there are instances where it is easier to put it in the reverse order, but while
fill_from(A,edge_list) |> transitive_reduction |> laplacian |> eigenvalues
works when the functions only take a single argument, it requires ugly and noisy syntax for anything else, for example
fill_from(A,edge_list) |> x -> connected_components(x, 3)
2. Helps with conceptual flow.
Perhaps this is something which can be developed in time, however if you have object x
and you want to pass it through a set of transformations which will eventually return some object y
, it seems intrinsically easier to start from something that exists rather than envisioning what object y
might be, what the last transformation you would apply would be, then the next-to-last, and so forth.
3. Provides a natural way to narrow scope and discover functionality via tab completion.
Would it be possible to come up with something such as A<ctrl+.>
(as you suggested) to expand a list of methods which take A
as a parameter? Sure. Would it be natural to use it this way? Not really, because you’re writing something (the object name) which isn’t actually in the position it would end up. The code would have to be flipped around and turned into function(A)
.
Part of the reason tab completion is so nice it that it is a completion. You are still writing the code the way you will eventually see it appear, if you get part way through but then realize you forgot the spelling of the method you want to call then you can tap tab and it will just fill out the rest, you can use partial names to reduce the number of suggested functions, etc. etc. If I was trying to get the connected components of a graph and I forgot if the function was connected_components
or conn_comp
, with code completion I would write A.conn
, realize I didn’t remember the spelling, and then just hit <tab>
and it would just fill out the rest. With your proposed method I guess I would have to type A<ctrl+.>
and then maybe an interface would appear where I could start narrowing down the choices? But the point is that this is a totally different order of typing, and I would have to had consciously made a decision to use the function suggestion tooling rather from the start.
I would like to flip the question around - what disadvantage does UFCS have? You don’t have to use it. It is simply syntactic sugar, it doesn’t make Julia more or less object oriented. If Julia had UFCS, would you be asking for it to be removed?