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 <gurp...@gmail.com <javascript:>> 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<T>. 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<T> 
>> 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 non-optionals).
>>
>> I think an ideal first step would be the community blessing and adopting 
>> en masse some Optional<T> "generator". Second step would be to vouch for 
>> generics with this use case. And then implement an actual generic like 
>> `type Optional<T> struct { Value T; HasValue bool }`. And then perhaps, as 
>> the fourth or so step, we may shape our coding practices to better 
>> understand how all this could be practiced in Go source itself.
>>
>> --
>> Gurpartap Singh
>> https://twitter.com/Gurpartap
>>
>> On Saturday, August 19, 2017 at 8:35:34 PM UTC+5:30, Tong Sun wrote:
>>>
>>> Suggesting C# type syntax like "int*?*" so as to take nil as valid 
>>> value. 
>>>
>>> Currently:
>>>
>>> var i int
>>> i = nil
>>>
>>> will give:
>>>
>>> cannot use nil as type int in assignment
>>>
>>> However, more and more people are using json to transport data, and 
>>> there will be times that json may be invalid. I.e., the "int" type has 
>>> 'null' as input. 
>>>
>>> This is causing tremendous problems for me so far, as I have to jump 
>>> over the hoops to deal with them. 
>>> In C#, just by adding a "?" to the end of the type solves the problem. 
>>>
>>> Please consider. 
>>>
>>>
>>>
>>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to