[swift-evolution] [Proposal] Instance Operators
Vanderlei Martinelli
vmartinelli at alecrim.com
Thu Feb 25 13:59:16 CST 2016
Hello.
The proposal can be also read at
https://gist.github.com/vmartinelli/67d6ad234c7a4e14f8d5
Original thread:
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160125/008508.html
Opinions, comments and corrections (including on English grammar) are all
welcome. :-)
-Van
---------
Instance Operators
- Proposal: SE-NNNN
<https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-instance-operators.md>
- Author: Vanderlei Martinelli <https://github.com/vmartinelli>
- Status: *Awaiting review*
- Review manager: TBD
Introduction
The proposal aims to move operator implementation from the global and
static scope into extension/struct/class instance scope.
Swift-evolution thread: link to the discussion thread for that proposal
<https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160125/008508.html>
Motivation
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.
Example:
// MARK: - protocol
public protocol MyDoubleType {
public func someUsefulFunction()
public func *(lhs: Self, rhs: Self) -> Self
public postfix func ++(inout x: Self) -> Self
}
// MARK: - implementation
extension Double: MyDoubleType {
public func someUsefulFunction() {
// ...
}
// we cannot implement the operators here...
}
// ... but have to implement them here
public func *(lhs: Double, rhs: Double) -> Double {
return lhs.multipliedBy(rhs)
}
public postfix func ++(inout x: Double) -> Double {
x += 1.0
return x
}
Also the current implementation does not leave much room for future
expansion in the use of operators (such as conversion between values, for
example).
Proposed solution
Move the operator implementation into the extension/struct/class scope and
turn operator funcs into instance funcs, using the operator keyword.
Detailed designProtocol conformance
After the change the above code can be written like the example bellow.
// MARK: - protocol
public protocol MyDoubleType {
public func someUsefulFunction()
public operator *(rhs: Self) -> Self
public mutating postfix operator ++() -> Self
}
// MARK: - implementation
extension Double: MyDoubleType {
public func someUsefulFunction() {
// ...
}
public operator *(rhs: Double) -> Double {
return self.multipliedBy(rhs)
}
public mutating postfix operator ++() -> Double {
self += 1.0
return self
}
}
Operator funcs everywhere
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.
Operator internal names
Perhaps because of the internal implementation of Swift, operators have to
have names to be handled. The suggestion is to adopt
__operator__GreaterThanOrEqual for a >= operator, as example. The operator
introduction would be:
infix operator >= {
associativity none
precedence 130
name "GreaterThanOrEqual"
}
So the code will be written like this...
struct MyStruct {
operator >=(other: MyStruct) -> Bool {
return ...
}
}
... but translated internally to this:
struct MyStruct {
func __operator__GreaterThanOrEqual(other: MyStruct) -> Bool {
return ...
}
}
Impact on existing code
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.
Also the func keyword would be deprecated for operators as well, using the
operator to declare/implement an operator func.
Alternatives consideredStatus quo
Leave things as they are. Even being inconsistent or not allowing new
possibilities that instance operators will bring.
Static implementation inside extension/struct/class scope
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.
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.
Example:
// MARK: - protocol
public protocol MyDoubleType {
public func someUsefulFunction()
public static operator *(lhs: Self, rhs: Self) -> Self
public static operator /(lhs: Int64, rhs: Int64) -> Int64 // what?
public static postfix operator ++(inout x: Self) -> Self
}
// MARK: - implementation
extension Double: MyDoubleType {
public func someUsefulFunction() {
// ...
}
public static operator *(lhs: Double, rhs: Double) -> Double {
return lhs.multipliedBy(rhs)
}
// this should be implemented inside a Int64 type, not here...
public static operator /(lhs: Int64, rhs: Int64) -> Int64 {
// ...
}
public static postfix operator ++(inout x: Double) -> Double {
x += 1.0
return x
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160225/37cd3271/attachment.html>
More information about the swift-evolution
mailing list