# Negative in integral literals

**URL:** <https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790>\
**Category:** Language Design\
**Created:** [May 22, 2019, 4:37am UTC](https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790 "2019-05-22T04:37:38Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![mattquigley](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mattquigley/32/2943_2.png) [@mattquigley](https://discuss.kotlinlang.org/u/mattquigley)\
**Post date:** [May 22, 2019, 4:37am UTC](https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790/1 "2019-05-22T04:37:38Z")

</div>

I ran into this interesting Kotlin gotcha:

```
val i = -1.toByte() // this is an Int
val b = (-1).toByte() // this is a Byte

```

After some investigation, it turns out that -1 is actually 1.unaryMinus(), although the final bytecode does transform back into int i = -1 as a Java int. And I understand operator precedence, and that the dot (.) has higher precedence than the unary minus. But my question is why was this design chosen? Why not have the - symbol be a part of the grammar of an integral literal? e.g. in IntegerLiteral [Grammar](https://kotlinlang.org/docs/reference/grammar.html)

---

<div class="post-metadata">

**Author:** ![vbezhenar](https://avatars.discourse-cdn.com/v4/letter/v/35a633/32.png) [@vbezhenar](https://discuss.kotlinlang.org/u/vbezhenar)\
**Post date:** [May 22, 2019, 7:43am UTC](https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790/2 "2019-05-22T07:43:20Z")

</div>

You can use space between minus and a number: `- 1`. Some people would write it this way. If you would treat it differently, that would be huge gotcha IMO. And allowing spaces inside integer literal probably would be tricky.

---

<div class="post-metadata">

**Author:** ![Jonathan.Haas](https://avatars.discourse-cdn.com/v4/letter/j/c68b51/32.png) [@Jonathan.Haas](https://discuss.kotlinlang.org/u/Jonathan.Haas)\
**Post date:** [May 22, 2019, 11:46am UTC](https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790/3 "2019-05-22T11:46:15Z")

</div>

> [@mattquigley](#):
>
> val i = -1.toByte()

The dot operator has a higher precedence that the minus operator. So `-1.toByte()` == `-(1.toByte())`. That’s also why `-3.plus(4)` is -7 even though it looks like it should be 1. Kotlin has no negative number literals at all.

---

<div class="post-metadata">

**Author:** ![mattquigley](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mattquigley/32/2943_2.png) [@mattquigley](https://discuss.kotlinlang.org/u/mattquigley)\
**Post date:** [May 22, 2019, 4:06pm UTC](https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790/4 "2019-05-22T16:06:45Z")

</div>

Integer Literals would not include spaces. `- 1` could be considered the unary operator on 1 and `- 1.toByte()` which is the unary operator on `1.toByte()` seems much less of a gotcha than `-1.toByte()`.

---

<div class="post-metadata">

**Author:** ![mattquigley](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mattquigley/32/2943_2.png) [@mattquigley](https://discuss.kotlinlang.org/u/mattquigley)\
**Post date:** [May 22, 2019, 4:12pm UTC](https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790/5 "2019-05-22T16:12:19Z")

</div>

I understand Kotlin [operator precedence](https://kotlinlang.org/docs/reference/grammar.html?_ga=2.46763491.510335936.1558497865-924989427.1548202806#expressions) and the grammar of [IntegerLiteral](https://kotlinlang.org/docs/reference/grammar.html?_ga=2.46763491.510335936.1558497865-924989427.1548202806#IntegerLiteral).

My question is, _why_ was this design chosen? Why couldn’t a sign be included as part of the grammar? For reference, Java does not include a minus sign as part of Integer Literals either, but does include it in floating-point literals [see](https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html) (search for `SignedInteger`).

---

<div class="post-metadata">

**Author:** ![Jonathan.Haas](https://avatars.discourse-cdn.com/v4/letter/j/c68b51/32.png) [@Jonathan.Haas](https://discuss.kotlinlang.org/u/Jonathan.Haas)\
**Post date:** [May 22, 2019, 5:27pm UTC](https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790/6 "2019-05-22T17:27:55Z")

</div>

> [@mattquigley](#):
>
> My question is, _why_ was this design chosen?

I guess only the Kotlin devs can answer that. My guess is that they thought the unary operator was sufficient and that complication the grammar wasn’t worth it. You also want to avoid ambiguity, so if -1 could be interpreted as -1 literal as well as a unary minus plus a 1 literal that’s probably bad. I personally feel this could have been prevented easily by giving the unary minus operator a higher precedence than the dot operator. But I’m not a language designer, so I don’t know if that would have had other negative side effects.

---

<div class="post-metadata">

**Author:** ![ilya.gorbunov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ilya.gorbunov/32/1645_2.png) [@ilya.gorbunov](https://discuss.kotlinlang.org/u/ilya.gorbunov)\
**Post date:** [May 22, 2019, 9:44pm UTC](https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790/7 "2019-05-22T21:44:56Z")

</div>

> [@mattquigley](#):
>
> _why_ was this design chosen?

As I recall, the reason was to avoid having different semantics of the expressions  
`-1.toByte()` and `-x.toByte()`, where `val x = 1`

---

<div class="post-metadata">

**Author:** ![isiahmeadows](https://avatars.discourse-cdn.com/v4/letter/i/a9a28c/32.png) [@isiahmeadows](https://discuss.kotlinlang.org/u/isiahmeadows)\
**Post date:** [May 25, 2019, 5:09am UTC](https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790/8 "2019-05-25T05:09:37Z")

</div>

I have a separate question: [why does `Byte.unaryMinus()` return an `Int` instead of the obvious `Byte`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-byte/unary-minus.html)? Fixing that would fix this issue. I’ve filed [KT-31611](https://youtrack.jetbrains.com/issue/KT-31611) in light of this question.

TL;DR for others: [This behavior was inherited from Java](https://youtrack.jetbrains.com/issue/KT-2768), but I find Java’s behavior itself to be questionable and arguably buggy.

---

<div class="post-metadata">

**Author:** ![punkstarman](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/punkstarman/32/5996_2.png) [@punkstarman](https://discuss.kotlinlang.org/u/punkstarman)\
**Post date:** [May 25, 2019, 12:12pm UTC](https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790/9 "2019-05-25T12:12:50Z")

</div>

I believe it is healthy to question established rules from time to time. In order to properly question something, one must attempt to understand the original decision and any reasons that are given to support it.

The reason for unary minus converting a `byte` to an `int` isn’t that hard to find: [JVM Spec section 2.11.1](https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.11.1)

> If each typed instruction supported all of the Java Virtual Machine’s run-time data types, there would be more instructions than could be represented in a byte.

Kotlin users, remember that most choices are not as clear cut as may appear, many are tradeoffs between performance and simplicity.

---

<div class="post-metadata">

**Author:** ![ilya.gorbunov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ilya.gorbunov/32/1645_2.png) [@ilya.gorbunov](https://discuss.kotlinlang.org/u/ilya.gorbunov)\
**Post date:** [May 27, 2019, 11:40pm UTC](https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790/10 "2019-05-27T23:40:34Z")

</div>

The reason for having unary minus converting a `byte` to an `int` was mostly consistency with Java rather than the lack of JVM instructions. It is not a hard constraint to represent an each operation on primitive types with exactly one bytecode instruction.

---

<div class="post-metadata">

**Author:** ![punkstarman](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/punkstarman/32/5996_2.png) [@punkstarman](https://discuss.kotlinlang.org/u/punkstarman)\
**Post date:** [May 28, 2019, 9:50pm UTC](https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790/11 "2019-05-28T21:50:35Z")

</div>

Obviously the signature of Kotlin’s `Byte.unaryMinus()` was chosen in order to preserve consistency.

What was in question was why Java chose to convert `byte`s and `short`s to `int` when performing arithmetic operations. The JVM Spec clearly justifies this by saying that there wouldn’t be enough typed bytecodes and so it was decided to optimize for use of `int`s more than `byte`s and `short`s.

As to why JVM bytecodes are typed, I couldn’t find anything definitive. [A question on StackOverflow](https://stackoverflow.com/questions/2637879/types-in-bytecode) has a few insightful answers.

It may not be difficult to specify and implement a virtual machine whose opcodes are untyped, but that was not the direction the designers of the JVM took.

---

<div class="post-metadata">

**Author:** ![gidds](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/gidds/32/10865_2.png) [@gidds](https://discuss.kotlinlang.org/u/gidds)\
**Post date:** [June 10, 2019, 8:18pm UTC](https://discuss.kotlinlang.org/t/negative-in-integral-literals/12790/12 "2019-06-10T20:18:31Z")

</div>

I guess another benefit of having `unaryMinus()` return an `Int` is that it correctly handles the case where the value is -128, and so its negation isn’t representable as a `Byte`.
