Skip to content

Instantly share code, notes, and snippets.

@paulp
Last active November 17, 2017 00:00
Show Gist options
  • Save paulp/fca2ce1199abdfb26e69 to your computer and use it in GitHub Desktop.
Save paulp/fca2ce1199abdfb26e69 to your computer and use it in GitHub Desktop.
/** TL;DR Of course we want to savagely truncate our data!
* You know we want that because earlier you saw us cast between
* same-sized types (because you offer no other way) and all casts
* are the same.
*/
package main
import . "fmt"
type Foo int16
func show16(x int16) { Printf("Hello %d\n", x) }
func showFoo(x Foo) { show16(int16(x)) }
func main() {
var x = Foo(1 << 13)
showFoo(x)
}
///// Output: Hello 8192
///// As expected
/***
Now we apply these changes
```
-type Foo int16
+type Foo int32
- var x = Foo(1 << 13)
+ var x = Foo(1 << 20)
```
...anticipating a tiny bit of help from our
"static" "type" "system".
***/
///// Output: Hello 0
///// As expected (this is the bad kind of expected)
// Since people aren't always clear on what the problem is here
// ("you cast it to int16 yourself, why are you blaming go?")
// here's an illustration from another language of how it ought to be.
scala> val x: Int = 1 << 20
x: Int = 1048576
// This is a cast, an explicit programmer-indicated truncation.
scala> x.toShort
res0: Short = 0
// This is an ascription, not a cast, which will fail if the
// type cannot be losslessly widened into the ascripted type.
scala> x: Short
<console>:12: error: type mismatch;
found : Int
required: Short
x: Short
^
// Go creates no distinction between these very different notions,
// forcing casts in all cases. That renders any change to the size
// of a type potentially catastrophic, because there are no
// compilation-failing ascriptions, there is only silent data loss.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment