Detour: Unary operators & signed numeric literals

January 19, 2023

I noticed something while writing the last two sections on Integer literals and Floating-point literals, and I’m curious if anyone else noticed.

There’s no way to express a negative integer or floating-point literal!

If we look specifically at the definition of an decimal literal in EBNF format, we see:

decimal_lit    = "0" | ( "1"  "9" ) [ [ "_" ] decimal_digits ] .

Notably, we do not see this:

decimal_lit    = [ "+" | "-" ] "0" | ( "1"  "9" ) [ [ "_" ] decimal_digits ] .

Does this mean Go doesn’t support negative numbers? Well, obviously not. What use is a programming language without negative numbers?

Does it mean it doesn’t allow assigning negative values directly to constants or variables? No, that’s easily disproven as well.

So what gives?

The + and - signs are interpteted by Go as Unary operators (there are a few others as well).

So what that means is when you write

var myInt = -30

You have not written a negative integer literal (-30). Rather, you’ve written an integer literal (30), preceeded by the unary operator - which negates it value.

Remember that one for your next Go Pub Quiz night!

Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content

Operator constraints

Last week I inconspicuously skipped over one sentence in the spec, the last sentence in the section on Operands, and jumped straight ahead to the section on Qualified identifiers. This is because the sentence didn’t make immediate sense to me, and I needed time to research it. I’ve done that research now, so, let’s jump back and cover the missed territory. Operands … Implementation restriction: A compiler need not report an error if an operand’s type is a type parameter with an empty type set.


I’ll be live coding again today! I hope you can join me! I’ll be continuing where I left off, working on a new feature for my open-source CouchDB SDK, Join me to see how many mistakes a senior Go dev makes while coding. To kick off our dissection of expressions, we’ll look at the term “operand”. You may recall from your studies of algebra that an operand is the “object upon which an operator acts.

Lexical elements: Keywords, Operators and punctuation

Keywords The following keywords are reserved and may not be used as identifiers. break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var Operators and punctuation The following character sequences represent operators (including assignment operators) and punctuation: + & += &= && == != ( ) - | -= |= || < <= [ ] * ^ *= ^= <- > >= { } / << /= <<= ++ = := , ; % >> %= >>= -- !