On Wed, May 18, 2016 at 3:37 PM, Nicola Salmoria via swift-evolution < [email protected]> wrote:
> > > On Wed, May 18, 2016 at 10:27 PM, Tony Allevato <[email protected]> > wrote: > >> On Wed, May 18, 2016 at 1:00 PM Nicola Salmoria < >> [email protected]> wrote: >> >>> On Wed, May 18, 2016 at 8:03 PM, Tony Allevato <[email protected]> >>> wrote: >>> >>>> On Wed, May 18, 2016 at 10:02 AM Nicola Salmoria via swift-evolution < >>>> [email protected]> wrote: >>>> >>>>> > * What is your evaluation of the proposal? >>>>> >>>>> I'm generally in strong support, having long been a proponent of >>>>> removing >>>>> operators from protocols (the first occurrence was in this thread: >>>>> http://article.gmane.org/gmane.comp.lang.swift.evolution/7935) >>>>> >>>>> I have several comments about the details of the proposal, however. >>>>> >>>>> 1) At the beginning, in the "Proposed solution" section, the proposal >>>>> says >>>>> "This document does not propose that the current way of defining >>>>> operators >>>>> be removed or changed at this time. Rather, we describe an addition >>>>> that >>>>> specifically provides improvements for protocol operator requirements." >>>>> >>>>> Later, however, there is a "Deprecation of non-static protocol >>>>> operators" >>>>> section which suggest to do exactly that, and this is reiterated in the >>>>> "Impact on existing code" section. >>>>> >>>>> Since I think that the deprecation of global operator overloads is the >>>>> crucial point of the proposal, I assume that the former is an >>>>> oversight. >>>>> >>>> >>>> I could probably do a better job of clarifying the wording here. The >>>> proposal does *not* deprecate *all* global operator overloads. Global >>>> operators can still be implemented as they have been in Swift. So if you >>>> have a concrete type like `struct Matrix`, you can still define at the >>>> global level `func +(lhs: Matrix, rhs: Matrix) -> Matrix`. >>>> >>>> What's being deprecated is the current syntax used to define operator >>>> requirements inside protocols (by making the functions static) and the >>>> manner by which subtypes conform (ditto, through static methods instead of >>>> global functions). >>>> >>> >>> OK, I guess the unclear part is when you talk about "an addition that >>> specifically provides improvements for protocol operator requirements." >>> This is not just an addition; it's intended to completely replace the >>> protocol operator syntax. >>> >>>> >>>> >>>>> 2) The method signatures in the examples are not up to date with the >>>>> current >>>>> Swift 3 syntax. For example: >>>>> >>>>> protocol Equatable { >>>>> static func ==(lhs: Self, rhs: Self) -> Bool >>>>> } >>>>> >>>>> should be: >>>>> >>>>> protocol Equatable { >>>>> static func ==(_ lhs: Self, _ rhs: Self) -> Bool >>>>> } >>>>> >>>> >>>> Unless I'm mistaken, from looking at the Swift 3 branch of stdlib, the >>>> syntax changes don't appear to apply to operator functions. Since they are >>>> a special case that don't have argument labels, it wouldn't make sense to >>>> require them (or rather, the placeholders) here. >>>> >>> >>> I don't agree with this. >>> >>> Operators are called like this: >>> >>> x = y + z >>> >>> Of course it doesn't make sense to have parameter labels there. >>> >>> But the ones inside the protocol are not operators. They are methods, >>> and are called like methods. They happen to have funny names, but they are >>> still methods, and are called like this: >>> >>> x = T.+(y, z) >>> >>> In this case not only it makes sense for the parameters to have labels, >>> but making them behave differently from normal methods would be >>> inconsistent, and a step backwards from all the progress that has been made >>> in Swift 3 on that front. >>> >> >> What I'm saying is, if you look at the Swift 3 branch of stdlib, global >> operator functions still do not have argument labels. Picking one at >> random: >> https://github.com/apple/swift/blob/swift-3.0-branch/stdlib/public/core/String.swift#L329 >> >> If you're arguing that those functions should be forced to include `_` >> placeholders, that's fine, but it's not accurate to say that the way >> they're written in this proposal is a step backwards from all the progress >> made in Swift 3. It is *consistent* with the way global operator functions >> are currently declared in Swift 3. >> >> If it changes there, then it should change here as well. But they should >> be the same, and making that change for global operator functions is not >> part of the scope of this proposal. >> > > I'm not talking about the global operator functions; I'm talking about the > methods inside the protocol, which are methods and are called like methods; > they are not operators. > > Thanks for expressing this so clearly. I'm of the same feeling but fumbled the communication of it. On re-evaluation, I wonder if this proposal as it is would be a sufficiently large improvement. It's essentially permitting the use of characters reserved for operators in static method names, but it adds a set of somewhat inconsistent rules for how those functions are to be declared and called. As mentioned earlier, `T....(x, y)` looks rather unfortunate, and since automatic trampolines are out of scope, I wonder if what we have currently (naming static methods using words) is altogether that bad. Maybe we could just standardize those names and be done with it; on a cursory look, that seems to be Rust's approach. > > >> >> >> >>> >>> >>>> >>>> >>>>> 3) As has already been noted by many others, the suggested syntax for >>>>> prefix/postfix operators is overcomplicated. The proposal is: >>>>> >>>>> // These are deprecated, of course, but used here just to serve as an >>>>> // example. >>>>> static prefix func ++(_ value: inout Self) -> Self >>>>> static postfix func ++(_ value: inout Self) -> Self >>>>> >>>>> We don't need that. Since the 'operators' declared inside protocols are >>>>> effectively just normal methods (apart from their names), we just need >>>>> to >>>>> name the parameters accordingly: >>>>> >>>>> static func ++(prefix value: inout Self) -> Self >>>>> static func ++(postfix value: inout Self) -> Self >>>>> >>>>> 4) I don't agree with the request to limit to static methods for the >>>>> operator implementations. >>>>> I support this for symmetrical binary operators like +, but there are >>>>> other >>>>> operators like += that seem to work better with members. That is, the >>>>> proposed declaration: >>>>> >>>>> static func +=(_ lhs: inout Self, _ rhs: Self) >>>>> >>>>> is more similar to the global += operator definition, but is less >>>>> clear than: >>>>> >>>>> mutating func +=(_ rhs: Self) >>>>> >>>>> this is apparent also at the call site. With the proposed syntax, one >>>>> would >>>>> need to do: >>>>> >>>>> func +=<T: Foo>(_ lhs: inout T, _ rhs: T) { >>>>> T.+=(lhs, rhs) >>>>> } >>>>> >>>>> while with a member function this would read more naturally as: >>>>> >>>>> func +=<T: Foo>(_ lhs: inout T, _ rhs: T) { >>>>> lhs.+=(rhs) >>>>> } >>>>> >>>> >>>> I considered this, but eventually settled on "everything is static" for >>>> consistency. As you mention, there's a stronger argument to be made for >>>> assignment operators to have "left hand side is the receiver" semantics >>>> than there are for standard infix operators, but from a consistency point >>>> of view (and ease of learning), I think having everything static and the >>>> signatures of the static operators matching those of the global operators >>>> is preferable. >>>> >>> >>> I think this would better be left as a choice to the author of the >>> protocol. There doesn't seem to be any technical reason to place this >>> restriction. >>> >> >>> >>>> (Which is also why, as I mentioned in a previous reply, I would be open >>>> to dropping the prefix/postfix keyword and making it an argument label >>>> instead, in both contexts.) >>>> >>>> >>>>> >>>>> 5) the proposal mentions the open question of ambiguities between the >>>>> dot >>>>> syntax to access methods and operators whose name starts with a dot. >>>>> This seems to be a real issue: I don't think >>>>> >>>>> return T....(minimum, maximum) >>>>> >>>>> looks any good, even if the compiler was able to parse it. >>>>> >>>>> However, this just means that the methods used to implement operators >>>>> with >>>>> problematic names would need to use different names. Arguably, the only >>>>> cases where one would really want to use methods with operator names >>>>> is for >>>>> arithmetical operators. Custom operators like ... are better expressed >>>>> as >>>>> methods with more significant names. >>>>> >>>> >>>> If there is a strong case where an operator is better implemented as a >>>> global operator and a named method, this proposal still allows that, since >>>> it's not deprecating all global operator definitions. A protocol could >>>> certainly have a requirement that is a named method, and provide a global >>>> generic operator that calls it. >>>> >>>> >>>>> >>>>> 6) It seems somewhat arbitrary to restrict method names to match an >>>>> operator, nor to put requirements on the function signature. I'd say >>>>> there >>>>> are two cases, either the compiler can handle a method name that uses >>>>> special characters, or it can't. If it can't, matching an operator name >>>>> won't help. If it can, why put limits? There could be other creative >>>>> uses of >>>>> such names, which we would be ruling out for no particular reason. >>>>> This is >>>>> something that seems better left to the author of the protocol. >>>>> >>>> >>>> IMO, to reduce potential confusion, I would argue that a function whose >>>> name is the same as a defined operator should conform to the requirements >>>> (such as argument count) of that operator. It's certainly worth discussion, >>>> though! With that being said, it may be easier on users to "rule something >>>> out" now and open it up later if need be, rather than to leave it open for >>>> people to use and decide it needs to be closed later. >>>> >>> >>> This doesn't seem different to me from having multiple functions with >>> the same name and different signature, which Swift allows without problems. >>> Again, I think this is a choice that the author of the protocol should >>> make, and there doesn't seem to be any technical reason to require >>> otherwise. >>> >>> >>>> >>>> >>>>> 7) Automatic generation of trampoline functions is out of scope so I'm >>>>> not >>>>> going to talk much about it, I only want to mention that it would make >>>>> sense >>>>> to consider making such a feature as general as possible, instead of >>>>> focusing exclusively on operators. >>>>> >>>>> For example, think of the common mathematical functions like sin, cos, >>>>> etc. >>>>> It could make sense to give them the same treatment as operators, >>>>> declaring >>>>> them as part of the FloatingPoint protocol but preserving the global >>>>> functions too. >>>>> It might even make sense to be able to create trampolines not only from >>>>> global space to a type, but also from one type to another type, or >>>>> even for >>>>> all methods of a type (e.g. when boxing a value inside another type). >>>>> >>>>> > * Is the problem being addressed significant enough to warrant a >>>>> change to >>>>> Swift? >>>>> >>>>> Absolutely. The handling of operators in protocols has been one of the >>>>> worst >>>>> pain points in my use of Swift. >>>>> >>>>> > * Does this proposal fit well with the feel and direction of Swift? >>>>> >>>>> Yes; it significantly increases clarity and consistency. >>>>> >>>>> > * If you have used other languages or libraries with a similar >>>>> feature, >>>>> how do you feel that this proposal compares to those? >>>>> >>>>> I only have experience with C++ operator overloading, which is much >>>>> less >>>>> advanced. >>>>> >>>>> > * How much effort did you put into your review? A glance, a quick >>>>> reading, >>>>> or an in-depth study? >>>>> >>>>> An in-depth study of the proposal, and I read all the relevant threads >>>>> on >>>>> the mailing list. >>>>> >>>>> -- >>>>> Nicola >>>>> >>>>> >>>>> _______________________________________________ >>>>> swift-evolution mailing list >>>>> [email protected] >>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>> >>>> > > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution > >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
