<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">After careful consideration, I am not sure this sort of thing is actually a change that would *actually* be an obvious improvement.</div><div class=""><br class=""></div><div class=""># First Concern: Code-Organization/Ownership Issues</div><div class=""><br class=""></div><div class="">Although it is easy to see how to handle operators that have *homogenous* types — e.g. anything like `func +(lhs: T, rhs: T) -> T` — it’s really unclear how a proposal like this *should* work for operators that have *heterogeneous* types — e.g. anything like `func *(lhs: T, rhs: U) -> U ` (etc.).</div><div class=""><br class=""></div><div class="">Since we’re talking about operators, this isn’t really a hypothetical concern, either:</div><div class=""><br class=""></div><div class="">## Example: Vector/Matrix Operations</div><div class=""><br class=""></div><div class="">func *(lhs: Matrix4x4, rhs: Vector4) -> Vector4 </div><div class="">func *(lhs: Vector4, rhs: Matrix4x4) -> Vector4</div><div class=""><br class=""></div><div class="">Both operations are reasonable to define, but defining the operator as instance methods seems to leave you in a rather awkward spot:</div><div class=""><br class=""></div><div class="">- perhaps one is implemented by `Matrix4x4` and the other by `Vector4` (really odd code organization imho…)</div><div class="">- perhaps both are implemented by, say, `Matrix4x4`, but one of them is using nonstandard syntax (defeating the point of custom operators, imho)</div><div class="">- perhaps the proposal lets an operator-function declaration indicate *which* argument is `self` (new syntax/new semantics)</div><div class=""><br class=""></div><div class="">…whereas the “operators are static functions” approach makes it reasonable to have both versions defined at the same scope (and e.g. "near each other”).</div><div class=""><br class=""></div><div class="">I know the specific proposal here wouldn’t eliminate the ability to define the operators as currently, but it’d be a shame to be unable to include things like the above method in protocols.</div><div class=""><br class=""></div><div class="">## Example: Scalar/Vector Operations</div><div class=""><br class=""></div><div class="">Similarly, at a more-basic level, you might *want* this:</div><div class=""><br class=""></div><div class="">protocol VectorType : Equatable {</div><div class=""> typealias Component : NumericType // if it existed</div><div class=""><br class=""></div><div class=""> // to match convention, scalars go *in front* of vectors</div><div class=""> operator *(lhs: Int, rhs: Self) -> Self </div><div class=""> operator *(lhs: Self.Component, rhs: Self) -> Self </div><div class=""><br class=""></div><div class=""> // but why should we not be flexible on this point?</div><div class=""> operator *(lhs: Self, rhs: Int) -> Self </div><div class=""> operator *(lhs: Self, rhs: Self.Component) -> Self </div><div class="">}</div><div class=""><br class=""></div><div class="">…and are we going to make `struct Vector4`’s conformance to `VectorType` contingent on the presence of extension methods on `Int` (etc.)?</div><div class=""><br class=""></div><div class="">That just seems really unintuitive and counterproductive.</div><div class=""><br class=""></div><div class=""># Second Concern: Dynamic Operator Dispatch Not Really Necessary</div><div class=""><br class=""></div><div class="">What I mean is, in the use cases that come to mind for dynamic operator-dispatch. making operators dynamically-dispatched wouldnt’ actually provide any benefit over what you can achieve today with protocols.</div><div class=""><br class=""></div><div class="">EG, for `==`, consider a protocol and operators like below:</div><div class=""><br class=""></div><div class="">protocol DynamicEquatable : class {</div><div class=""> func isEqual(other: Self) -> Bool</div><div class="">}</div><div class=""><br class=""></div><div class="">func ==<T:DynamicEquatable>(lhs: T, rhs: T) -> Bool {</div><div class=""> return (lhs === rhs) || lhs.isEqual(rhs)</div><div class="">}</div><div class=""><br class=""></div><div class=""><div class="">func !=<T:DynamicEquatable>(lhs: T, rhs: T) -> Bool {</div><div class=""> return (lhs !== rhs) && !lhs.isEqual(rhs)</div><div class="">}</div></div><div class=""><br class=""></div><div class="">…which as far as I can tell gets you back to the same place you’d be if you had a dynamically-dispatched `==` (both in terms of *what it would do* and also *what issues it would still have*).</div><div class=""><br class=""></div><div class="">Is there some (beneficial?) aspect of making `==` dynamically-dispatched that isn’t also present in the above design?</div><div class=""><br class=""></div><div class="">Are there operators for which there would be a material difference between the operator being dynamically-dispatched and the operator being defined over a protocol that has a dynamically-dispatched method providing the implementation?</div><div class=""><br class=""></div><div class=""># Remark</div><div class=""><br class=""></div><div class="">For `==` in particular, you could *maybe* improve the above slightly if Swift had a way to write a where clause like `U:>T` — meaning “U is a subclass of T, but not T itself” — as then you could add variants like:</div><div class=""><br class=""></div><div class="">func ==<T:DynamicEquatable,U:DynamicEquatable where T:>U>(lhs: T, rhs: U) -> Bool {</div><div class=""> return (lhs === rhs) || lhs.isEqual(rhs)</div><div class="">}</div><div class=""><br class=""></div><div class=""><div class="">func ==<T:DynamicEquatable,U:DynamicEquatable where U:>T>(lhs: T, rhs: U) -> Bool {</div><div class=""> return (lhs === rhs) || rhs.isEqual(lhs)</div><div class="">}</div></div><div class=""><br class=""></div><div class="">…which would hopefully make a direct call into the more-derived type’s implementation of `isEqual`, which would be more-likely to contain a fast path, but even so it’s not obvious that there’s all that much of an actual win to be had here, in practice.</div><div class=""><br class=""></div><div><blockquote type="cite" class=""><div class="">On Feb 25, 2016, at 1:59 PM, Vanderlei Martinelli via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hello.<div class=""><br class=""></div><div class="">The proposal can be also read at <a href="https://gist.github.com/vmartinelli/67d6ad234c7a4e14f8d5" class="">https://gist.github.com/vmartinelli/67d6ad234c7a4e14f8d5</a></div><div class=""><br class=""></div><div class="">Original thread: <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160125/008508.html" class="">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160125/008508.html</a></div><div class=""><br class=""></div><div class="">Opinions, comments and corrections (including on English grammar) are all welcome. :-)<br class=""><div class=""><br class=""></div><div class="">-Van</div><div class=""><br class=""></div><div class="">---------</div><div class=""><br class=""></div><div class=""><h1 style="font-size:2.25em;margin-right:0px;margin-bottom:16px;margin-left:0px;line-height:1.2;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';margin-top:0px!important" class="">Instance Operators</h1><ul style="padding:0px 0px 0px 2em;margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class=""><li style="" class="">Proposal: <a href="https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-instance-operators.md" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none" class="">SE-NNNN</a></li><li style="" class="">Author: <a href="https://github.com/vmartinelli" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none" class="">Vanderlei Martinelli</a></li><li style="" class="">Status: <strong style="" class="">Awaiting review</strong></li><li style="" class="">Review manager: TBD</li></ul><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class="">Introduction</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">The proposal aims to move operator implementation from the global and static scope into extension/struct/class instance scope.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">Swift-evolution thread: <a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160125/008508.html" style="background-color:transparent;color:rgb(64,120,192);text-decoration:none" class="">link to the discussion thread for that proposal</a></p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class="">Motivation</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">When writing the protocol interface the operator is declarated inside the scope of that protocol, but its implementation has to be static and global. This, besides being inconsistent, might not the behaviour expected by programmers coming from other languages that have some kind of support for interface/protocol and operator implementation.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">Example:</p><div class="" style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px"><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;padding:16px;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal" class=""><span class="" style="color:rgb(150,152,150)">// MARK: - protocol</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">protocol</span> MyDoubleType {
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">someUsefulFunction</span>()
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">*</span>(lhs: <span class="" style="color:rgb(167,29,93)">Self</span>, rhs: <span class="" style="color:rgb(167,29,93)">Self</span>) <span class="" style="color:rgb(167,29,93)">-></span> Self
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">postfix</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">++</span>(<span class="" style="color:rgb(121,93,163)">inout</span> <span class="" style="">x</span>: <span class="" style="color:rgb(167,29,93)">Self</span>) <span class="" style="color:rgb(167,29,93)">-></span> Self
}
<span class="" style="color:rgb(150,152,150)">// MARK: - implementation</span>
<span class="" style="color:rgb(167,29,93)">extension</span> <span class="" style="color:rgb(0,134,179)">Double</span>: MyDoubleType {
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">someUsefulFunction</span>() {
<span class="" style="color:rgb(150,152,150)">// ...</span>
}
<span class="" style="color:rgb(150,152,150)">// we cannot implement the operators here...</span>
}
<span class="" style="color:rgb(150,152,150)">// ... but have to implement them here</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">*</span>(lhs: <span class="" style="color:rgb(0,134,179)">Double</span>, rhs: <span class="" style="color:rgb(0,134,179)">Double</span>) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">Double</span> {
<span class="" style="color:rgb(167,29,93)">return</span> lhs<span class="" style="color:rgb(167,29,93)">.</span>multipliedBy(rhs)
}
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">postfix</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">++</span>(<span class="" style="color:rgb(121,93,163)">inout</span> <span class="" style="">x</span>: <span class="" style="color:rgb(0,134,179)">Double</span>) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">Double</span> {
x <span class="" style="color:rgb(167,29,93)">+=</span> <span class="" style="color:rgb(0,134,179)">1</span><span class="" style="color:rgb(167,29,93)">.</span><span class="" style="color:rgb(0,134,179)">0</span>
<span class="" style="color:rgb(167,29,93)">return</span> x
}</pre></div><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">Also the current implementation does not leave much room for future expansion in the use of operators (such as conversion between values, for example).</p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class="">Proposed solution</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">Move the operator implementation into the extension/struct/class scope and turn operator funcs into instance funcs, using the <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">operator</code> keyword.</p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class="">Detailed design</h2><h3 style="margin-top:1em;margin-bottom:16px;line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class="">Protocol conformance</h3><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">After the change the above code can be written like the example bellow.</p><div class="" style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px"><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;padding:16px;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal" class=""><span class="" style="color:rgb(150,152,150)">// MARK: - protocol</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">protocol</span> MyDoubleType {
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">someUsefulFunction</span>()
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">operator</span> <span class="" style="color:rgb(167,29,93)">*</span>(rhs: <span class="" style="color:rgb(167,29,93)">Self</span>) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(167,29,93)">Self</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">mutating</span> <span class="" style="color:rgb(167,29,93)">postfix</span> <span class="" style="color:rgb(167,29,93)">operator</span> <span class="" style="color:rgb(167,29,93)">++</span>() <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(167,29,93)">Self</span>
}
<span class="" style="color:rgb(150,152,150)">// MARK: - implementation</span>
<span class="" style="color:rgb(167,29,93)">extension</span> <span class="" style="color:rgb(0,134,179)">Double</span>: MyDoubleType {
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">someUsefulFunction</span>() {
<span class="" style="color:rgb(150,152,150)">// ...</span>
}
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">operator</span> <span class="" style="color:rgb(167,29,93)">*</span>(rhs: <span class="" style="color:rgb(0,134,179)">Double</span>) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">Double</span> {
<span class="" style="color:rgb(167,29,93)">return</span> <span class="" style="color:rgb(167,29,93)">self</span><span class="" style="color:rgb(167,29,93)">.</span>multipliedBy(rhs)
}
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">mutating</span> <span class="" style="color:rgb(167,29,93)">postfix</span> <span class="" style="color:rgb(167,29,93)">operator</span> <span class="" style="color:rgb(167,29,93)">++</span>() <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">Double</span> {
<span class="" style="color:rgb(167,29,93)">self</span> <span class="" style="color:rgb(167,29,93)">+=</span> <span class="" style="color:rgb(0,134,179)">1</span><span class="" style="color:rgb(167,29,93)">.</span><span class="" style="color:rgb(0,134,179)">0</span>
<span class="" style="color:rgb(167,29,93)">return</span> <span class="" style="color:rgb(167,29,93)">self</span>
}
}</pre></div><h3 style="margin-top:1em;margin-bottom:16px;line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class="">Operator funcs everywhere</h3><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">An operator does not have to be implemented only to conform to a protocol, however. It can be also be implemented in any other place where a common func is. This means that even the current form can be supported.</p><h3 style="margin-top:1em;margin-bottom:16px;line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class="">Operator internal names</h3><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">Perhaps because of the internal implementation of Swift, operators have to have names to be handled. The suggestion is to adopt <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">__operator__GreaterThanOrEqual</code> for a <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">>=</code> operator, as example. The operator introduction would be:</p><div class="" style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px"><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;padding:16px;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal" class=""><span class="" style="color:rgb(167,29,93)">infix</span> <span class="" style="color:rgb(167,29,93)">operator</span> <span class="" style="color:rgb(167,29,93)">>=</span> {
<span class="" style="color:rgb(167,29,93)">associativity</span> <span class="" style="color:rgb(167,29,93)">none</span>
<span class="" style="color:rgb(167,29,93)">precedence</span> <span class="" style="color:rgb(0,134,179)">130</span>
name <span class="" style="color:rgb(24,54,145)"><span class="" style="">"</span>GreaterThanOrEqual<span class="" style="">"</span></span>
}</pre></div><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">So the code will be written like this...</p><div class="" style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px"><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;padding:16px;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal" class=""><span class="" style="color:rgb(167,29,93)">struct</span> MyStruct {
<span class="" style="color:rgb(167,29,93)">operator</span> <span class="" style="color:rgb(167,29,93)">>=</span>(other: MyStruct) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">Bool</span> {
<span class="" style="color:rgb(167,29,93)">return</span> <span class="" style="color:rgb(167,29,93)">...</span>
}
}</pre></div><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">... but translated internally to this:</p><div class="" style="margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px"><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;padding:16px;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal" class=""><span class="" style="color:rgb(167,29,93)">struct</span> MyStruct {
<span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">__operator__GreaterThanOrEqual</span>(other: MyStruct) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">Bool</span> {
<span class="" style="color:rgb(167,29,93)">return</span> <span class="" style="color:rgb(167,29,93)">...</span>
}
}</pre></div><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class="">Impact on existing code</h2><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">Since after this change an operator can be implemented in any other place where a common func can be, the current implementation may continue to exist, but marked as deprecated with a compiler/analyser warning.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">Also the <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">func</code> keyword would be deprecated for operators as well, using the <code style="font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;padding:0.2em 0px;margin:0px;background-color:rgba(0,0,0,0.0392157);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px" class="">operator</code> to declare/implement an operator func.</p><h2 style="margin-top:1em;margin-bottom:16px;line-height:1.225;font-size:1.75em;padding-bottom:0.3em;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:rgb(238,238,238);color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class="">Alternatives considered</h2><h3 style="margin-top:1em;margin-bottom:16px;line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class="">Status quo</h3><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">Leave things as they are. Even being inconsistent or not allowing new possibilities that instance operators will bring.</p><h3 style="margin-top:1em;margin-bottom:16px;line-height:1.43;font-size:1.5em;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol'" class="">Static implementation inside extension/struct/class scope</h3><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">This is the way operators are implemented in C#, for example. The change would be only aesthetic. The functionality would remain the same as today.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">As the types may differ from protocol/structure/class, this would allow state within the scope of operators that have nothing to do with that type. Not a good thing. In this case it might be better to keep things as they are.</p><p style="margin-top:0px;margin-bottom:16px;color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px" class="">Example:</p><div class="" style="color:rgb(51,51,51);font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol';font-size:16px;margin-bottom:0px!important"><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;padding:16px;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal" class=""><span class="" style="color:rgb(150,152,150)">// MARK: - protocol</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">protocol</span> MyDoubleType {
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">someUsefulFunction</span>()
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">static</span> <span class="" style="color:rgb(167,29,93)">operator</span> <span class="" style="color:rgb(167,29,93)">*</span>(lhs: <span class="" style="color:rgb(167,29,93)">Self</span>, rhs: <span class="" style="color:rgb(167,29,93)">Self</span>) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(167,29,93)">Self</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">static</span> <span class="" style="color:rgb(167,29,93)">operator</span> <span class="" style="color:rgb(167,29,93)">/</span>(lhs: <span class="" style="color:rgb(0,134,179)">Int64</span>, rhs: <span class="" style="color:rgb(0,134,179)">Int64</span>) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">Int64</span> <span class="" style="color:rgb(150,152,150)">// what?</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">static</span> <span class="" style="color:rgb(167,29,93)">postfix</span> <span class="" style="color:rgb(167,29,93)">operator</span> <span class="" style="color:rgb(167,29,93)">++</span>(<span class="" style="color:rgb(167,29,93)">inout</span> x: <span class="" style="color:rgb(167,29,93)">Self</span>) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(167,29,93)">Self</span>
}
<span class="" style="color:rgb(150,152,150)">// MARK: - implementation</span>
<span class="" style="color:rgb(167,29,93)">extension</span> <span class="" style="color:rgb(0,134,179)">Double</span>: MyDoubleType {
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">func</span> <span class="" style="color:rgb(121,93,163)">someUsefulFunction</span>() {
<span class="" style="color:rgb(150,152,150)">// ...</span>
}
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">static</span> <span class="" style="color:rgb(167,29,93)">operator</span> <span class="" style="color:rgb(167,29,93)">*</span>(lhs: <span class="" style="color:rgb(0,134,179)">Double</span>, rhs: <span class="" style="color:rgb(0,134,179)">Double</span>) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">Double</span> {
<span class="" style="color:rgb(167,29,93)">return</span> lhs<span class="" style="color:rgb(167,29,93)">.</span>multipliedBy(rhs)
}
<span class="" style="color:rgb(150,152,150)">// this should be implemented inside a Int64 type, not here...</span>
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">static</span> <span class="" style="color:rgb(167,29,93)">operator</span> <span class="" style="color:rgb(167,29,93)">/</span>(lhs: <span class="" style="color:rgb(0,134,179)">Int64</span>, rhs: <span class="" style="color:rgb(0,134,179)">Int64</span>) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">Int64</span> {
<span class="" style="color:rgb(150,152,150)">// ...</span>
}
<span class="" style="color:rgb(167,29,93)">public</span> <span class="" style="color:rgb(167,29,93)">static</span> <span class="" style="color:rgb(167,29,93)">postfix</span> <span class="" style="color:rgb(167,29,93)">operator</span> <span class="" style="color:rgb(167,29,93)">++</span>(<span class="" style="color:rgb(167,29,93)">inout</span> x: <span class="" style="color:rgb(0,134,179)">Double</span>) <span class="" style="color:rgb(167,29,93)">-></span> <span class="" style="color:rgb(0,134,179)">Double</span> {
x <span class="" style="color:rgb(167,29,93)">+=</span> <span class="" style="color:rgb(0,134,179)">1</span><span class="" style="color:rgb(167,29,93)">.</span><span class="" style="color:rgb(0,134,179)">0</span>
<span class="" style="color:rgb(167,29,93)">return</span> x
}
}</pre><pre style="overflow:auto;font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;font-size:14px;margin-top:0px;margin-bottom:0px;line-height:1.45;padding:16px;background-color:rgb(247,247,247);border-top-left-radius:3px;border-top-right-radius:3px;border-bottom-right-radius:3px;border-bottom-left-radius:3px;word-wrap:normal" class=""><br class=""></pre></div></div></div></div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>