[Pitch] Add the sign method to the SignedNumberType protocol.


(Adam Nemecek) #1

Howdy,
I think that the SignedNumberType should implement a method called sign
that will return -1 for negative numbers, 0 for 0 and 1 for positive
numbers. This is similar to the signum method in e.g. Java and similarly
called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0)
but I couldn't get the types right so I'm open to suggestions.


(Adrian Zubarev) #2

This should do the trick:

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 22. Mai 2016 bei 09:08:37, Adam Nemecek via swift-evolution (swift-evolution@swift.org) schrieb:

Howdy,
I think that the SignedNumberType should implement a method called sign that will return -1 for negative numbers, 0 for 0 and 1 for positive numbers. This is similar to the signum method in e.g. Java and similarly called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0) but I couldn't get the types right so I'm open to suggestions.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Haravikk) #3

Could you give an example of this method’s usage? Surely your value is either positive, negative or zero already, so this method doesn’t return anything more useful.

In other words, anywhere that I might do this:

  if myValue.sign > 0 { … }

I could just as easily do:

  if myValue > 0 { … }

To the same end result surely? Unless I’m missing something it seems redundant.

If there is a use-case for this, would it make more sense to have the return type as an enum with cases for Positive, Negative and Zero?

···

On 22 May 2016, at 08:07, Adam Nemecek via swift-evolution <swift-evolution@swift.org> wrote:

Howdy,
I think that the SignedNumberType should implement a method called sign that will return -1 for negative numbers, 0 for 0 and 1 for positive numbers. This is similar to the signum method in e.g. Java and similarly called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0) but I couldn't get the types right so I'm open to suggestions.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


#4

Challenge accepted… Removed the if/else if, at the cost of double function call to a tri-op:

extension Bool {
    func as01<T:SignedNumberType>() -> T { return self ? 1 : 0 }
}

extension SignedNumberType {
    var sign: Self { return (self > 0).as01() - (self < 0).as01() }
}

Dany

···

Le 22 mai 2016 à 03:07, Adam Nemecek via swift-evolution <swift-evolution@swift.org> a écrit :

Howdy,
I think that the SignedNumberType should implement a method called sign that will return -1 for negative numbers, 0 for 0 and 1 for positive numbers. This is similar to the signum method in e.g. Java and similarly called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0) but I couldn't get the types right so I'm open to suggestions.


(Adrian Zubarev) #5

Whoops didn’t check that your example worked as well :smiley:

···

--
Adrian Zubarev
Sent with Airmail

Am 22. Mai 2016 bei 10:27:17, Adrian Zubarev (adrian.zubarev@devandartist.com) schrieb:

This should do the trick:

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 22. Mai 2016 bei 09:08:37, Adam Nemecek via swift-evolution (swift-evolution@swift.org) schrieb:

Howdy,
I think that the SignedNumberType should implement a method called sign that will return -1 for negative numbers, 0 for 0 and 1 for positive numbers. This is similar to the signum method in e.g. Java and similarly called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0) but I couldn't get the types right so I'm open to suggestions.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Adam Nemecek) #6

It's not for branching based on the value, it's for calculating
mathematical functions with the sign retrieved from the value. So for the
same reason, no it should not be an enum. It should be the same type as the
type it's called on. It's that way in Haskell as well

http://hackage.haskell.org/package/base-4.9.0.0/docs/Prelude.html#v:signum

This function is basically in every language

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign

https://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#signum(double)

http://en.cppreference.com/w/cpp/numeric/math/signbit

https://golang.org/pkg/math/#Signbit

https://msdn.microsoft.com/en-us/library/system.math.sign(v=vs.110).aspx

It's used a bunch e.g. in dsp but also in mathematics

https://www.quora.com/What-are-the-real-life-applications-of-Signum-function

This quote somewhat summarizes it "So signum shows up in many places where
discontinuous jumps must be written in closed form."

···

On Mon, May 23, 2016 at 12:29 AM, Haravikk <swift-evolution@haravikk.me> wrote:

Could you give an example of this method’s usage? Surely your value is
either positive, negative or zero already, so this method doesn’t return
anything more useful.

In other words, anywhere that I might do this:

if myValue.sign > 0 { … }

I could just as easily do:

if myValue > 0 { … }

To the same end result surely? Unless I’m missing something it seems
redundant.

If there is a use-case for this, would it make more sense to have the
return type as an enum with cases for Positive, Negative and Zero?

On 22 May 2016, at 08:07, Adam Nemecek via swift-evolution < > swift-evolution@swift.org> wrote:

Howdy,
I think that the SignedNumberType should implement a method called sign
that will return -1 for negative numbers, 0 for 0 and 1 for positive
numbers. This is similar to the signum method in e.g. Java and similarly
called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0)
but I couldn't get the types right so I'm open to suggestions.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Adam Nemecek) #7

Oh and also machine learning. Search for sign or signum and machine
learning, you'll find a lot of results.

···

On Mon, May 23, 2016 at 1:26 AM, Adam Nemecek <adamnemecek@gmail.com> wrote:

It's not for branching based on the value, it's for calculating
mathematical functions with the sign retrieved from the value. So for the
same reason, no it should not be an enum. It should be the same type as the
type it's called on. It's that way in Haskell as well

http://hackage.haskell.org/package/base-4.9.0.0/docs/Prelude.html#v:signum

This function is basically in every language

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign

https://docs.oracle.com/javase/7/docs/api/java/lang/Math.html#signum(double)

http://en.cppreference.com/w/cpp/numeric/math/signbit

https://golang.org/pkg/math/#Signbit

https://msdn.microsoft.com/en-us/library/system.math.sign(v=vs.110).aspx

It's used a bunch e.g. in dsp but also in mathematics

https://www.quora.com/What-are-the-real-life-applications-of-Signum-function

This quote somewhat summarizes it "So signum shows up in many places where
discontinuous jumps must be written in closed form."

On Mon, May 23, 2016 at 12:29 AM, Haravikk <swift-evolution@haravikk.me> > wrote:

Could you give an example of this method’s usage? Surely your value is
either positive, negative or zero already, so this method doesn’t return
anything more useful.

In other words, anywhere that I might do this:

if myValue.sign > 0 { … }

I could just as easily do:

if myValue > 0 { … }

To the same end result surely? Unless I’m missing something it seems
redundant.

If there is a use-case for this, would it make more sense to have the
return type as an enum with cases for Positive, Negative and Zero?

On 22 May 2016, at 08:07, Adam Nemecek via swift-evolution < >> swift-evolution@swift.org> wrote:

Howdy,
I think that the SignedNumberType should implement a method called sign
that will return -1 for negative numbers, 0 for 0 and 1 for positive
numbers. This is similar to the signum method in e.g. Java and similarly
called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0)
but I couldn't get the types right so I'm open to suggestions.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Charlie Monroe) #8

The clean way would be to make it an enum with var signum that would return -1, 0, 1:

enum IntegerSign<NumberType: SignedNumberType> {

    case Negative
    case Zero
    case Positive
  
    var signum: NumberType {
        switch self {
        case .Negative:
            return -1 as NumberType
        case .Zero:
            return 0 as NumberType
        case .Positive:
            return 1 as NumberType
        }
    }
  
}

extension SignedNumberType {
    var sign: IntegerSign<Self> {
        if self == 0 {
            return .Zero
        } else if self > 0 {
            return .Positive
        } else {
            return .Negative
        }
    }
}

Charlie

···

On May 23, 2016, at 9:29 AM, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

Could you give an example of this method’s usage? Surely your value is either positive, negative or zero already, so this method doesn’t return anything more useful.

In other words, anywhere that I might do this:

  if myValue.sign > 0 { … }

I could just as easily do:

  if myValue > 0 { … }

To the same end result surely? Unless I’m missing something it seems redundant.

If there is a use-case for this, would it make more sense to have the return type as an enum with cases for Positive, Negative and Zero?

On 22 May 2016, at 08:07, Adam Nemecek via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Howdy,
I think that the SignedNumberType should implement a method called sign that will return -1 for negative numbers, 0 for 0 and 1 for positive numbers. This is similar to the signum method in e.g. Java and similarly called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0) but I couldn't get the types right so I'm open to suggestions.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Haravikk) #9

I don’t believe this solves the problem; I think you’ve really just moved the branching into the as01() method.

I think the more correct solution would be for all integer types to have a required Bool initialiser in a protocol somewhere, this way you could just do:

  var sign:Self { return Self(boolValue: self > 0) - Self(boolValue: self < 0) }

Since all integer types should be able to do this by just extending the value to fit, rather than testing it. I’m not completely up-to-date on the integer changes that will be in Swift 3, but perhaps conversion from bool will be easier in future, in Swift 2.2 it’s not really treated as a number type for conversion purposes, which is disappointing.

Also apologies for my initial misunderstanding of the need for this sign property, no idea how I managed to get such a mental block as it’s obviously very useful for multiplication when account for sign and a few other cases. Anyway, I’m a +1, though implementation is definitely trickier than it seems it should be, thanks to some of Swift’s number-related quirks!

···

On 23 May 2016, at 20:19, Dany St-Amant via swift-evolution <swift-evolution@swift.org> wrote:

Challenge accepted… Removed the if/else if, at the cost of double function call to a tri-op:

extension Bool {
    func as01<T:SignedNumberType>() -> T { return self ? 1 : 0 }
}

extension SignedNumberType {
    var sign: Self { return (self > 0).as01() - (self < 0).as01() }
}


(David Sweeris) #10

Can we make it RawRepresentable? That way signum can just return self.rawValue

···

Sent from my iPhone

On May 23, 2016, at 06:05, Charlie Monroe via swift-evolution <swift-evolution@swift.org> wrote:

The clean way would be to make it an enum with var signum that would return -1, 0, 1:

enum IntegerSign<NumberType: SignedNumberType> {

    case Negative
    case Zero
    case Positive
  
    var signum: NumberType {
        switch self {
        case .Negative:
            return -1 as NumberType
        case .Zero:
            return 0 as NumberType
        case .Positive:
            return 1 as NumberType
        }
    }
  
}

extension SignedNumberType {
    var sign: IntegerSign<Self> {
        if self == 0 {
            return .Zero
        } else if self > 0 {
            return .Positive
        } else {
            return .Negative
        }
    }
}

Charlie

On May 23, 2016, at 9:29 AM, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

Could you give an example of this method’s usage? Surely your value is either positive, negative or zero already, so this method doesn’t return anything more useful.

In other words, anywhere that I might do this:

  if myValue.sign > 0 { … }

I could just as easily do:

  if myValue > 0 { … }

To the same end result surely? Unless I’m missing something it seems redundant.

If there is a use-case for this, would it make more sense to have the return type as an enum with cases for Positive, Negative and Zero?

On 22 May 2016, at 08:07, Adam Nemecek via swift-evolution <swift-evolution@swift.org> wrote:

Howdy,
I think that the SignedNumberType should implement a method called sign that will return -1 for negative numbers, 0 for 0 and 1 for positive numbers. This is similar to the signum method in e.g. Java and similarly called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0) but I couldn't get the types right so I'm open to suggestions.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Sweeris) #11

That depends... Does “x = a ? b : c” and "if a {x = b} else {x = c}” compile down to the same machine code? I know of one arch where “?:” takes 0 cycles, but I don’t know if there’s a difference on x86 or ARM.

Either way, I’d think that just doing the comparison within `sign` would be faster, since it doesn’t create two extra Bools and SignedNumberTypes.

- Dave Sweeris

···

On May 24, 2016, at 6:33 AM, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

On 23 May 2016, at 20:19, Dany St-Amant via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Challenge accepted… Removed the if/else if, at the cost of double function call to a tri-op:

extension Bool {
    func as01<T:SignedNumberType>() -> T { return self ? 1 : 0 }
}

extension SignedNumberType {
    var sign: Self { return (self > 0).as01() - (self < 0).as01() }
}

I don’t believe this solves the problem; I think you’ve really just moved the branching into the as01() method.

I think the more correct solution would be for all integer types to have a required Bool initialiser in a protocol somewhere, this way you could just do:

  var sign:Self { return Self(boolValue: self > 0) - Self(boolValue: self < 0) }

Since all integer types should be able to do this by just extending the value to fit, rather than testing it. I’m not completely up-to-date on the integer changes that will be in Swift 3, but perhaps conversion from bool will be easier in future, in Swift 2.2 it’s not really treated as a number type for conversion purposes, which is disappointing.

Also apologies for my initial misunderstanding of the need for this sign property, no idea how I managed to get such a mental block as it’s obviously very useful for multiplication when account for sign and a few other cases. Anyway, I’m a +1, though implementation is definitely trickier than it seems it should be, thanks to some of Swift’s number-related quirks!
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jeremy Pereira) #12

Challenge accepted… Removed the if/else if, at the cost of double function call to a tri-op:

extension Bool {
    func as01<T:SignedNumberType>() -> T { return self ? 1 : 0 }
}

extension SignedNumberType {
    var sign: Self { return (self > 0).as01() - (self < 0).as01() }
}

I don’t believe this solves the problem; I think you’ve really just moved the branching into the as01() method.

I think the more correct solution would be for all integer types to have a required Bool initialiser in a protocol somewhere, this way you could just do:

  var sign:Self { return Self(boolValue: self > 0) - Self(boolValue: self < 0) }

Aren’t you just hiding the branches in the initialiser there?

···

On 24 May 2016, at 12:33, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

On 23 May 2016, at 20:19, Dany St-Amant via swift-evolution <swift-evolution@swift.org> wrote:


(Charlie Monroe) #13

Sure, that's a good idea, though I'd personally use the signum var, since using rawValue seems like a bit of an abuse of the fact the enum is defined this way and doesn't help readability of the code:

enum IntegerSign<NumberType: SignedNumberType>: RawRepresentable {

    case Negative
    case Zero
    case Positive
    
    init?(rawValue: NumberType) {
        if rawValue == -1 {
            self = .Negative
        } else if rawValue == 0 {
            self = .Zero
        } else if rawValue == 1 {
            self = .Positive
        } else {
            return nil
        }
    }
    
    var rawValue: NumberType {
        return self.signum
    }
    
    var signum: NumberType {
        switch self {
        case .Negative:
            return -1 as NumberType
        case .Zero:
            return 0 as NumberType
        case .Positive:
            return 1 as NumberType
        }
    }
    
}

extension SignedNumberType {
    var sign: IntegerSign<Self> {
        if self == 0 {
            return .Zero
        } else if self > 0 {
            return .Positive
        } else {
            return .Negative
        }
    }
}

···

On May 24, 2016, at 6:09 AM, David Sweeris <davesweeris@mac.com> wrote:

Can we make it RawRepresentable? That way signum can just return self.rawValue

Sent from my iPhone

On May 23, 2016, at 06:05, Charlie Monroe via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

The clean way would be to make it an enum with var signum that would return -1, 0, 1:

enum IntegerSign<NumberType: SignedNumberType> {

    case Negative
    case Zero
    case Positive
  
    var signum: NumberType {
        switch self {
        case .Negative:
            return -1 as NumberType
        case .Zero:
            return 0 as NumberType
        case .Positive:
            return 1 as NumberType
        }
    }
  
}

extension SignedNumberType {
    var sign: IntegerSign<Self> {
        if self == 0 {
            return .Zero
        } else if self > 0 {
            return .Positive
        } else {
            return .Negative
        }
    }
}

Charlie

On May 23, 2016, at 9:29 AM, Haravikk via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Could you give an example of this method’s usage? Surely your value is either positive, negative or zero already, so this method doesn’t return anything more useful.

In other words, anywhere that I might do this:

  if myValue.sign > 0 { … }

I could just as easily do:

  if myValue > 0 { … }

To the same end result surely? Unless I’m missing something it seems redundant.

If there is a use-case for this, would it make more sense to have the return type as an enum with cases for Positive, Negative and Zero?

On 22 May 2016, at 08:07, Adam Nemecek via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Howdy,
I think that the SignedNumberType should implement a method called sign that will return -1 for negative numbers, 0 for 0 and 1 for positive numbers. This is similar to the signum method in e.g. Java and similarly called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0) but I couldn't get the types right so I'm open to suggestions.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Haravikk) #14

Shouldn’t have to but possibly yeah; the booleans are just 1-bit values, so they can be extended to fit any integer type, but currently the ability to convert them seems lacking. There’s supposed to be something being done about improving the ability to use numeric types interchangeably (e.g- you should be able to freely fire an Int16 into an Int32 with implicit casting since it definitely fits), but I don’t know if Bool will be included in that or not.

···

On 25 May 2016, at 16:51, Jeremy Pereira <jeremy.j.pereira@googlemail.com> wrote:

On 24 May 2016, at 12:33, Haravikk via swift-evolution <swift-evolution@swift.org> wrote:

On 23 May 2016, at 20:19, Dany St-Amant via swift-evolution <swift-evolution@swift.org> wrote:

Challenge accepted… Removed the if/else if, at the cost of double function call to a tri-op:

extension Bool {
   func as01<T:SignedNumberType>() -> T { return self ? 1 : 0 }
}

extension SignedNumberType {
   var sign: Self { return (self > 0).as01() - (self < 0).as01() }
}

I don’t believe this solves the problem; I think you’ve really just moved the branching into the as01() method.

I think the more correct solution would be for all integer types to have a required Bool initialiser in a protocol somewhere, this way you could just do:

  var sign:Self { return Self(boolValue: self > 0) - Self(boolValue: self < 0) }

Aren’t you just hiding the branches in the initialiser there?


(David Sweeris) #15

Sorry, I misspoke. I just meant define it like this:
public enum IntegerSign<T: SignedIntegerType> : Int {
    case Negative = -1
    case Zero = 0
    case Positive = 1
    public var signum: T {
        return T(self.rawValue.toIntMax())
    }
}

Although, come to think of it, I’m not sure if that’s an exact drop-in replacement for your code, since it’s `SignedIntegerType` instead of `SignedNumberType`

-Dave Sweeris

···

On May 23, 2016, at 11:48 PM, Charlie Monroe <charlie@charliemonroe.net> wrote:

Sure, that's a good idea, though I'd personally use the signum var, since using rawValue seems like a bit of an abuse of the fact the enum is defined this way and doesn't help readability of the code:

enum IntegerSign<NumberType: SignedNumberType>: RawRepresentable {

    case Negative
    case Zero
    case Positive
    
    init?(rawValue: NumberType) {
        if rawValue == -1 {
            self = .Negative
        } else if rawValue == 0 {
            self = .Zero
        } else if rawValue == 1 {
            self = .Positive
        } else {
            return nil
        }
    }
    
    var rawValue: NumberType {
        return self.signum
    }
    
    var signum: NumberType {
        switch self {
        case .Negative:
            return -1 as NumberType
        case .Zero:
            return 0 as NumberType
        case .Positive:
            return 1 as NumberType
        }
    }
    
}

extension SignedNumberType {
    var sign: IntegerSign<Self> {
        if self == 0 {
            return .Zero
        } else if self > 0 {
            return .Positive
        } else {
            return .Negative
        }
    }
}

On May 24, 2016, at 6:09 AM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:

Can we make it RawRepresentable? That way signum can just return self.rawValue

Sent from my iPhone

On May 23, 2016, at 06:05, Charlie Monroe via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

The clean way would be to make it an enum with var signum that would return -1, 0, 1:

enum IntegerSign<NumberType: SignedNumberType> {

    case Negative
    case Zero
    case Positive
  
    var signum: NumberType {
        switch self {
        case .Negative:
            return -1 as NumberType
        case .Zero:
            return 0 as NumberType
        case .Positive:
            return 1 as NumberType
        }
    }
  
}

extension SignedNumberType {
    var sign: IntegerSign<Self> {
        if self == 0 {
            return .Zero
        } else if self > 0 {
            return .Positive
        } else {
            return .Negative
        }
    }
}

Charlie

On May 23, 2016, at 9:29 AM, Haravikk via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Could you give an example of this method’s usage? Surely your value is either positive, negative or zero already, so this method doesn’t return anything more useful.

In other words, anywhere that I might do this:

  if myValue.sign > 0 { … }

I could just as easily do:

  if myValue > 0 { … }

To the same end result surely? Unless I’m missing something it seems redundant.

If there is a use-case for this, would it make more sense to have the return type as an enum with cases for Positive, Negative and Zero?

On 22 May 2016, at 08:07, Adam Nemecek via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Howdy,
I think that the SignedNumberType should implement a method called sign that will return -1 for negative numbers, 0 for 0 and 1 for positive numbers. This is similar to the signum method in e.g. Java and similarly called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0) but I couldn't get the types right so I'm open to suggestions.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Charlie Monroe) #16

Yes, but here, the rawValue is Int - in my code, the rawValue is NumberType, which IMHO makes more sense...

···

On May 24, 2016, at 7:36 AM, David Sweeris <davesweeris@mac.com> wrote:

Sorry, I misspoke. I just meant define it like this:
public enum IntegerSign<T: SignedIntegerType> : Int {
    case Negative = -1
    case Zero = 0
    case Positive = 1
    public var signum: T {
        return T(self.rawValue.toIntMax())
    }
}

Although, come to think of it, I’m not sure if that’s an exact drop-in replacement for your code, since it’s `SignedIntegerType` instead of `SignedNumberType`

-Dave Sweeris

On May 23, 2016, at 11:48 PM, Charlie Monroe <charlie@charliemonroe.net <mailto:charlie@charliemonroe.net>> wrote:

Sure, that's a good idea, though I'd personally use the signum var, since using rawValue seems like a bit of an abuse of the fact the enum is defined this way and doesn't help readability of the code:

enum IntegerSign<NumberType: SignedNumberType>: RawRepresentable {

    case Negative
    case Zero
    case Positive
    
    init?(rawValue: NumberType) {
        if rawValue == -1 {
            self = .Negative
        } else if rawValue == 0 {
            self = .Zero
        } else if rawValue == 1 {
            self = .Positive
        } else {
            return nil
        }
    }
    
    var rawValue: NumberType {
        return self.signum
    }
    
    var signum: NumberType {
        switch self {
        case .Negative:
            return -1 as NumberType
        case .Zero:
            return 0 as NumberType
        case .Positive:
            return 1 as NumberType
        }
    }
    
}

extension SignedNumberType {
    var sign: IntegerSign<Self> {
        if self == 0 {
            return .Zero
        } else if self > 0 {
            return .Positive
        } else {
            return .Negative
        }
    }
}

On May 24, 2016, at 6:09 AM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:

Can we make it RawRepresentable? That way signum can just return self.rawValue

Sent from my iPhone

On May 23, 2016, at 06:05, Charlie Monroe via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

The clean way would be to make it an enum with var signum that would return -1, 0, 1:

enum IntegerSign<NumberType: SignedNumberType> {

    case Negative
    case Zero
    case Positive
  
    var signum: NumberType {
        switch self {
        case .Negative:
            return -1 as NumberType
        case .Zero:
            return 0 as NumberType
        case .Positive:
            return 1 as NumberType
        }
    }
  
}

extension SignedNumberType {
    var sign: IntegerSign<Self> {
        if self == 0 {
            return .Zero
        } else if self > 0 {
            return .Positive
        } else {
            return .Negative
        }
    }
}

Charlie

On May 23, 2016, at 9:29 AM, Haravikk via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Could you give an example of this method’s usage? Surely your value is either positive, negative or zero already, so this method doesn’t return anything more useful.

In other words, anywhere that I might do this:

  if myValue.sign > 0 { … }

I could just as easily do:

  if myValue > 0 { … }

To the same end result surely? Unless I’m missing something it seems redundant.

If there is a use-case for this, would it make more sense to have the return type as an enum with cases for Positive, Negative and Zero?

On 22 May 2016, at 08:07, Adam Nemecek via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Howdy,
I think that the SignedNumberType should implement a method called sign that will return -1 for negative numbers, 0 for 0 and 1 for positive numbers. This is similar to the signum method in e.g. Java and similarly called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0) but I couldn't get the types right so I'm open to suggestions.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(David Sweeris) #17

The RawValue is an Int, but signum is a T, which I thought was the point. I tried saying `T: IntegerLiteralConvertible`, and making RawValue = T, but the playground didn’t like that. Maybe with some of Swift 3’s generic enhancements, it could be that simple.

In any case, it sounds like this might be a moot point… I was hoping raw values could be exploited to simplify the code, but if it can’t work, it can’t work.

- Dave Sweeris

···

On May 24, 2016, at 1:41 AM, Charlie Monroe <charlie@charliemonroe.net> wrote:

Yes, but here, the rawValue is Int - in my code, the rawValue is NumberType, which IMHO makes more sense...

On May 24, 2016, at 7:36 AM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:

Sorry, I misspoke. I just meant define it like this:
public enum IntegerSign<T: SignedIntegerType> : Int {
    case Negative = -1
    case Zero = 0
    case Positive = 1
    public var signum: T {
        return T(self.rawValue.toIntMax())
    }
}

Although, come to think of it, I’m not sure if that’s an exact drop-in replacement for your code, since it’s `SignedIntegerType` instead of `SignedNumberType`

-Dave Sweeris

On May 23, 2016, at 11:48 PM, Charlie Monroe <charlie@charliemonroe.net <mailto:charlie@charliemonroe.net>> wrote:

Sure, that's a good idea, though I'd personally use the signum var, since using rawValue seems like a bit of an abuse of the fact the enum is defined this way and doesn't help readability of the code:

enum IntegerSign<NumberType: SignedNumberType>: RawRepresentable {

    case Negative
    case Zero
    case Positive
    
    init?(rawValue: NumberType) {
        if rawValue == -1 {
            self = .Negative
        } else if rawValue == 0 {
            self = .Zero
        } else if rawValue == 1 {
            self = .Positive
        } else {
            return nil
        }
    }
    
    var rawValue: NumberType {
        return self.signum
    }
    
    var signum: NumberType {
        switch self {
        case .Negative:
            return -1 as NumberType
        case .Zero:
            return 0 as NumberType
        case .Positive:
            return 1 as NumberType
        }
    }
    
}

extension SignedNumberType {
    var sign: IntegerSign<Self> {
        if self == 0 {
            return .Zero
        } else if self > 0 {
            return .Positive
        } else {
            return .Negative
        }
    }
}

On May 24, 2016, at 6:09 AM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:

Can we make it RawRepresentable? That way signum can just return self.rawValue

Sent from my iPhone

On May 23, 2016, at 06:05, Charlie Monroe via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

The clean way would be to make it an enum with var signum that would return -1, 0, 1:

enum IntegerSign<NumberType: SignedNumberType> {

    case Negative
    case Zero
    case Positive
  
    var signum: NumberType {
        switch self {
        case .Negative:
            return -1 as NumberType
        case .Zero:
            return 0 as NumberType
        case .Positive:
            return 1 as NumberType
        }
    }
  
}

extension SignedNumberType {
    var sign: IntegerSign<Self> {
        if self == 0 {
            return .Zero
        } else if self > 0 {
            return .Positive
        } else {
            return .Negative
        }
    }
}

Charlie

On May 23, 2016, at 9:29 AM, Haravikk via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Could you give an example of this method’s usage? Surely your value is either positive, negative or zero already, so this method doesn’t return anything more useful.

In other words, anywhere that I might do this:

  if myValue.sign > 0 { … }

I could just as easily do:

  if myValue > 0 { … }

To the same end result surely? Unless I’m missing something it seems redundant.

If there is a use-case for this, would it make more sense to have the return type as an enum with cases for Positive, Negative and Zero?

On 22 May 2016, at 08:07, Adam Nemecek via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Howdy,
I think that the SignedNumberType should implement a method called sign that will return -1 for negative numbers, 0 for 0 and 1 for positive numbers. This is similar to the signum method in e.g. Java and similarly called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0) but I couldn't get the types right so I'm open to suggestions.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Charlie Monroe) #18

Ok, how about this? The compiler currently crashes when compiling this, but IMHO it is (or should be) valid code.

enum IntegerSign<NumberType: SignedNumberType>: NumberType {
    
    case Negative = -1
    case Zero = 0
    case Positive = 1
    
    var signum: NumberType {
        return self.rawValue
    }
    
}

extension SignedNumberType {
    var sign: IntegerSign<Self> {
        if self == 0 {
            return .Zero
        } else if self > 0 {
            return .Positive
        } else {
            return .Negative
        }
    }
}

···

On May 24, 2016, at 8:48 PM, David Sweeris <davesweeris@mac.com> wrote:

The RawValue is an Int, but signum is a T, which I thought was the point. I tried saying `T: IntegerLiteralConvertible`, and making RawValue = T, but the playground didn’t like that. Maybe with some of Swift 3’s generic enhancements, it could be that simple.

In any case, it sounds like this might be a moot point… I was hoping raw values could be exploited to simplify the code, but if it can’t work, it can’t work.

- Dave Sweeris

On May 24, 2016, at 1:41 AM, Charlie Monroe <charlie@charliemonroe.net <mailto:charlie@charliemonroe.net>> wrote:

Yes, but here, the rawValue is Int - in my code, the rawValue is NumberType, which IMHO makes more sense...

On May 24, 2016, at 7:36 AM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:

Sorry, I misspoke. I just meant define it like this:
public enum IntegerSign<T: SignedIntegerType> : Int {
    case Negative = -1
    case Zero = 0
    case Positive = 1
    public var signum: T {
        return T(self.rawValue.toIntMax())
    }
}

Although, come to think of it, I’m not sure if that’s an exact drop-in replacement for your code, since it’s `SignedIntegerType` instead of `SignedNumberType`

-Dave Sweeris

On May 23, 2016, at 11:48 PM, Charlie Monroe <charlie@charliemonroe.net <mailto:charlie@charliemonroe.net>> wrote:

Sure, that's a good idea, though I'd personally use the signum var, since using rawValue seems like a bit of an abuse of the fact the enum is defined this way and doesn't help readability of the code:

enum IntegerSign<NumberType: SignedNumberType>: RawRepresentable {

    case Negative
    case Zero
    case Positive
    
    init?(rawValue: NumberType) {
        if rawValue == -1 {
            self = .Negative
        } else if rawValue == 0 {
            self = .Zero
        } else if rawValue == 1 {
            self = .Positive
        } else {
            return nil
        }
    }
    
    var rawValue: NumberType {
        return self.signum
    }
    
    var signum: NumberType {
        switch self {
        case .Negative:
            return -1 as NumberType
        case .Zero:
            return 0 as NumberType
        case .Positive:
            return 1 as NumberType
        }
    }
    
}

extension SignedNumberType {
    var sign: IntegerSign<Self> {
        if self == 0 {
            return .Zero
        } else if self > 0 {
            return .Positive
        } else {
            return .Negative
        }
    }
}

On May 24, 2016, at 6:09 AM, David Sweeris <davesweeris@mac.com <mailto:davesweeris@mac.com>> wrote:

Can we make it RawRepresentable? That way signum can just return self.rawValue

Sent from my iPhone

On May 23, 2016, at 06:05, Charlie Monroe via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

The clean way would be to make it an enum with var signum that would return -1, 0, 1:

enum IntegerSign<NumberType: SignedNumberType> {

    case Negative
    case Zero
    case Positive
  
    var signum: NumberType {
        switch self {
        case .Negative:
            return -1 as NumberType
        case .Zero:
            return 0 as NumberType
        case .Positive:
            return 1 as NumberType
        }
    }
  
}

extension SignedNumberType {
    var sign: IntegerSign<Self> {
        if self == 0 {
            return .Zero
        } else if self > 0 {
            return .Positive
        } else {
            return .Negative
        }
    }
}

Charlie

On May 23, 2016, at 9:29 AM, Haravikk via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Could you give an example of this method’s usage? Surely your value is either positive, negative or zero already, so this method doesn’t return anything more useful.

In other words, anywhere that I might do this:

  if myValue.sign > 0 { … }

I could just as easily do:

  if myValue > 0 { … }

To the same end result surely? Unless I’m missing something it seems redundant.

If there is a use-case for this, would it make more sense to have the return type as an enum with cases for Positive, Negative and Zero?

On 22 May 2016, at 08:07, Adam Nemecek via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Howdy,
I think that the SignedNumberType should implement a method called sign that will return -1 for negative numbers, 0 for 0 and 1 for positive numbers. This is similar to the signum method in e.g. Java and similarly called methods in other languages.

The implementation is fairly straight forward

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

I was trying to implement is without branching by doing (x > 0) - (x < 0) but I couldn't get the types right so I'm open to suggestions.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution