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: cmp: Add Cond[T any](cond bool, ifval, elseval T) T #66062

Open
earthboundkid opened this issue Mar 1, 2024 · 10 comments
Open

proposal: cmp: Add Cond[T any](cond bool, ifval, elseval T) T #66062

earthboundkid opened this issue Mar 1, 2024 · 10 comments
Labels
Milestone

Comments

@earthboundkid
Copy link
Contributor

Proposal Details

Recently, #64825 was marked as a likely declined proposal. This is an alternate proposal with a similar goal: to make writing simple, commonly used bool conversions easier. Here is the proposed addition:

func Cond[T any](cond bool, ifval, elseval T) T {
   if cond {
     return ifval
  }
  return elseval
}

I have been using a helper like this in my code since Go 1.18 and I find it convenient to have. The bool conversions mentioned in #64825 would be cmp.Cond(b, 1, 0) with this alternative proposal.

@seh
Copy link
Contributor

seh commented Mar 1, 2024

This is analogous to a ternary conditional operator, but it evaluates its consequent and alternative values eagerly, which makes it less useful. However, I understand that we're not likely to see such an operator in Go any time soon.

@Merovius
Copy link
Contributor

Merovius commented Mar 1, 2024

I'll note that it should be

func Cond[T any, B ~bool](cond B, ifval, elseval T) T

@x0wllaar
Copy link

x0wllaar commented Mar 1, 2024

I mean, you can make it lazy if you want: https://go.dev/play/p/D9BDFlGF-Uf

@earthboundkid
Copy link
Contributor Author

earthboundkid commented Mar 1, 2024

I'll note that it should be

func Cond[T any, B ~bool](cond B, ifval, elseval T) T

I don't think it's worthwhile to make it generic over bool types. If it were builtin, sure.

Of course, if it were builtin, it should be lazy.

@ianlancetaylor ianlancetaylor moved this to Incoming in Proposals Mar 1, 2024
@Merovius
Copy link
Contributor

Merovius commented Mar 1, 2024

I disagree. bool is a declared type and it would be pretty frustrating, having to convert it if you happen to use a user-declared boolean type (this is different for slices, for example, where type MySlice []T is assignable to []T). Not that declaring boolean types is incredibly common, but it's not unheard of. And the cost seems close to zero. For a standard library function, it seems like a no-brainer to me, that we'd want to make it as general as we can.

@Jorropo
Copy link
Member

Jorropo commented Mar 2, 2024

I mean, you can make it lazy if you want: https://go.dev/play/p/D9BDFlGF-Uf

That is impressive extends to go through to not write a simpler if check.

@zigo101
Copy link

zigo101 commented Mar 2, 2024

#36303 proposal: new builtin to pick from one of two values

#37739 proposal: Go 2: lazy values

Zig's solution:

_ = if (cond) ifval else elseval;

@Jorropo
Copy link
Member

Jorropo commented Mar 2, 2024

Python's solution:

_ = ifval if cond else elseval

Skips () but is not intuitive (it's forced by parser limitations and falls out of the requirements but it's still weird).

@Jorropo
Copy link
Member

Jorropo commented Mar 2, 2024

Of course, if it were builtin, it should be lazy.

👎 this would be weird magic, currently builtins only cheat about the type system (generics before we had generics and ~string~[]byte signature overload) but not control flow. The value of adding control flow cheats so you can save a couple of ⏎ presses is low to me.

@earthboundkid
Copy link
Contributor Author

I had not seen #36303 before. Looks like the builtin version of this has been rejected. I still think the cmp.Cond version is marginally convenient and fits with the general vibe of package cmp.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Incoming
Development

No branches or pull requests

7 participants