4 ms·
Now Go has everything I need in a programming language!
by mseepgood 5y ago
Now Go has everything I need in a programming language!
- drdaeman 5y agoNot for me. There is no ?: ternary operator. Having to write 6 additional lines of code for each tiny conditional sucks. It's not frequent, I think I've only had a single case in a few years where I had difficulty working around, but when it happens - it's not fun. err := h(cond(x) ? f(x) : g(x)) vs var temp T if cond(x) { temp = f(x) } else { temp = g(x) } err := h(temp) Hopefully, this can be improved with generics, e.g. now it should be possible to create e.g. `func Coalesce (type T) (...args T) T` function to simplify common scenarios.
- crtc 5y agoThis is by design: https://go.dev/doc/faq#Does_Go_have_a_ternary_form https://go.dev/doc/faq#Does_Go_have_a_ternary_form Ken Thompson added ?: to B / C and then he took it from us in Go due to the wisdom he gathered in between.
- RodgerTheGreat 5y ago> A language needs only one conditional control flow construct. And yet, Go has a switch statement.
- MrDOS 5y agoNot only that, but despite all of the other syntactic sugar Go is lacking (usually sorely, such as a “try” error handler), the switch statement is really just an “if” statement in disguise. var someVar, anotherVar string // ... switch { case someVar == "whatever": fmt.Println("Tell me how, exactly,") case anotherVar == "nope": fmt.Println("this compiles to a jump table?") default: fmt.Println("Spoiler: it doesn't.") }
- acuozzo 5y ago> the switch statement is really just an “if” statement in disguise If the switch is over a fixed set of strings, then can't the backend generate a perfect hash function ala gperf and then proceed to use the computed hash value to implement a jump table? Also, FWIW, the only compiler backends I've ever seen blindly emit a jump table all died in the '80s. Jump tables aren't always the fastest choice: https://www.cipht.net/2017/10/03/are-jump-tables-always-fastest.html https://www.cipht.net/2017/10/03/are-jump-tables-always-fast...
- morelisp 5y agoGo currently uses a binary search for integer switches (and I believe serial comparisons otherwise). Jump tables are in development and likely to appear around 1.19 or 1.20. As you say, there's a lot of edge cases to consider when figuring out whether a table or comparisons are the better choice. https://go-review.googlesource.com/c/go/+/357330/ https://go-review.googlesource.com/c/go/+/357330/
- MrDOS 5y ago> can't the backend (...) implement a jump table? Note that my example “switches” over two independent variables. Even if the Go compiler did generate a table, for this example it would really be generating two tables: and then we're back to the “how is this better than an `if`?” question.
- int_19h 5y agoAnd loops!
- orangecat 5y agoThe if-else form, although longer, is unquestionably clearer. I disagree: - The variable name is repeated three times, increasing visual clutter and the chance of typos. - The variable can't declared immutable. In Java/JS/Dart/etc it's nice to know that after "const x = foo ? bar : baz", x won't change. And you don't even have to add a new operator, Rust and Kotlin get these benefits with an expression form of if/else.
- ngrilly 5y agoIf you only had a single case in a few years, then why would you need a ternary operator? Your anecdotal data experience is actually confirming their decision to leave this out of the language.
- drdaeman 5y agoFor that one rare occasion, obviously. I can't find that code but IIRC it was me working with with AWS SDK and it infamously exposes all sort of stuff as *strings and *ints because there is no sane way to have Maybe<string> in Go. So I had a whole screen of those `if resp.foo != nil { v = *resp.foo } else { v = fallback }`, sometimes deeply nested (for resp.foo.bar[idx].baz, because no null chaining operator either). Yes, a purist may argue that's AWS SDK problem and they should've went with something else, and that Go's decision to not have ?: still stands true. Sadly, I haven't had luxury to wait another decade until Amazon maybe sorts it out, yet I still wanted to write something I could read back. I don't disagree typical use results in poor readability. I'm not gonna put those ?:s just about everywhere. Yet I do think that there are sometimes infrequent exceptions where ternary would've been objectively better.
- Mawr 5y agoI agree that the latter version is too verbose, but if the alternative is this: err := h(cond(x) ? f(x) : g(x)) ... then I'd much rather stick with the verbosity. There's way too much going on in a single line here. I'd rather have if statements be expressions, with gofmt-enforced line breaks: err := h( if cond(x) { f(x) } else { g(x) }, ) No unnecessary temp variables and no stuffing everything into one line.
- collaborative 5y agoI love stuffing things into one-liners. Not hard to see what is happening if you understand it enough Reason is I prefer to move my eye balls than scroll the screen. Too many lines and you forget what preceded what you're seeing or have to keep scrolling to make sense of everything
- noselasd 5y agoWhile you perhaps would not want to write the verbose version, I certainly would have much more fun reading and debugging the verbose version.
- stouset 5y agoFrankly I'd kill for go statements to be expressions, which essentially solves this. foo := if a { b } else { c }
- Beltalowda 5y agoDoesn't exactly win any awards for elegance, but: err := h(map[bool]func(T){true: f, false: g}[cond(x)](x)) You're probably not going to want to use this though, although I've used the map[bool]T trick in some simpler examples.
- jatone 5y agovar temp func(x) T = g if cond(x) { temp = f } err := h(temp(x))