FAQ
I seem to keep running into situations where I have a function like:

func Thing(...) (interface{}, error) {
}

Which I then do this with:

x, err := Thing()
y := x.(AppropriateType)

I know this is related to the whole generics thing and I'm not interested
in that at all. I'm interested in know why this would be a bad idea to
support:

x, err := Thing().(*Type, error)

Ie. Support a type assertion in the form (T1, T2, ...) that could be
invoked on a multi-type return from a function.

I *did* go and read that ancient epic thread about this, but honestly the
only real objections to this I could see were:

1) .(T) is a multi return type itself, in the form T, ok := blah.(T)

(comment; this isn't relevant; it's already a special case in that you can
x := blah.(T) without having to x, _ := blah.(T)

2) If you support the syntax of func().(T) it's arbitrary which of the
return elements should have the type assertion attached.

(comment: I'm not suggesting this at all; I'm suggesting the type assert
must be of equal length to the function return set)


So, long story short: Can anyone succinctly why this would be either 1)
inconsistent, or 2) a Bad Thing (tm).

There's a lot of redundant code out there that could go away with this.

Cheers,
Doug.

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Search Discussions

  • Nigel Tao at May 18, 2013 at 5:10 pm

    On Fri, May 17, 2013 at 6:36 PM, Dougx wrote:
    x, err := Thing()
    y := x.(AppropriateType)
    In my experience (having written and reviewed Go code since before Go
    was open-sourced), this shouldn't be that common, for at least two
    reasons.


    The first is minor: it is idiomatic is to check the error as soon as
    possible, so I'd normally write:

    x, err := Thing()
    if err != nil {
       // Deal with the error somehow, usually returning.
    }
    // By this point, you don't care about err anymore.
    y := x.(T)


    The second is major: it is also idiomatic that if a function or method
    returns (T, error) and it returns a non-nil error, then the T returned
    is typically the zero value. If T is an interface type, such as
    interface{}, then the zero value is nil. A type assertion like

    y := x.(T)
    or in your proposal
    y, err := Thing().(T, error)

    will panic if x is a nil interface value. So don't do that.

    x, err := Thing().(*Type, error)
    To me, this looks like tuples, but while Go has multiple return
    values, it does not have tuples. You can't say

    tup := Thing()

    and have tup be a 2-tuple of type (interface{}, error).


    Type assertions are also already a little impure: you can already
    write both y := x.(T) and y, ok := x.(T). I'd hesitate to make that
    even more complicated by either allowing some form of the even more
    awkward looking

    y, yok, err, errok := x.(T, error)
    or should that be
    y, err, yok, errok := x.(T, error)

    or by breaking orthogonality by having "comma-ok single-element type
    assertions" and "multiple-element type assertions" but not "comma-ok
    multiple-element type assertions".

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.
  • Dougx at May 19, 2013 at 12:31 am
    Mhm. Thanks, that's a good point. I hadn't considered the implications of
    nil type asserts. Even if you don't asset on the error (trivial to avoid
    with a (*T1, *T2, _) syntax) you'll still end up in situations where you
    try to cast a function return like (nil, nil, error) which will panic even
    though the error is set.

    Pity; I really hate all these pointless type asserts everywhere in my code.
    I may have to start doing more:

    var x T; err := lib.call(blah, blah, &x)

    Annoying though; passing return arguments into functions because you only
    had a single return type was one of the things about C I especially
    disliked.

    Cheers,
    Doug.
    On Sunday, May 19, 2013 1:10:39 AM UTC+8, Nigel Tao wrote:

    On Fri, May 17, 2013 at 6:36 PM, Dougx <douglas...@gmail.com <javascript:>>
    wrote:
    x, err := Thing()
    y := x.(AppropriateType)
    In my experience (having written and reviewed Go code since before Go
    was open-sourced), this shouldn't be that common, for at least two
    reasons.


    The first is minor: it is idiomatic is to check the error as soon as
    possible, so I'd normally write:

    x, err := Thing()
    if err != nil {
    // Deal with the error somehow, usually returning.
    }
    // By this point, you don't care about err anymore.
    y := x.(T)


    The second is major: it is also idiomatic that if a function or method
    returns (T, error) and it returns a non-nil error, then the T returned
    is typically the zero value. If T is an interface type, such as
    interface{}, then the zero value is nil. A type assertion like

    y := x.(T)
    or in your proposal
    y, err := Thing().(T, error)

    will panic if x is a nil interface value. So don't do that.

    x, err := Thing().(*Type, error)
    To me, this looks like tuples, but while Go has multiple return
    values, it does not have tuples. You can't say

    tup := Thing()

    and have tup be a 2-tuple of type (interface{}, error).


    Type assertions are also already a little impure: you can already
    write both y := x.(T) and y, ok := x.(T). I'd hesitate to make that
    even more complicated by either allowing some form of the even more
    awkward looking

    y, yok, err, errok := x.(T, error)
    or should that be
    y, err, yok, errok := x.(T, error)

    or by breaking orthogonality by having "comma-ok single-element type
    assertions" and "multiple-element type assertions" but not "comma-ok
    multiple-element type assertions".
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedMay 18, '13 at 1:36a
activeMay 19, '13 at 12:31a
posts3
users2
websitegolang.org

2 users in discussion

Dougx: 2 posts Nigel Tao: 1 post

People

Translate

site design / logo © 2022 Grokbase