[swift-users] Implementing signum

Rick Mann rmann at latencyzero.com
Sun Nov 20 18:31:37 CST 2016


Thank you, Hooman, that's very educational.

> On Nov 20, 2016, at 10:09 , Hooman Mehr <hooman at mac.com> wrote:
> 
> Let me explain this a bit further:
> 
> Swift generic programming is very different from C++ template programming. Swift compiler needs to type-check generic code on spot, not while instantiating the template (because in Swift, instantiation can occur at runtime if the generic code is from a different module).
> 
> This means that it should know what operations will be supported on the type being extended. Your `Signumable` defines only a single function. IF you extend `Signumable` to provide an implementation, you can’t refer to any function other than `sgn()`, but you need more to be able to implement sin(). This is don though generic constraints. You need to constrain the type to which your extension applies. The minimal contains that you need are: `ExpressibleByIntegerLiteral` and `Comparable` so that you can write the algorithm as follow:
> 
> 
> The way you wrote it, would require more defined operations (subtraction):
> 
> protocol Signumable
> {
>     func sgn() -> Self
> }
> 
> extension Signumable where Self: ExpressibleByIntegerLiteral & Comparable
> {
>     func
>         sgn()
>         -> Self
>     {
>         if 0 < self { return 1 }
>         if self < 0 { return -1 }
>         return 0
>     }
> }
> 
> This can potentially work on any integer (including unsigned) and floating point type and any other type that happens to support those two protocols. But it does not work yet, because those types do not automatically conform to `Signumable`. To make them conform you need a bit of boilerplate:
> 
> extension Int: Signumable {}
> extension Int8: Signumable {}
> extension Int16: Signumable {}
> extension Int32: Signumable {}
> extension Int64: Signumable {}
> extension UInt: Signumable {}
> extension UInt8: Signumable {}
> extension UInt16: Signumable {}
> extension UInt32: Signumable {}
> extension UInt64: Signumable {}
> extension Float32: Signumable {}
> extension Float64: Signumable {}
> extension Float80: Signumable {}
> 
> The problem is, if a new numeric type is defined say a rational number type, it won’t conform automatically and you will have to declare its conformance as above. For this reason, it is better to try to find an existing standard protocol to extend instead of introducing your own protocol for such things.
> 
> So, as others suggested, it is better to extend the existing `SignedNumber` protocol instead of introducing your own  `Signumable`, unless if you need to write other generic algorithms that need your protocol as their constraints.
> 
>> On Nov 19, 2016, at 6:44 PM, Rick Mann via swift-users <swift-users at swift.org> wrote:
>> 
>> I'm trying to do this:
>> 
>> protocol Signumable
>> {
>> 	func sgn() -> Self
>> }
>> 
>> extension Signumable
>> {
>> 	func
>> 	sgn()
>> 		-> Self
>> 	{
>> 		let pos = 0 < self		//  Error
>> 		let neg = self < 0		//  Error
>> 		let p = pos ? Self(1) : Self(0)
>> 		let n = neg ? Self(1) : Self(0)
>> 		return p - n
>> 	}
>> }
>> 
>> 
>> extension Double : Signumable {}
>> 
>> But I get
>> 
>> Binary operator '<' cannot be applied to operands of type 'Int' and 'Self'
>> 
>> I figure there should be additional constraints on Signumable.
>> 
>> Help would be much appreciated!
>> 
>> 
>> -- 
>> Rick Mann
>> rmann at latencyzero.com
>> 
>> 
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users
> 


-- 
Rick Mann
rmann at latencyzero.com




More information about the swift-users mailing list