Hacker News new | past | comments | ask | show | jobs | submit login

Yeah, both Rust and Go also use the method syntax to provide dynamic dispatch, and it's simpler for them since this dispatch is chosen (presumably vtable style) based on the privileged first operand.

However, I think using methods to provide infix syntax is a real mistake. For instance, if I want to make an infix operator which allows me to subtract mytype and yourtype, I can do the following:

    mytype - yourtype; // mytype.sub(yourtype)
However, the opposite requires me to add methods to yourtype:

    yourtype - mytype; // yourtype.sub(mytype)
Python gets around this by having 'r' versions of functions which get invoked if yourtype refuses to acknowledge my type. However Go and Rust could resolve which binary function to use statically, but they don't want to support overloading unless it's a method on the first object.



Infix operators are out of scope of my comment. I am only referring to method invocation syntax itself, x.a(y, z).b(v), being infix.


I misunderstood then. However, if you just meant that people prefer method syntax because method syntax is infix, then it seems to come full circle to asking why they like infix syntax for methods... Doesn't really matter - it is what it is.


Well, if you imagine some prefix method syntax -- let's say, foo[a](b, c, d) instead of a.foo(b, c, d) -- it misses out on one of the advantages, in that method chaining is easier to read. I mean this is a nice feature for function call syntax in general and the benefits of infix syntax is not specific to methods. This is one reason why some new languages make f(a, b, c) and a.f(b, c) produce the same AST. Anyway, I wanted to separate the effects of infix positioning of the method name from those of having distinguished syntax for method invocations, which with static dispatch still carries other advantages.


It won’t be dynamically dispatched in Rust unless it’s a trait object.


I think your point is to emphasize there is no additional cost to method syntax. I wasn't trying to imply there was, only that when you want dynamic dispatch, you can only get it from method syntax.

Another interesting asymmetry, which I think shows a weird favoritism for method syntax is that Rust allows both of these:

   object_of_type_A.foo()
   object_of_type_B.foo()
But not both of these:

   foo(object_of_type_A)
   foo(object_of_type_B)
Ignoring dynamic/static dispatch for the moment, you can overload if you use method syntax, but not if you use function syntax. For me, I would prefer the latter, but I think I'm clearly in the minority.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: