Go Programming Experience
Intermediate
Other Languages Experience
No response
Related Idea
- [ ] Has this idea, or one like it, been proposed before?
- [ ] Does this affect error handling?
- [ ] Is this about generics?
- [ ] Is this change backward compatible? Breaking the Go 1 compatibility guarantee is a large cost and requires a large benefit
Has this idea, or one like it, been proposed before?
No
Does this affect error handling?
No
Is this about generics?
No
Proposal
Summary
This proposal introduces an experimental shorthand syntax for if
statements in Go, allowing a single statement after the condition using a colon (:
) instead of a block with braces — limited to simple statements (excluding return
).
The new syntax is gated under the ifcolon
experiment flag (GOEXPERIMENT=ifcolon
) and aims to improve code readability in straightforward conditional branches by reducing visual noise in cases where braces are otherwise required but semantically unnecessary.
Motivation
Go encourages simplicity and clarity, but even simple one-line if
statements must currently be enclosed in braces, which can introduce visual clutter in otherwise trivial conditions. For example:
if x > 0 {
x = 10
}
This proposal introduces a more concise form:
if x > 0: x = 10
This syntax improves expressiveness in cases where a single, non-returning statement is conditionally executed. The goal is to evaluate whether this form enhances code ergonomics while preserving Go’s readability and structural clarity.
Proposal
Enable a new form of if
statement under the build tag goexperiment.ifcolon
:
if cond: single_stmt
Where single_stmt
is a simple statement (defined below). Semantically, this is equivalent to:
if cond {
single_stmt
}
The colon variant is not intended to replace regular if
blocks, but to supplement them in common short-form cases.
Supported usage
This experimental syntax supports the following simple statements after the colon:
- Assignments, e.g.:
go
if x > 0: x = 10
- Function or method calls, e.g.:
go
if err != nil: log.Fatal(err)
- Control flow statements:
go
if x > 10: break
if x == 0: continue
Declarations (such as var
, const
, or type
) and compound statements (blocks or multiple statements) are not supported.
Compatibility
The change is fully backward compatible. It is hidden behind the GOEXPERIMENT=ifcolon
flag and gated via:
- Parser checks in
go/parser
andcmd/compile/internal/syntax
- A corresponding boolean in
internal/goexperiment
No existing Go code is affected by this change.
Examples
Simple reassignment:
x := 5
if x > 0: x = 10
Loop control:
for i := 0; i < 10; i++ {
if i % 2 == 0: continue
if i == 7: break
fmt.Println(i)
}
Function call:
if ready: notify()
Labeled break:
Outer:
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
if j == 2: break Outer
}
}
Implementation status
- Parser support is implemented in both the
go/parser
and compiler frontend. - Tests are added under
test/ifcolon.go
and guarded by//go:build goexperiment.ifcolon
- Flag is declared in
internal/goexperiment.Flags
Testing
A sample test case validating the syntax and control flow behaviors:
func main() {
count := 0
if true: count++
if true: count = 10
for i := 0; i < 5; i++ {
if i == 2: continue
if i == 4: break
}
Outer:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if j == 1: break Outer
}
}
fn := func(x *int) {
*x = 42
}
if true: fn(&count)
}
Drawbacks
- Increased grammar complexity (though minimal and isolated).
Conclusion
This experimental syntax explores compactness for simple conditional execution in Go. With strict scoping and an opt-in flag, it provides an ergonomic improvement opportunity without compromising Go’s core principles.
Language Spec Changes
No response
Informal Change
No response
Is this change backward compatible?
No
Orthogonality: How does this change interact or overlap with existing features?
No response
Would this change make Go easier or harder to learn, and why?
No response
Cost Description
No response
Changes to Go ToolChain
No response
Performance Costs
No response
Prototype
No response
Comment From: Jorropo
Many similar proposals like #62434 #27135 have been refused.
This proposal is different that it adds :
but that doesn't address:
the decision that there are no 1-line if statements is done.
https://github.com/golang/go/issues/27135#issuecomment-422889166
Comment From: gopherbot
Change https://go.dev/cl/688755 mentions this issue: cmd/compile, go/parser: add experiment for
if cond: stmtsyntax
Comment From: gabyhelp
Related Issues
- proposal: Go 2: Single line `if` variant for returns and other jump statements #62434 (closed)
- proposal: Go 2: error handling in one line #57547 (closed)
- proposal: Go 2: add syntax to repeat a Condition check for different StatementLists #27075 (closed)
- Proposal: Support inline "if" statement syntax #32860 (closed)
- proposal: Go 2: Short statement in switch #56115 (closed)
- proposal: spec: for/else block #73857 (closed)
- proposal: spec: finer control of variable scope in if (\& other) statements #70337 (closed)
- spec: add "with" conditional branch #68968 (closed)
- proposal: Go2: error handling shortening #62378 (closed)
- proposal: Go 2: spec: conditional-assign (?=) for limited ternary operator functionality #31659 (closed)
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: pixel365
@Jorropo ,
Got it — that's unfortunate, especially since the implementation already works, but I understand the decision and respect the prior discussions. Thanks for the review and consideration.
Comment From: Jorropo
Usually we advise to start the proposal discussion before working on the implementation but up to you.