Go: x/website: reword FAQ answer on lack of ternary operator

Created on 27 Dec 2019  路  4Comments  路  Source: golang/go

Go version: 1.13

Introduction

There is recurring proposal about "ternary operator" in the issues (e.g. 1, 2, 3...). This suggestion is in hope to reduce their frequency in future.

Problem

Trouble seems to have two parts:

  1. Go currently intentionally lacks any form of "conditional expression" (either ternary operator or something alike) which could be used inside expression for brevity.
  2. It is not well explained in FAQ, which leads readers to feel protest and even disgust, and, probably, adds to repulsing newcomers :)

It seems currently there is strong opposition to improve the 1-st part. Then perhaps we can improve the 2-nd?

Further I shall copy current text and proposed change to it, but here are main points:

  • motivation uses word UNQUESTIONABLY which is quite questionable approach and have air of insolence, rudeness and doesn't look like professional language
  • another ambiguous word is CLEARER (code without conditional expression) which fails to impress after example of 5 additional lines (with 6-th missing) suggested as substitution
  • motivation refers to unspecified "language designers" who "had seen (what they didn't like) too often" which sounds like decision was someone's fancy, rather than it is based on popular (though still controversial) opinion in community
  • the text doesn't give hope for improvements (alternatives) in future versions
  • proposed workaround example is incomplete (lacking variable definition - which looks like omission by intention to reduce line count) and, perhaps it could be shorter

Supposed update to text

_this variant is a bit lengthy, feel free to suggest cuts_

Currently there is no conditional expression in Go (neither ternary expression, nor anything similar). General workaround is:

var n someType
if expr {
    n = trueVal
} else {
    n = falseVal
}

which often may be shortened to (at the expense of reassignment):

n := falseVal
if expr { n = trueVal }

The reason for absence of conditional expression in Go is the popular opinion among developers (in various languages), that it may lead to poor code readability and style, e.g.:

  • using ternary operator instead of conditional statement (not expression) for brevity;
  • using conditional expressions with very long parts split into several lines;
  • using nested ternary operator which makes precedence ambiguous.

Future versions of Go may introduce some alternatives (like allowing return value from if-else or type parameters for functions which will allow creating custom operator-like function etc.). Please don't post yet another issue "add ternary operator". It is omitted by design and is not going to be added at least in the same form as in C++ and Java.

Current Text

There is no ternary testing operation in Go. You may use the following to achieve the same result:

if expr {
    n = trueVal
} else {
    n = falseVal
}

The reason ?: is absent from Go is that the language's designers had seen the operation used too often to create impenetrably complex expressions. The if-else form, although longer, is unquestionably clearer. A language needs only one conditional control flow construct.

UPD: yet one more about the same #36303

Documentation NeedsInvestigation

Most helpful comment

You should also remove the last line:

A language needs only one conditional control flow construct.

as it doesn't apply to Go.

Go has two control flow constructs: if-else and the switch statement. Indeed, as stated here: https://golang.org/doc/effective_go.html#switch

It's therefore possible鈥攁nd idiomatic鈥攖o write an if-else-if-else chain as a switch.

Compare:

if COND {
  //
} else {
  //
}

to:

switch {
case COND:
  //
default:
  //
}

Both are perfectly valid Go.

All 4 comments

We are go.

// @dmitshur

Is the phrasing "unquestionably clearer" not still present in the proposed change? Personally as someone who questions the clarity of both workarounds versus a one-line ternary expression, I can actually feel my blood pressure go up as I read that.

Also, I'd urge reconsidering this stance. I understand that Go is targeting making code that isn't clever, is easy to read, and is resistant to making and hiding simple subtle mistakes (although variable shadowing and typed nils are pretty big strikes against this goal IMO).

using ternary operator instead of conditional statement (not expression) for brevity;
using conditional expressions with very long parts split into several lines;
using nested ternary operator which makes precedence ambiguous.

Why not just restrict the return values to exclude expressions - include only literals, constants, and variables? It prevents using the expressions for control flow, prevents the creation of lengthy expressions, and prevents the use of nested ternary if since that would be an expression. It would still cover the main cases that are frequently brought up (binary configuration choices and substituting default values for nil / zero values). Then perhaps everyone can be happy?

You should also remove the last line:

A language needs only one conditional control flow construct.

as it doesn't apply to Go.

Go has two control flow constructs: if-else and the switch statement. Indeed, as stated here: https://golang.org/doc/effective_go.html#switch

It's therefore possible鈥攁nd idiomatic鈥攖o write an if-else-if-else chain as a switch.

Compare:

if COND {
  //
} else {
  //
}

to:

switch {
case COND:
  //
default:
  //
}

Both are perfectly valid Go.

Was this page helpful?
0 / 5 - 0 ratings