# Implementing signum

**URL:** <https://forums.swift.org/t/implementing-signum/4563>\
**Category:** Using Swift\
**Created:** [November 20, 2016, 2:44am UTC](https://forums.swift.org/t/implementing-signum/4563 "2016-11-20T02:44:04Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![JetForMe](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jetforme/32/482_2.png) [@JetForMe](https://forums.swift.org/u/JetForMe)\
**Post date:** [November 20, 2016, 2:44am UTC](https://forums.swift.org/t/implementing-signum/4563/1 "2016-11-20T02:44:04Z")

</div>

I'm trying to do this:

protocol Signumable  
{  
&nbsp;&nbsp;func sgn() -\> Self  
}

extension Signumable  
{  
&nbsp;&nbsp;func  
&nbsp;&nbsp;sgn()  
&nbsp;&nbsp;&nbsp;&nbsp;-\> Self  
&nbsp;&nbsp;{  
&nbsp;&nbsp;&nbsp;&nbsp;let pos = 0 \< self // Error  
&nbsp;&nbsp;&nbsp;&nbsp;let neg = self \< 0 // Error  
&nbsp;&nbsp;&nbsp;&nbsp;let p = pos ? Self(1) : Self(0)  
&nbsp;&nbsp;&nbsp;&nbsp;let n = neg ? Self(1) : Self(0)  
&nbsp;&nbsp;&nbsp;&nbsp;return p - n  
&nbsp;&nbsp;}  
}

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@latencyzero.com

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [November 20, 2016, 7:59am UTC](https://forums.swift.org/t/implementing-signum/4563/2 "2016-11-20T07:59:38Z")

</div>

> From some older evolution-thread:

extension SignedNumberType {  
var sign: Self {  
if self == (0 as Self) {  
return (0 as Self)  
} else if self \> (0 as Self) {  
return (1 as Self)  
}  
return (-1 as Self)  
}  
}

> **···**
>
> --  
> Adrian Zubarev  
> Sent with Airmail
> 
> Am 20. November 2016 um 03:44:04, Rick Mann via swift-users (swift-users@swift.org(mailto:swift-users@swift.org)) schrieb:
> 
> > 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@latencyzero.com
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-users mailing list  
> > swift-users@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-users](https://lists.swift.org/mailman/listinfo/swift-users)

---

<div class="post-metadata">

**Author:** ![hooman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hooman/32/43536_2.png) [@hooman](https://forums.swift.org/u/hooman)\
**Post date:** [November 20, 2016, 6:09pm UTC](https://forums.swift.org/t/implementing-signum/4563/3 "2016-11-20T18:09:20Z")

</div>

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  
{  
&nbsp;&nbsp;&nbsp;&nbsp;func sgn() -\> Self  
}

extension Signumable where Self: ExpressibleByIntegerLiteral & Comparable  
{  
&nbsp;&nbsp;&nbsp;&nbsp;func  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sgn()  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-\> Self  
&nbsp;&nbsp;&nbsp;&nbsp;{  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if 0 \< self { return 1 }  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if self \< 0 { return -1 }  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0  
&nbsp;&nbsp;&nbsp;&nbsp;}  
}

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 \<[https://gist.github.com/hooman/6e08c48e1e06ee19e06e5b09f664f9be&gt;](https://gist.github.com/hooman/6e08c48e1e06ee19e06e5b09f664f9be&gt;), 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@swift.org\> wrote:
> > 
> > I'm trying to do this:
> > 
> > protocol Signumable  
> > {  
> > &nbsp;&nbsp;func sgn() -\> Self  
> > }
> > 
> > extension Signumable  
> > {  
> > &nbsp;&nbsp;func  
> > &nbsp;&nbsp;sgn()  
> > &nbsp;&nbsp;&nbsp;&nbsp;-\> Self  
> > &nbsp;&nbsp;{  
> > &nbsp;&nbsp;&nbsp;&nbsp;let pos = 0 \< self // Error  
> > &nbsp;&nbsp;&nbsp;&nbsp;let neg = self \< 0 // Error  
> > &nbsp;&nbsp;&nbsp;&nbsp;let p = pos ? Self(1) : Self(0)  
> > &nbsp;&nbsp;&nbsp;&nbsp;let n = neg ? Self(1) : Self(0)  
> > &nbsp;&nbsp;&nbsp;&nbsp;return p - n  
> > &nbsp;&nbsp;}  
> > }
> > 
> > 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@latencyzero.com
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-users mailing list  
> > swift-users@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-users](https://lists.swift.org/mailman/listinfo/swift-users)

---

<div class="post-metadata">

**Author:** ![jtbandes](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jtbandes/32/463_2.png) [@jtbandes](https://forums.swift.org/u/jtbandes)\
**Post date:** [November 20, 2016, 8:09am UTC](https://forums.swift.org/t/implementing-signum/4563/4 "2016-11-20T08:09:19Z")

</div>

Just played with this and it turns out that due to the implicit nature of  
IntegerLiteralConvertible, you don't need any of the "as Self"s:

extension SignedNumber{  
&nbsp;&nbsp;&nbsp;&nbsp;var sign: Self {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if self == 0 {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else if self \> 0 {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1  
&nbsp;&nbsp;&nbsp;&nbsp;}  
}

> **···**
>
> On Sat, Nov 19, 2016 at 11:59 PM, Adrian Zubarev via swift-evolution \< swift-evolution@swift.org\> wrote:
> 
> > From some older evolution-thread:
> > 
> > extension SignedNumberType {  
> > &nbsp;&nbsp;&nbsp;&nbsp;var sign: Self {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if self == (0 as Self) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (0 as Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else if self \> (0 as Self) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (1 as Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (-1 as Self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > }  
> > --  
> > Adrian Zubarev  
> > Sent with Airmail

---

<div class="post-metadata">

**Author:** ![JetForMe](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jetforme/32/482_2.png) [@JetForMe](https://forums.swift.org/u/JetForMe)\
**Post date:** [November 21, 2016, 12:31am UTC](https://forums.swift.org/t/implementing-signum/4563/5 "2016-11-21T00:31:37Z")

</div>

Thank you, Hooman, that's very educational.

> **···**
>
> > On Nov 20, 2016, at 10:09 , Hooman Mehr \<hooman@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  
> > {  
> > &nbsp;&nbsp;&nbsp;&nbsp;func sgn() -\> Self  
> > }
> > 
> > extension Signumable where Self: ExpressibleByIntegerLiteral & Comparable  
> > {  
> > &nbsp;&nbsp;&nbsp;&nbsp;func  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sgn()  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-\> Self  
> > &nbsp;&nbsp;&nbsp;&nbsp;{  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if 0 \< self { return 1 }  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if self \< 0 { return -1 }  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0  
> > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > }
> > 
> > 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@swift.org\> wrote:
> > > 
> > > I'm trying to do this:
> > > 
> > > protocol Signumable  
> > > {  
> > > &nbsp;&nbsp;func sgn() -\> Self  
> > > }
> > > 
> > > extension Signumable  
> > > {  
> > > &nbsp;&nbsp;func  
> > > &nbsp;&nbsp;sgn()  
> > > &nbsp;&nbsp;&nbsp;&nbsp;-\> Self  
> > > &nbsp;&nbsp;{  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let pos = 0 \< self // Error  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let neg = self \< 0 // Error  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let p = pos ? Self(1) : Self(0)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;let n = neg ? Self(1) : Self(0)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;return p - n  
> > > &nbsp;&nbsp;}  
> > > }
> > > 
> > > 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@latencyzero.com
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-users mailing list  
> > > swift-users@swift.org  
> > > [https://lists.swift.org/mailman/listinfo/swift-users](https://lists.swift.org/mailman/listinfo/swift-users)
> 
> --  
> Rick Mann  
> rmann@latencyzero.com

---

<div class="post-metadata">

**Author:** ![dabrahams](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dabrahams/32/9815_2.png) [@dabrahams](https://forums.swift.org/u/dabrahams)\
**Post date:** [November 29, 2016, 2:46am UTC](https://forums.swift.org/t/implementing-signum/4563/6 "2016-11-29T02:46:53Z")

</div>

To be clear, that's true, but it's not the reason we typecheck generic  
code at its point-of-definition. The fact that instantiation can occur  
at runtime is almost completely an artifact of our implementation model,  
rather than a part of how the language is defined.

We typecheck generics at the point of definition because it's the right  
thing to do, regardless of your implementation model. The alternative  
leaves you writing generic code that appears to compile but actually  
only works for the one or two cases you tested it with, and that  
generates the infamous C++ “template instantiation backtrace” when it  
fails.

> **···**
>
> on Sun Nov 20 2016, Hooman Mehr \<swift-users-AT-swift.org\> 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).
> 
> --  
> -Dave

---

<div class="post-metadata">

**Author:** ![dabrahams](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dabrahams/32/9815_2.png) [@dabrahams](https://forums.swift.org/u/dabrahams)\
**Post date:** [November 29, 2016, 2:53am UTC](https://forums.swift.org/t/implementing-signum/4563/7 "2016-11-29T02:53:21Z")

</div>

The deeper generic programming principle here has to do with how  
requirements are clustered into protocols and whether that limits what  
you can express. Are there any Signumables that can't also efficiently  
implement the requirements of SignedNumber (and vice-versa)? If not,  
these two things are fundamentally, in some sense, the same protocol and  
should be merged. If so, there may be a reason to have a distinct  
protocol, so that you can write algorithms constrained to that protocol  
that give protocols that depend on the operation.

> **···**
>
> on Sun Nov 20 2016, Hooman Mehr \<swift-users-AT-swift.org\> 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  
> > {  
> > &nbsp;&nbsp;&nbsp;&nbsp;func sgn() -\> Self  
> > }
> > 
> > extension Signumable where Self: ExpressibleByIntegerLiteral & Comparable  
> > {  
> > &nbsp;&nbsp;&nbsp;&nbsp;func  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sgn()  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-\> Self  
> > &nbsp;&nbsp;&nbsp;&nbsp;{  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if 0 \< self { return 1 }  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if self \< 0 { return -1 }  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0  
> > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > }
> > 
> > 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  
> > \<[https://gist.github.com/hooman/6e08c48e1e06ee19e06e5b09f664f9be&gt;](https://gist.github.com/hooman/6e08c48e1e06ee19e06e5b09f664f9be&gt;), 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.
> 
> --  
> -Dave
