Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: Go 2: Use an array as a ExpressionList for switch case statement #58868

Closed
northbear opened this issue Mar 4, 2023 · 11 comments
Closed
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal Proposal-FinalCommentPeriod v2 An incompatible library change
Milestone

Comments

@northbear
Copy link

it would be good to have an able to "unpack" array for switch/case statement in the same way as it can be for variadic function parameters. Example:

var TrueValues []string = []string{"yes", "true", "1"}
var FalseValues []string = []string{"no", "false", "0"}

func Convert(v string) (bool, error) {
    switch v {
    case TrueValues...: 
        return true, nil
    case FalseValues...: 
        return false, nil
    default:
        return true, fmt.Errorf("incorrect value: %s", v)
    }
}

Or maybe make another builtin function (kinda anyof or in in the same way as range) that could be used also with if statement.

func ValidateTrue(s string) bool {
    if s in TrueValues {
        return true
    }
    return false
}
@gopherbot gopherbot added this to the Proposal milestone Mar 4, 2023
@earthboundkid
Copy link
Contributor

Go 1.21 will have slices.Contains(TrueValues, s).

@ianlancetaylor
Copy link
Contributor

We already support case "yes", "true", "1". Is using a variable that much better?

@ianlancetaylor ianlancetaylor added LanguageChange Suggested changes to the Go language v2 An incompatible library change labels Mar 5, 2023
@northbear
Copy link
Author

northbear commented Mar 5, 2023

Hi @ianlancetaylor
It's exactly how I use it right now. But, sometimes this lists can be pretty long. Another point is that it often happens that you need to reuse the list in other parts of code.
It may be more convenient to define similar arrays in const or var sections and reuse it everywhere.

@northbear
Copy link
Author

@carlmjohnson
Yeah, it's great! But for my taste is too long for a pretty basic function of seeking an item in a list. Right now I'm using a generic function for it. Kinda

func belongs[ T comparable ](item T, ar []T) bool {
    for _, v := range ar {
        if v == item {
            return true
        }
    }
    return false
}

It is much shorter and doesn't require jumping to import section to add a package name.
Also I think It would be good to implement vector operations on slices or arrays. But I feel it may be against golang philosophy keeping the language as simple as possible.
Anyway thanks...

@fzipp
Copy link
Contributor

fzipp commented Mar 5, 2023

It is much shorter

If you like your name better you can do

var belongs = slices.Contains

and doesn't require jumping to import section to add a package name.

Have a look at https://pkg.go.dev/golang.org/x/tools/cmd/goimports

@northbear
Copy link
Author

@fzipp yeah, usually there is more than one way to solve an issue. it's why we love Go.
I know goimports, it's ok. I'm just waiting when it becomes a part of Golang standard tools.

The only feature that I miss there is a replacing unused variables with underscore. But switching this error to a warning at least on stage of development would be way better. But it's not the case of this proposal. I'm sure it's already proposed by other guys.

@northbear
Copy link
Author

So I meant it's not about function names. it's for a DRY principle. Any implementation will be ok for me.
I see dislikes here but don't see any reasonable motivation of it.

@thediveo
Copy link

thediveo commented Mar 6, 2023

With the current language design, the compiler knows all values and creates appropriate optimizations. With your proposal, the compiler doesn't know almost anything anymore. How would you like your "match test"? Linear, bisecting, ...? Personally, I don't see how this convenience proposal improves Go without at in its current state having a lot of open questions. Especially performance-wise, because it is totally unclear how to deal with the arrays/slices in a general, yet performing way.

I can imagine that this might have been the reasons for downvotes, but that's just my guess.

@northbear
Copy link
Author

@thediveo I don't see how it can break existent optimizations. I didin't check a golang code generator, but actually there are two ways to handle 'case'-statement with multiple expressions: One is an expanding one 'case'-statement with multiple expressions to several cases with single expression and convert in conditional jump of ASM code. Second is an evaluating list of expressions to an internal array of values and make seek of a matching value.
In both case there is no much place for optimizations. And taking a values from a list provided explicitly doesn't break anything here. Moreover, arrays keep already evaluated data, so it can be handled much easier.
With slices it's a bit more tricky. But I'm not sure that using slices as a case expression is demanded much.

@ianlancetaylor
Copy link
Contributor

This amounts to another way to do something that the language can already do. The benefits of this new feature don't outweigh the significant cost of changing the language.

Therefore this is a likely decline. Leaving open for three weeks for final comments.

@northbear
Copy link
Author

@ianlancetaylor It can be closed. Anyway it's intended to be a kind of syntax sugar. thanks...

@golang golang locked and limited conversation to collaborators Apr 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge LanguageChange Suggested changes to the Go language Proposal Proposal-FinalCommentPeriod v2 An incompatible library change
Projects
None yet
Development

No branches or pull requests

6 participants