Skip to content
This repository was archived by the owner on Sep 1, 2020. It is now read-only.

Binary literals #23

Closed
aaronlifton3 opened this issue Sep 5, 2014 · 8 comments
Closed

Binary literals #23

aaronlifton3 opened this issue Sep 5, 2014 · 8 comments

Comments

@aaronlifton3
Copy link

It would be nice if this scalac fork had built-in non-macro binary literals, similar to the macro-based one found in retronym's macrocosm

E.g. https://github.com/retronym/macrocosm/blob/master/src/main/scala/com/github/retronym/macrocosm/Macrocosm.scala#L72

Example:

scala> b"101010"
res4: Int = 42

scala> b"102"
<console>:11: error: exception during macro expansion: invalid binary literal
              b"102"
              ^
@puffnfresh
Copy link

What type would it become? Int? Short? Byte? Long? String?

@propensive
Copy link

You would want to have some prefix signify the meaning of the subsequent 1s and 0s, and a suffix signify the type, consistent with hex. e.g. 0q1001110100L. Anything else would be quite inconsistent with what we already have.

@non
Copy link

non commented Sep 6, 2014

I think it could work very similarly to hex literals (0x111).

For example:

0b111Z // Byte
0b111S // Short
0b111  // Int
0b111L // Long

What do you all think?

EDIT: I think this is almost exactly what @propensive is proposing.

@propensive
Copy link

It's exactly the same, except I was scared of the possible ambiguity of 0b1011 looking like hex. (Obviously it's not -- it's a mental parsing thing, hence my random suggestion of q.)

@Blaisorblade
Copy link

@non's proposal is also coherent with Java 8's binary literals.
👍 on using 0b as a prefix; to consider an alternative, I'd want a mnemonic as good as the one for b.

@som-snytt
Copy link

The b mnemonic is weakened by the b boolean conversion in format strings.

To counteract that, add 0k alias for true and 0n0 for false.

0b10 Byte, 0B10 Short, 010 Int, 010L Long, 0cA Char. (No longer fearing the ghost of octal, and no longer wishing to use backslashes for unicode '\u000A'. OK, the pun on 0k loosened me up a bit. Pun on bit unintended.)

@Blaisorblade
Copy link

The b mnemonic is weakened by the b boolean conversion in format strings.

Valid point.

@propensive wrote:

Anything else would be quite inconsistent with what we already have.

For instance, this would be inconsistent:

0b10 Byte, 0B10 Short, 010 Int, 010L Long, 0cA Char.

However, I realize I had missed some jokes in your message and I'm unsure about others.

puffnfresh pushed a commit to puffnfresh/scala that referenced this issue Jul 30, 2015
These methods are "signature polymorphic", which means that compiler
should not:
  1. adapt the arguments to `Object`
  2. wrap the repeated parameters in an array
  3. adapt the result type to `Object`, but instead treat it as it
     it already conforms to the expected type.

Dispiritingly, my initial attempt to implement this touched the type
checker, uncurry, erasure, and the backend.

However, I realized we could centralize handling of this in the typer
if at each application we substituted the signature polymorphic
symbol with a clone that carried its implied signature, which is
derived from the types of the arguments (typechecked without an
expected type) and position within and enclosing cast or block.

The test case requires Java 7+ to compile so is currently embedded
in a conditionally compiled block of code in a run test.

We ought to create a partest category for modern JVMs so we can
write such tests in a more natural style.

Here's how this looks in bytecode. Note the `bipush` / `istore`
before/after the invocation of `invokeExact`, and the descriptor
`(LO$;I)I`.

```
% cat sandbox/poly-sig.scala && qscala Test && echo ':javap Test$#main' | qscala
import java.lang.invoke._

object O {
  def bar(x: Int): Int = -x
}

object Test {
  def main(args: Array[String]): Unit = {
    def lookup(name: String, params: Array[Class[_]], ret: Class[_]) = {
      val lookup = java.lang.invoke.MethodHandles.lookup
      val mt = MethodType.methodType(ret, params)
      lookup.findVirtual(O.getClass, name, mt)
    }
    def lookupBar = lookup("bar", Array(classOf[Int]), classOf[Int])

    val barResult: Int = lookupBar.invokeExact(O, 42)
    ()
  }
}

scala> :javap Test$#main
  public void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=3, args_size=2
         0: aload_0
         1: invokespecial typelevel#18                 // Method lookupBar$1:()Ljava/lang/invoke/MethodHandle;
         4: getstatic     typelevel#23                 // Field O$.MODULE$:LO$;
         7: bipush        42
         9: invokevirtual typelevel#29                 // Method java/lang/invoke/MethodHandle.invokeExact:(LO$;I)I
        12: istore_2
        13: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      14     0  this   LTest$;
            0      14     1  args   [Ljava/lang/String;
           13       0     2 barResult   I
      LineNumberTable:
        line 16: 0
}
```

I've run this test across our active JVMs:

```
% for v in 1.6 1.7 1.8; do java_use $v; pt --terse test/files/run/t7965.scala || break; done
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-466.1-11M4716)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-466.1, mixed mode)
Selected 1 tests drawn from specified tests

.

1/1 passed (elapsed time: 00:00:02)
Test Run PASSED
java version "1.7.0_71"
Java(TM) SE Runtime Environment (build 1.7.0_71-b14)
Java HotSpot(TM) 64-Bit Server VM (build 24.71-b01, mixed mode)
Selected 1 tests drawn from specified tests

.

1/1 passed (elapsed time: 00:00:07)
Test Run PASSED
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
Selected 1 tests drawn from specified tests

.

1/1 passed (elapsed time: 00:00:05)
Test Run PASSED
```
milessabin pushed a commit that referenced this issue Aug 12, 2016
This corrects an error in the change to the trait encoding
in scala#5003: getters in traits should have empty bodies and
be emitted as abstract.

```
% ~/scala/2.12.0-M4/bin/scalac sandbox/test.scala && javap -c T
Compiled from "test.scala"
public interface T {
  public abstract void T$_setter_$x_$eq(int);

  public int x();
    Code:
       0: aload_0
       1: invokeinterface #15,  1           // InterfaceMethod x:()I
       6: ireturn

  public int y();
    Code:
       0: aload_0
       1: invokeinterface #20,  1           // InterfaceMethod y:()I
       6: ireturn

  public void y_$eq(int);
    Code:
       0: aload_0
       1: iload_1
       2: invokeinterface #24,  2           // InterfaceMethod y_$eq:(I)V
       7: return

  public void $init$();
    Code:
       0: aload_0
       1: bipush        42
       3: invokeinterface #29,  2           // InterfaceMethod T$_setter_$x_$eq:(I)V
       8: aload_0
       9: bipush        24
      11: invokeinterface #24,  2           // InterfaceMethod y_$eq:(I)V
      16: return
}

% qscalac sandbox/test.scala && javap -c T
Compiled from "test.scala"
public interface T {
  public abstract void T$_setter_$x_$eq(int);

  public abstract int x();

  public abstract int y();

  public abstract void y_$eq(int);

  public static void $init$(T);
    Code:
       0: aload_0
       1: bipush        42
       3: invokeinterface #21,  2           // InterfaceMethod T$_setter_$x_$eq:(I)V
       8: aload_0
       9: bipush        24
      11: invokeinterface #23,  2           // InterfaceMethod y_$eq:(I)V
      16: return

  public void $init$();
    Code:
       0: aload_0
       1: invokestatic  #27                 // Method $init$:(LT;)V
       4: return
}
```
@milessabin
Copy link
Member

To resurrect this issue, please rework it as an issue/PR against Lightbend Scala (ie. scala/scala).

@milessabin milessabin added this to the Parked milestone Aug 12, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants