Pre-SIP: Support Binary Integer Literals

It’d probably be easier to define a .toInt on Binary, otherwise you’d have to import the feature flag for implicit conversions anywhere you want to adapt the types (which is a pain in the neck).

Otherwise, I agree it’s probably the simplest way to differentiate them.

2 Likes

I just recently ported the hex and bin macro-based interpolators to Dotty: https://github.com/scodec/scodec-bits/blob/topic/dotty/core/shared/src/main/scala-0.22/scodec/bits/Interpolators.scala

scala> import scodec.bits._

scala> val b = hex"deadbeef"
val b: scodec.bits.ByteVector = ByteVector(4 bytes, 0xdeadbeef)

scala> val c = bin"1100110"
val c: scodec.bits.BitVector = BitVector(7 bits, 0xcc)

Per a suggestion from @soronpo, I was able to get FromDigits for ByteVector working as well: https://github.com/scodec/scodec-bits/blob/topic/dotty/core/shared/src/main/scala-0.22/scodec/bits/ByteVectorPlatform.scala

This gives usage like:

scala> import scodec.bits._

scala> val b: ByteVector = 0x00112233_44556677_8899aabb_ccddeeff_fedba098
val b: scodec.bits.ByteVector = ByteVector(20 bytes, 0x00112233445566778899aabbccddeefffedba098)

I’d love to see support for radix 2 with FromDigits via 0b prefix.

Aside: I noticed when using hex literals, the string passed to fromDigits includes a leading 0. E.g., 0xdeadbeef results in a digits string “0deadbeef”.

6 Likes

Hello,
So a few days ago, I needed binary integer literals, and I remembered it being accepted by the SIP comity, and I was surprised by it not working.
Looking closer the SIP is “waiting for implementation”, and there is a proposed implementation for Scala 2, but not one for Scala 3.

So I decided to get my hand dirty and make it myself, but I was very surprised to find that all I needed to do was to uncomment a single line:

There might be some other capability we might want, but the following works as expected:

  assert(0b0000 == 0)
  assert(0b0001 == 1)
  assert(0b0010 == 2)
  assert(0b0100 == 4)
  assert(0b1000 == 8)

  assert(0b1000_0000_0000_0000__0000_0000_0000_0000L == 2147483648L)

  assert(0b1000_0000_0000_0000__0000_0000_0000_0000 == -2147483648) // Signed !

  0b1_0000_0000_0000_0000__0000_0000_0000_0000 // error: number too large

(The signed thing surprised me, but it works the same for hex literals)

So my question is: What is missing for this to be part of Scala ?

3 Likes

ship itt!

1 Like

Well, here is the PR if someone wants to look at it:

4 Likes

I think we want to compare with genericNumberLiterals first. The idea was that we do not want more one-letter sigils in literals and that we want to use instead a more general solution.

Or a more far-reaching proposal

I get that, but 0b is a very common standard, and it feels weird not to support it, especially given the ease of implementation !

Also I don’t really understand the link between FromDigits and this, an Int is still an Int, regardless of how it was written, it would be surprising to write something like the following:

val x: BinaryInt = 10101
//vs
val x = 0b10101

Furthermore the SIP comity already accepted the proposal, so the syntax is fixed, the remaining detail is the implementation
It seems hard to argue for a more complicated system than the one we get by uncommenting a single line
(Or the SIP comity should un-accept the proposal)

3 Likes

I agree, 0b is common. So I am OK with adding it.

3 Likes

Congratulations to everyone who participated in this thread!

This is like the long conversation about why we can’t get a puppy.

3 Likes