Re: [go-nuts] Re: Go 2 suggestion - Types like "int?"

2017-08-26 Thread gurpartap
Relevant Tweet: https://twitter.com/casio_juarez/status/900374362401914881

On Wednesday, August 23, 2017 at 1:42:07 AM UTC+5:30, Joe Tsai wrote:
>
> What you are asking for is captured in https://golang.org/issue/7054
>
> On Tuesday, August 22, 2017 at 12:28:41 PM UTC-7, Steven Blenkinsop wrote:
>>
>> Other places where Go relies on every type having a zero value:
>>
>> // Making slices with non-zero length.
>> s := make([]*int, 10)
>>
>> // Reslicing a slice beyond its length.
>> s := make([]*int, 0, 10)[:10]
>>
>> // Eliding fields from a composite literal.
>> p := struct { x: int; y: *int } { x: 5 }
>> s := []*int { 10: new(int) }
>>
>> // Initializing an array programmatically.
>> var arr [10]*int
>> for i := range arr { ... }
>>
>> // Accessing a non-existent map entry.
>> v := m["non existent"]
>>
>> // Reading from a closed channel.
>> v := <-ch
>>
>> // Comma-ok.
>> // Without zero values, the type of `v` is in each case
>> // something like `ok ? *int : uninitialized`.
>> v, ok := m["string"]
>> v, ok := i.(*int)
>> v, ok := <-ch
>>
>>
>> On Tue, Aug 22, 2017 at 8:59 AM  wrote:
>>
>>> I would like to echo on Tong Sun's suggestion here. I know his isn't an 
>>> "experience report" per se, but a suggestion worth building on, for those 
>>> who're wishful of optionals in Go.
>>>
>>> The case mentioned might be immediately solvable by just using a pointer 
>>> to the variable, which gives you the ability to assign nil (json null) to 
>>> it. However, *T is *not* syntactic sugar for Optional. Pointers come 
>>> across as "just as good as optionals" when needed because we don't have 
>>> another [built-in] option. Not to mention, pointers have more than 
>>> nil-assignability to them.
>>>
>>> I understand that we can just write a generic generator for Optional 
>>> for whatever type we want an optional wrapper for. This is something I've 
>>> always done when absolutely needed (most of the time with proto3 Protobuf).
>>>
>>> func main() {
>>> msg := pboptional.NewString()
>>>
>>> fmt.Println("msg:", msg).// => msg: nil
>>>
>>> msg.From("hello world")
>>>
>>> fmt.Println("msg:", msg) // => msg: Optional("hello world")
>>>
>>> if msg, ok := msg.Unwrap(); ok {
>>> // some
>>> fmt.Println("msg:", msg) // => msg: hello world
>>> } else {
>>> // none
>>> fmt.Println("msg is nil")
>>> }
>>> }
>>>
>>> There are obvious advantages to using optionals, including safely 
>>> defining variable. However, on the contrary, Go is currently, and by-design 
>>> so, not in the best shape to adopt optional types. For optionals to be a 
>>> viable in core, non-optionals would have to (?) guarantee a value (and not 
>>> just assumed zero-value when left uninitialized). This is for the compiler 
>>> to deliver the type-safety promise of optionals *and* non-optionals. In 
>>> other words, it means that we would have to not allow uninitialized types 
>>> to be zero-value. I mean, what good is supporting optional types, if the 
>>> non-optionals don't require you to set their values?
>>>
>>> Consider this currently valid Go code:
>>>
>>> func getAge() (int, error) {
>>> var age int
>>> return age, errors.New("ERR") // age is assumed zero-value
>>> }
>>>
>>> func main() {
>>> age, err := getAge() // => 0, ERR
>>> }
>>>
>>> With optionals implemented (how I'm imagining), this would become:
>>>
>>> // uninitialized non-optional should not compile
>>> // i.e. don't assume zero-value
>>> func getAge() (int, error) {
>>> var age int
>>> return age, errors.New("ERR") // => compile error: variable age is 
>>> not initialized
>>> }
>>>
>>> // this should work instead
>>> func getAge() (int?, error) {
>>> var age int?
>>> return nil, errors.New("ERR")
>>> }
>>>
>>> func main() {
>>> age, err := getAge() // => Optional(nil), ERR
>>> }
>>>
>>> But every method that also returns an error, should not necessarily have 
>>> an accompanied optional type, like `(int?, error)`. There's so much in Go 
>>> that can be nil (or nil like zero-values), and isn't necessarily fit to be 
>>> considered optional, like nil interfaces and pointers. 
>>>
>>> We're also going to have to reconsider the phrase "errors are just 
>>> values" if we want to pair non-optional types with error in the return 
>>> types. Take the following suggestion (inspired from Swift):
>>>
>>> func getAge() (int, throws error) {
>>> var age int
>>> throw errors.New("ERR")
>>> // we're not returning anything and it compiles
>>> // i.e. throw *is* return but only for error
>>> }
>>>
>>> func main() {
>>> age := try getAge() // => panic("ERR")
>>> }
>>>
>>> func main() {
>>> // although getAge() returns a non-optional, it
>>> // gets is automatically wrapped in an optional
>>> // when using `try?`.
>>> //
>>> // basically we're trading 

Re: [go-nuts] Re: Go 2 suggestion - Types like "int?"

2017-08-22 Thread thebrokentoaster
What you are asking for is captured in https://golang.org/issue/7054

On Tuesday, August 22, 2017 at 12:28:41 PM UTC-7, Steven Blenkinsop wrote:
>
> Other places where Go relies on every type having a zero value:
>
> // Making slices with non-zero length.
> s := make([]*int, 10)
>
> // Reslicing a slice beyond its length.
> s := make([]*int, 0, 10)[:10]
>
> // Eliding fields from a composite literal.
> p := struct { x: int; y: *int } { x: 5 }
> s := []*int { 10: new(int) }
>
> // Initializing an array programmatically.
> var arr [10]*int
> for i := range arr { ... }
>
> // Accessing a non-existent map entry.
> v := m["non existent"]
>
> // Reading from a closed channel.
> v := <-ch
>
> // Comma-ok.
> // Without zero values, the type of `v` is in each case
> // something like `ok ? *int : uninitialized`.
> v, ok := m["string"]
> v, ok := i.(*int)
> v, ok := <-ch
>
>
> On Tue, Aug 22, 2017 at 8:59 AM  wrote:
>
>> I would like to echo on Tong Sun's suggestion here. I know his isn't an 
>> "experience report" per se, but a suggestion worth building on, for those 
>> who're wishful of optionals in Go.
>>
>> The case mentioned might be immediately solvable by just using a pointer 
>> to the variable, which gives you the ability to assign nil (json null) to 
>> it. However, *T is *not* syntactic sugar for Optional. Pointers come 
>> across as "just as good as optionals" when needed because we don't have 
>> another [built-in] option. Not to mention, pointers have more than 
>> nil-assignability to them.
>>
>> I understand that we can just write a generic generator for Optional 
>> for whatever type we want an optional wrapper for. This is something I've 
>> always done when absolutely needed (most of the time with proto3 Protobuf).
>>
>> func main() {
>> msg := pboptional.NewString()
>>
>> fmt.Println("msg:", msg).// => msg: nil
>>
>> msg.From("hello world")
>>
>> fmt.Println("msg:", msg) // => msg: Optional("hello world")
>>
>> if msg, ok := msg.Unwrap(); ok {
>> // some
>> fmt.Println("msg:", msg) // => msg: hello world
>> } else {
>> // none
>> fmt.Println("msg is nil")
>> }
>> }
>>
>> There are obvious advantages to using optionals, including safely 
>> defining variable. However, on the contrary, Go is currently, and by-design 
>> so, not in the best shape to adopt optional types. For optionals to be a 
>> viable in core, non-optionals would have to (?) guarantee a value (and not 
>> just assumed zero-value when left uninitialized). This is for the compiler 
>> to deliver the type-safety promise of optionals *and* non-optionals. In 
>> other words, it means that we would have to not allow uninitialized types 
>> to be zero-value. I mean, what good is supporting optional types, if the 
>> non-optionals don't require you to set their values?
>>
>> Consider this currently valid Go code:
>>
>> func getAge() (int, error) {
>> var age int
>> return age, errors.New("ERR") // age is assumed zero-value
>> }
>>
>> func main() {
>> age, err := getAge() // => 0, ERR
>> }
>>
>> With optionals implemented (how I'm imagining), this would become:
>>
>> // uninitialized non-optional should not compile
>> // i.e. don't assume zero-value
>> func getAge() (int, error) {
>> var age int
>> return age, errors.New("ERR") // => compile error: variable age is 
>> not initialized
>> }
>>
>> // this should work instead
>> func getAge() (int?, error) {
>> var age int?
>> return nil, errors.New("ERR")
>> }
>>
>> func main() {
>> age, err := getAge() // => Optional(nil), ERR
>> }
>>
>> But every method that also returns an error, should not necessarily have 
>> an accompanied optional type, like `(int?, error)`. There's so much in Go 
>> that can be nil (or nil like zero-values), and isn't necessarily fit to be 
>> considered optional, like nil interfaces and pointers. 
>>
>> We're also going to have to reconsider the phrase "errors are just 
>> values" if we want to pair non-optional types with error in the return 
>> types. Take the following suggestion (inspired from Swift):
>>
>> func getAge() (int, throws error) {
>> var age int
>> throw errors.New("ERR")
>> // we're not returning anything and it compiles
>> // i.e. throw *is* return but only for error
>> }
>>
>> func main() {
>> age := try getAge() // => panic("ERR")
>> }
>>
>> func main() {
>> // although getAge() returns a non-optional, it
>> // gets is automatically wrapped in an optional
>> // when using `try?`.
>> //
>> // basically we're trading error for nil value.
>> age := try? getAge() // => Optional(nil)
>> }
>>
>> func main() {
>> // this is the graceful way to get non-optional result
>> // and handle error, if any.
>> try {
>> age := getAge()
>> } catch error {
>> 

Re: [go-nuts] Re: Go 2 suggestion - Types like "int?"

2017-08-22 Thread Steven Blenkinsop
Other places where Go relies on every type having a zero value:

// Making slices with non-zero length.
s := make([]*int, 10)

// Reslicing a slice beyond its length.
s := make([]*int, 0, 10)[:10]

// Eliding fields from a composite literal.
p := struct { x: int; y: *int } { x: 5 }
s := []*int { 10: new(int) }

// Initializing an array programmatically.
var arr [10]*int
for i := range arr { ... }

// Accessing a non-existent map entry.
v := m["non existent"]

// Reading from a closed channel.
v := <-ch

// Comma-ok.
// Without zero values, the type of `v` is in each case
// something like `ok ? *int : uninitialized`.
v, ok := m["string"]
v, ok := i.(*int)
v, ok := <-ch


On Tue, Aug 22, 2017 at 8:59 AM  wrote:

> I would like to echo on Tong Sun's suggestion here. I know his isn't an
> "experience report" per se, but a suggestion worth building on, for those
> who're wishful of optionals in Go.
>
> The case mentioned might be immediately solvable by just using a pointer
> to the variable, which gives you the ability to assign nil (json null) to
> it. However, *T is *not* syntactic sugar for Optional. Pointers come
> across as "just as good as optionals" when needed because we don't have
> another [built-in] option. Not to mention, pointers have more than
> nil-assignability to them.
>
> I understand that we can just write a generic generator for Optional
> for whatever type we want an optional wrapper for. This is something I've
> always done when absolutely needed (most of the time with proto3 Protobuf).
>
> func main() {
> msg := pboptional.NewString()
>
> fmt.Println("msg:", msg).// => msg: nil
>
> msg.From("hello world")
>
> fmt.Println("msg:", msg) // => msg: Optional("hello world")
>
> if msg, ok := msg.Unwrap(); ok {
> // some
> fmt.Println("msg:", msg) // => msg: hello world
> } else {
> // none
> fmt.Println("msg is nil")
> }
> }
>
> There are obvious advantages to using optionals, including safely defining
> variable. However, on the contrary, Go is currently, and by-design so, not
> in the best shape to adopt optional types. For optionals to be a viable in
> core, non-optionals would have to (?) guarantee a value (and not just
> assumed zero-value when left uninitialized). This is for the compiler to
> deliver the type-safety promise of optionals *and* non-optionals. In
> other words, it means that we would have to not allow uninitialized types
> to be zero-value. I mean, what good is supporting optional types, if the
> non-optionals don't require you to set their values?
>
> Consider this currently valid Go code:
>
> func getAge() (int, error) {
> var age int
> return age, errors.New("ERR") // age is assumed zero-value
> }
>
> func main() {
> age, err := getAge() // => 0, ERR
> }
>
> With optionals implemented (how I'm imagining), this would become:
>
> // uninitialized non-optional should not compile
> // i.e. don't assume zero-value
> func getAge() (int, error) {
> var age int
> return age, errors.New("ERR") // => compile error: variable age is
> not initialized
> }
>
> // this should work instead
> func getAge() (int?, error) {
> var age int?
> return nil, errors.New("ERR")
> }
>
> func main() {
> age, err := getAge() // => Optional(nil), ERR
> }
>
> But every method that also returns an error, should not necessarily have
> an accompanied optional type, like `(int?, error)`. There's so much in Go
> that can be nil (or nil like zero-values), and isn't necessarily fit to be
> considered optional, like nil interfaces and pointers.
>
> We're also going to have to reconsider the phrase "errors are just values"
> if we want to pair non-optional types with error in the return types. Take
> the following suggestion (inspired from Swift):
>
> func getAge() (int, throws error) {
> var age int
> throw errors.New("ERR")
> // we're not returning anything and it compiles
> // i.e. throw *is* return but only for error
> }
>
> func main() {
> age := try getAge() // => panic("ERR")
> }
>
> func main() {
> // although getAge() returns a non-optional, it
> // gets is automatically wrapped in an optional
> // when using `try?`.
> //
> // basically we're trading error for nil value.
> age := try? getAge() // => Optional(nil)
> }
>
> func main() {
> // this is the graceful way to get non-optional result
> // and handle error, if any.
> try {
> age := getAge()
> } catch error {
> fmt.Println(err.Error()) // => ERR
> }
> }
>
> Therefore, if considered, optionals would be a *huge* undertaking to
> implement (and practice) in Go source, while also delivering the promise
> optionals bring.
>
> Let me know if you have a better syntax/suggestion than try catch blocks
> (for returning only an error; no zero-values for