Warning for possible overflow or optional

Hello,

Don’t you think that the compiler should emit a warning for a possible overflow in the following code?

func foo(x:UInt16) {

  let y = Int16(x) <— Shouldn’t we have a warning here? Or an optional?
  print(y)
}

This code is very very fragile and Swift is supposed to bring safety?

Thanks,

Stéphane

This is perfectly safe since it's checked at runtime. If you don't want it
checked at runtime you can use Int16(bitPattern: x).

I just finished writing the inflate algorithm in Swift. With your
suggestion I would have used bitPattern or truncatingBitPattern everywhere
to bypass warnings and missed at least two times where Swift caught a
mistake a runtime. C API users would have a similar problem.

-david GitHub - AE9RB/SwiftGL: This project has moved.

···

On Tue, Feb 16, 2016 at 4:45 AM, Stéphane Lizeray <swift-evolution@swift.org > wrote:

Hello,

Don’t you think that the compiler should emit a warning for a possible
overflow in the following code?

func foo(x:UInt16) {

let y = Int16(x) <— Shouldn’t we have a warning here? Or an optional?
print(y)
}

This code is very very fragile and Swift is supposed to bring safety?

Thanks,

Stéphane

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

Safety does not mean you can easily write code that crashes once it is deployed….

Safety means that the compiler helps you to avoid programming errors as much as possible. This is what Optional is all about.

In this case, I should have used an Int32 instead of converting an UInt16 to an Int16….

Int16(UInt16:) should be either a failable constructor or the compiler should emit a warning.

Stéphane

···

On 16 Feb 2016, at 19:02, David Turnbull <dturnbull@gmail.com> wrote:

This is perfectly safe since it's checked at runtime. If you don't want it checked at runtime you can use Int16(bitPattern: x).

I just finished writing the inflate algorithm in Swift. With your suggestion I would have used bitPattern or truncatingBitPattern everywhere to bypass warnings and missed at least two times where Swift caught a mistake a runtime. C API users would have a similar problem.

-david GitHub - AE9RB/SwiftGL: This project has moved.

On Tue, Feb 16, 2016 at 4:45 AM, Stéphane Lizeray <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
Hello,

Don’t you think that the compiler should emit a warning for a possible overflow in the following code?

func foo(x:UInt16) {

  let y = Int16(x) <— Shouldn’t we have a warning here? Or an optional?
  print(y)
}

This code is very very fragile and Swift is supposed to bring safety?

Thanks,

Stéphane

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

Can you show some examples where and why you use not-Int types and this is
a problem? What you're suggesting will be a burden to those of us who need
bitwise optimizations or work with C APIs.

My last week was spent reading files with huffman coding. So I had no
choice but to use bitwise operations. My experience is that Swift got this
right (except for "truncatingBitPattern" taking up 25% of an 80 column
line).

So my question is, "why are you not using Int?" There's plenty of use
cases, you just haven't stated yours so we can't understand why the current
system is failing you.

Safety does not mean you can easily write code that crashes once it is

deployed….

var a = [Int](); a[0]=99

That was pretty easy. I don't buy into this argument. If you don't want an
out of bounds error, you either make sure you don't math your way out of
bounds or you check every time before you subscript. I don't see why an
integer conversion should be any different.

-david

Can you show some examples where and why you use not-Int types and this is
a problem? What you're suggesting will be a burden to those of us who need
bitwise optimizations or work with C APIs.

My last week was spent reading files with huffman coding. So I had no
choice but to use bitwise operations. My experience is that Swift got this
right (except for "truncatingBitPattern" taking up 25% of an 80 column
line).

Suggestions for improved names welcomed.

···

on Tue Feb 16 2016, David Turnbull <swift-evolution@swift.org> wrote:

So my question is, "why are you not using Int?" There's plenty of use
cases, you just haven't stated yours so we can't understand why the current
system is failing you.

Safety does not mean you can easily write code that crashes once it is

deployed….

var a = [Int](); a[0]=99

That was pretty easy. I don't buy into this argument. If you don't want an
out of bounds error, you either make sure you don't math your way out of
bounds or you check every time before you subscript. I don't see why an
integer conversion should be any different.

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

--
-Dave

"Int16(UInt16:) should be either a failable constructor or the compiler
should emit a warning."

That feels right to me (failable constructor) from a safety standpoint,
make you code to deal with it explicitly instead of being surprised by a
runtime failure that you make not detect easily in testing, etc.

···

On Tue, Feb 16, 2016 at 10:20 AM Stéphane Lizeray <swift-evolution@swift.org> wrote:

Safety does not mean you can easily write code that crashes once it is
deployed….

Safety means that the compiler helps you to avoid programming errors as
much as possible. This is what Optional is all about.

In this case, I should have used an Int32 instead of converting an UInt16
to an Int16….

Int16(UInt16:) should be either a failable constructor or the compiler
should emit a warning.

Stéphane

On 16 Feb 2016, at 19:02, David Turnbull <dturnbull@gmail.com> wrote:

This is perfectly safe since it's checked at runtime. If you don't want it
checked at runtime you can use Int16(bitPattern: x).

I just finished writing the inflate algorithm in Swift. With your
suggestion I would have used bitPattern or truncatingBitPattern everywhere
to bypass warnings and missed at least two times where Swift caught a
mistake a runtime. C API users would have a similar problem.

-david GitHub - AE9RB/SwiftGL: This project has moved.

On Tue, Feb 16, 2016 at 4:45 AM, Stéphane Lizeray < > swift-evolution@swift.org> wrote:

Hello,

Don’t you think that the compiler should emit a warning for a possible
overflow in the following code?

func foo(x:UInt16) {

let y = Int16(x) <— Shouldn’t we have a warning here? Or an optional?
print(y)
}

This code is very very fragile and Swift is supposed to bring safety?

Thanks,

Stéphane

_______________________________________________
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

I believe you stated that you ran across at least two times that runtime
checks caught a narrowing error (e.g. overflow) in your recent work. I
support runtime checks however I feel in the case of operations that could
have a narrowing issue using a failable constructor makes sense. It puts
you control in how to deal with a narrowing error. You could assert if you
so want (much like what happens now) or you could deal with the edge case.
Swift makes the code to deal with a failable initializer generally trivial.

It makes you think about this very real pitfall (in some problem
domains) when going between numerical types.

The issue of why are you using unsigned, etc. is orthogonal to this issue.
If these types exist in the language folks will use them and it should be
safe / consistent for them when they do.

-Shawn

···

On Tue, Feb 16, 2016 at 11:11 AM David Turnbull <dturnbull@gmail.com> wrote:

Can you show some examples where and why you use not-Int types and this is
a problem? What you're suggesting will be a burden to those of us who need
bitwise optimizations or work with C APIs.

My last week was spent reading files with huffman coding. So I had no
choice but to use bitwise operations. My experience is that Swift got this
right (except for "truncatingBitPattern" taking up 25% of an 80 column
line).

So my question is, "why are you not using Int?" There's plenty of use
cases, you just haven't stated yours so we can't understand why the current
system is failing you.

Safety does not mean you can easily write code that crashes once it is

deployed….

var a = [Int](); a[0]=99

That was pretty easy. I don't buy into this argument. If you don't want an
out of bounds error, you either make sure you don't math your way out of
bounds or you check every time before you subscript. I don't see why an
integer conversion should be any different.

-david

Thinking a little more about this how about just adding failable
constructors so it becomes easier to deal with runtime narrowing errors for
those that need it? (that was my main issue I ran across when using these
classes in an early project, I had to put code around things to deal with
the edge case that the library was already obviously doing)

extension UInt16 {
    public init(_ v: UInt8)
    public init(_ v: Int8)
    public init(_ v: Int16)
    public init(_ v: UInt32) // runtime narrowing check,
asserts BOOOM
    public init?(validatingValue: UInt32) // runtime narrowing check,
failable initializer
    public init(truncatingBitPattern: UInt32) // narrowing "fixup"
initializer
    public init(_ v: Int32) // runtime narrowing check,
asserts BOOOM
    public init?(validatingValue: UInt32) // runtime narrowing check,
failable initializer
    public init(truncatingBitPattern: Int32) // narrowing "fixup"
initializer
...
    public init(bitPattern: Int16) // I know what I doing!
(aka live dangerously)
}

Ideally – to me – you would want the failable initializers to be the
default ones available with the boom crash ones being something you could
switch to use much like the the other special "i know what I am doing
ones". Not sure of the naming to use for such an initializer however.

-Shawn

···

On Tue, Feb 16, 2016 at 11:28 AM Shawn Erickson <shawnce@gmail.com> wrote:

I believe you stated that you ran across at least two times that runtime
checks caught a narrowing error (e.g. overflow) in your recent work. I
support runtime checks however I feel in the case of operations that could
have a narrowing issue using a failable constructor makes sense. It puts
you control in how to deal with a narrowing error. You could assert if you
so want (much like what happens now) or you could deal with the edge case.
Swift makes the code to deal with a failable initializer generally trivial.

It makes you think about this very real pitfall (in some problem
domains) when going between numerical types.

The issue of why are you using unsigned, etc. is orthogonal to this issue.
If these types exist in the language folks will use them and it should be
safe / consistent for them when they do.

-Shawn

On Tue, Feb 16, 2016 at 11:11 AM David Turnbull <dturnbull@gmail.com> > wrote:

Can you show some examples where and why you use not-Int types and this
is a problem? What you're suggesting will be a burden to those of us who
need bitwise optimizations or work with C APIs.

My last week was spent reading files with huffman coding. So I had no
choice but to use bitwise operations. My experience is that Swift got this
right (except for "truncatingBitPattern" taking up 25% of an 80 column
line).

So my question is, "why are you not using Int?" There's plenty of use
cases, you just haven't stated yours so we can't understand why the current
system is failing you.

Safety does not mean you can easily write code that crashes once it is

deployed….

var a = [Int](); a[0]=99

That was pretty easy. I don't buy into this argument. If you don't want
an out of bounds error, you either make sure you don't math your way out of
bounds or you check every time before you subscript. I don't see why an
integer conversion should be any different.

-david

Ok one last reply to myself...

public class Int16 {
    public init(_ v: UInt8) {}
    public init(_ v: Int8) {}

    public init?(_ v: UInt16) {...on overflow return nil...}
    public init(assertValue: UInt16) {...on overflow assert...} // I think
we could just drop this
    public init(truncatingValue: UInt16) {...on overflow truncate, alway
positive...}

    public init?(_ v: Int32) {...on overflow return nil...}
    public init(assertValue: Int32) {...on overflow assert...} // I think
we could just drop this
    public init(truncatingValue: Int32) {...on overflow truncate, maintain
sign...}

    public init?(_ v: UInt32) {...on overflow return nil...}
    public init(assertValue: UInt32) {...on overflow assert...} // I think
we could just drop this
    public init(truncatingValue: UInt32) {...on overflow truncate, alway
positive...}

    ...others...

    public init(bitPattern: UInt16) {...close your eyes and copy the
bits...}
}

let unsigned32 = UInt32(UInt16.max + 50)

guard let foo = Int16(unsigned32) else {
    throw Blah ...or... assert("BOOM")
}
...do stuff...

...or...

if let foo = Int16(unsigned32) {
    ...do stuff...
}
else {
    ...handle error...
}

...or...

let foo = Int16(truncatingValue: unsigned32)
...do stuff...

...or...

let foo = Int16(assertValue: unsigned32) //again I think we could just drop
this
...do stuff unless I just went boom...

···

On Tue, Feb 16, 2016 at 11:57 AM Shawn Erickson <shawnce@gmail.com> wrote:

Thinking a little more about this how about just adding failable
constructors so it becomes easier to deal with runtime narrowing errors for
those that need it? (that was my main issue I ran across when using these
classes in an early project, I had to put code around things to deal with
the edge case that the library was already obviously doing)

extension UInt16 {
    public init(_ v: UInt8)
    public init(_ v: Int8)
    public init(_ v: Int16)
    public init(_ v: UInt32) // runtime narrowing
check, asserts BOOOM
    public init?(validatingValue: UInt32) // runtime narrowing
check, failable initializer
    public init(truncatingBitPattern: UInt32) // narrowing "fixup"
initializer
    public init(_ v: Int32) // runtime narrowing
check, asserts BOOOM
    public init?(validatingValue: UInt32) // runtime narrowing
check, failable initializer
    public init(truncatingBitPattern: Int32) // narrowing "fixup"
initializer
...
    public init(bitPattern: Int16) // I know what I doing!
(aka live dangerously)
}

Ideally – to me – you would want the failable initializers to be the
default ones available with the boom crash ones being something you could
switch to use much like the the other special "i know what I am doing
ones". Not sure of the naming to use for such an initializer however.

-Shawn

On Tue, Feb 16, 2016 at 11:28 AM Shawn Erickson <shawnce@gmail.com> wrote:

I believe you stated that you ran across at least two times that runtime
checks caught a narrowing error (e.g. overflow) in your recent work. I
support runtime checks however I feel in the case of operations that could
have a narrowing issue using a failable constructor makes sense. It puts
you control in how to deal with a narrowing error. You could assert if you
so want (much like what happens now) or you could deal with the edge case.
Swift makes the code to deal with a failable initializer generally trivial.

It makes you think about this very real pitfall (in some problem
domains) when going between numerical types.

The issue of why are you using unsigned, etc. is orthogonal to this
issue. If these types exist in the language folks will use them and it
should be safe / consistent for them when they do.

-Shawn

On Tue, Feb 16, 2016 at 11:11 AM David Turnbull <dturnbull@gmail.com> >> wrote:

Can you show some examples where and why you use not-Int types and this
is a problem? What you're suggesting will be a burden to those of us who
need bitwise optimizations or work with C APIs.

My last week was spent reading files with huffman coding. So I had no
choice but to use bitwise operations. My experience is that Swift got this
right (except for "truncatingBitPattern" taking up 25% of an 80 column
line).

So my question is, "why are you not using Int?" There's plenty of use
cases, you just haven't stated yours so we can't understand why the current
system is failing you.

Safety does not mean you can easily write code that crashes once it is

deployed….

var a = [Int](); a[0]=99

That was pretty easy. I don't buy into this argument. If you don't want
an out of bounds error, you either make sure you don't math your way out of
bounds or you check every time before you subscript. I don't see why an
integer conversion should be any different.

-david

I launched a similar thread just a few days ago. [swift-evolution] Make integer conversion initializers failable

Félix

···

Le 16 févr. 2016 à 15:37:17, Shawn Erickson via swift-evolution <swift-evolution@swift.org> a écrit :

Ok one last reply to myself...

public class Int16 {
    public init(_ v: UInt8) {}
    public init(_ v: Int8) {}
    
    public init?(_ v: UInt16) {...on overflow return nil...}
    public init(assertValue: UInt16) {...on overflow assert...} // I think we could just drop this
    public init(truncatingValue: UInt16) {...on overflow truncate, alway positive...}
    
    public init?(_ v: Int32) {...on overflow return nil...}
    public init(assertValue: Int32) {...on overflow assert...} // I think we could just drop this
    public init(truncatingValue: Int32) {...on overflow truncate, maintain sign...}
    
    public init?(_ v: UInt32) {...on overflow return nil...}
    public init(assertValue: UInt32) {...on overflow assert...} // I think we could just drop this
    public init(truncatingValue: UInt32) {...on overflow truncate, alway positive...}
    
    ...others...
    
    public init(bitPattern: UInt16) {...close your eyes and copy the bits...}
}

let unsigned32 = UInt32(UInt16.max + 50)

guard let foo = Int16(unsigned32) else {
    throw Blah ...or... assert("BOOM")
}
...do stuff...

...or...

if let foo = Int16(unsigned32) {
    ...do stuff...
}
else {
    ...handle error...
}

...or...

let foo = Int16(truncatingValue: unsigned32)
...do stuff...

...or...

let foo = Int16(assertValue: unsigned32) //again I think we could just drop this
...do stuff unless I just went boom...

On Tue, Feb 16, 2016 at 11:57 AM Shawn Erickson <shawnce@gmail.com <mailto:shawnce@gmail.com>> wrote:
Thinking a little more about this how about just adding failable constructors so it becomes easier to deal with runtime narrowing errors for those that need it? (that was my main issue I ran across when using these classes in an early project, I had to put code around things to deal with the edge case that the library was already obviously doing)

extension UInt16 {
    public init(_ v: UInt8)
    public init(_ v: Int8)
    public init(_ v: Int16)
    public init(_ v: UInt32) // runtime narrowing check, asserts BOOOM
    public init?(validatingValue: UInt32) // runtime narrowing check, failable initializer
    public init(truncatingBitPattern: UInt32) // narrowing "fixup" initializer
    public init(_ v: Int32) // runtime narrowing check, asserts BOOOM
    public init?(validatingValue: UInt32) // runtime narrowing check, failable initializer
    public init(truncatingBitPattern: Int32) // narrowing "fixup" initializer
...
    public init(bitPattern: Int16) // I know what I doing! (aka live dangerously)
}

Ideally – to me – you would want the failable initializers to be the default ones available with the boom crash ones being something you could switch to use much like the the other special "i know what I am doing ones". Not sure of the naming to use for such an initializer however.

-Shawn

On Tue, Feb 16, 2016 at 11:28 AM Shawn Erickson <shawnce@gmail.com <mailto:shawnce@gmail.com>> wrote:
I believe you stated that you ran across at least two times that runtime checks caught a narrowing error (e.g. overflow) in your recent work. I support runtime checks however I feel in the case of operations that could have a narrowing issue using a failable constructor makes sense. It puts you control in how to deal with a narrowing error. You could assert if you so want (much like what happens now) or you could deal with the edge case. Swift makes the code to deal with a failable initializer generally trivial.

It makes you think about this very real pitfall (in some problem domains) when going between numerical types.

The issue of why are you using unsigned, etc. is orthogonal to this issue. If these types exist in the language folks will use them and it should be safe / consistent for them when they do.

-Shawn

On Tue, Feb 16, 2016 at 11:11 AM David Turnbull <dturnbull@gmail.com <mailto:dturnbull@gmail.com>> wrote:
Can you show some examples where and why you use not-Int types and this is a problem? What you're suggesting will be a burden to those of us who need bitwise optimizations or work with C APIs.

My last week was spent reading files with huffman coding. So I had no choice but to use bitwise operations. My experience is that Swift got this right (except for "truncatingBitPattern" taking up 25% of an 80 column line).

So my question is, "why are you not using Int?" There's plenty of use cases, you just haven't stated yours so we can't understand why the current system is failing you.

Safety does not mean you can easily write code that crashes once it is deployed….

var a = [Int](); a[0]=99

That was pretty easy. I don't buy into this argument. If you don't want an out of bounds error, you either make sure you don't math your way out of bounds or you check every time before you subscript. I don't see why an integer conversion should be any different.

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

Yes, this is exactly my proposal!

Thanks,

Stéphane

···

On 16 Feb 2016, at 22:20, Félix Cloutier via swift-evolution <swift-evolution@swift.org> wrote:

I launched a similar thread just a few days ago. [swift-evolution] Make integer conversion initializers failable

Félix

Le 16 févr. 2016 à 15:37:17, Shawn Erickson via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

Ok one last reply to myself...

public class Int16 {
    public init(_ v: UInt8) {}
    public init(_ v: Int8) {}
    
    public init?(_ v: UInt16) {...on overflow return nil...}
    public init(assertValue: UInt16) {...on overflow assert...} // I think we could just drop this
    public init(truncatingValue: UInt16) {...on overflow truncate, alway positive...}
    
    public init?(_ v: Int32) {...on overflow return nil...}
    public init(assertValue: Int32) {...on overflow assert...} // I think we could just drop this
    public init(truncatingValue: Int32) {...on overflow truncate, maintain sign...}
    
    public init?(_ v: UInt32) {...on overflow return nil...}
    public init(assertValue: UInt32) {...on overflow assert...} // I think we could just drop this
    public init(truncatingValue: UInt32) {...on overflow truncate, alway positive...}
    
    ...others...
    
    public init(bitPattern: UInt16) {...close your eyes and copy the bits...}
}

let unsigned32 = UInt32(UInt16.max + 50)

guard let foo = Int16(unsigned32) else {
    throw Blah ...or... assert("BOOM")
}
...do stuff...

...or...

if let foo = Int16(unsigned32) {
    ...do stuff...
}
else {
    ...handle error...
}

...or...

let foo = Int16(truncatingValue: unsigned32)
...do stuff...

...or...

let foo = Int16(assertValue: unsigned32) //again I think we could just drop this
...do stuff unless I just went boom...

On Tue, Feb 16, 2016 at 11:57 AM Shawn Erickson <shawnce@gmail.com <mailto:shawnce@gmail.com>> wrote:
Thinking a little more about this how about just adding failable constructors so it becomes easier to deal with runtime narrowing errors for those that need it? (that was my main issue I ran across when using these classes in an early project, I had to put code around things to deal with the edge case that the library was already obviously doing)

extension UInt16 {
    public init(_ v: UInt8)
    public init(_ v: Int8)
    public init(_ v: Int16)
    public init(_ v: UInt32) // runtime narrowing check, asserts BOOOM
    public init?(validatingValue: UInt32) // runtime narrowing check, failable initializer
    public init(truncatingBitPattern: UInt32) // narrowing "fixup" initializer
    public init(_ v: Int32) // runtime narrowing check, asserts BOOOM
    public init?(validatingValue: UInt32) // runtime narrowing check, failable initializer
    public init(truncatingBitPattern: Int32) // narrowing "fixup" initializer
...
    public init(bitPattern: Int16) // I know what I doing! (aka live dangerously)
}

Ideally – to me – you would want the failable initializers to be the default ones available with the boom crash ones being something you could switch to use much like the the other special "i know what I am doing ones". Not sure of the naming to use for such an initializer however.

-Shawn

On Tue, Feb 16, 2016 at 11:28 AM Shawn Erickson <shawnce@gmail.com <mailto:shawnce@gmail.com>> wrote:
I believe you stated that you ran across at least two times that runtime checks caught a narrowing error (e.g. overflow) in your recent work. I support runtime checks however I feel in the case of operations that could have a narrowing issue using a failable constructor makes sense. It puts you control in how to deal with a narrowing error. You could assert if you so want (much like what happens now) or you could deal with the edge case. Swift makes the code to deal with a failable initializer generally trivial.

It makes you think about this very real pitfall (in some problem domains) when going between numerical types.

The issue of why are you using unsigned, etc. is orthogonal to this issue. If these types exist in the language folks will use them and it should be safe / consistent for them when they do.

-Shawn

On Tue, Feb 16, 2016 at 11:11 AM David Turnbull <dturnbull@gmail.com <mailto:dturnbull@gmail.com>> wrote:
Can you show some examples where and why you use not-Int types and this is a problem? What you're suggesting will be a burden to those of us who need bitwise optimizations or work with C APIs.

My last week was spent reading files with huffman coding. So I had no choice but to use bitwise operations. My experience is that Swift got this right (except for "truncatingBitPattern" taking up 25% of an 80 column line).

So my question is, "why are you not using Int?" There's plenty of use cases, you just haven't stated yours so we can't understand why the current system is failing you.

Safety does not mean you can easily write code that crashes once it is deployed….

var a = [Int](); a[0]=99

That was pretty easy. I don't buy into this argument. If you don't want an out of bounds error, you either make sure you don't math your way out of bounds or you check every time before you subscript. I don't see why an integer conversion should be any different.

-david
_______________________________________________
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