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

Add annotation to specify operators precedence. #69

Closed
4lex1v opened this issue Sep 30, 2014 · 4 comments
Closed

Add annotation to specify operators precedence. #69

4lex1v opened this issue Sep 30, 2014 · 4 comments

Comments

@4lex1v
Copy link

4lex1v commented Sep 30, 2014

Is it possible to add some kind of annotation to control the precedence of functions with symbolic names, something similar to what Haskell has?

implicit class ArrowAssoc[A](left: A) {
  @infixr(6) def ->[B](right: B): (A, B) = (left, right)
}

So the code like this: "string" -> "value" -> 10, would be parsed as ("string" -> ("value" -> 10)).

@paulp
Copy link

paulp commented Sep 30, 2014

This would be a lifesaver for writing code and a potential anchor for reading it. If you attach the lifesaver to the anchor, does it sink or float? I think it floats in general but maybe not in scala.

@julien-truffaut
Copy link

+1 would be extremely useful.

@paulp I don't think the use of a static table (as it is now) makes the code more readable. AFAIK, most people don't know what is the current operators precedence.

@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
soronpo pushed a commit to soronpo/scala.github.com that referenced this issue Feb 9, 2017
- Removed author's notes, and Adding them here:
1. Unary types are not crucial as infix type precedence, but good for completeness.
2. For the proposal section, I can copy-paste the specifications from expression and modify them to types, if it so required.
3. Would love some help to complete what happens in different programming languages. 
4. I think it is very unlikely that variance annotation will interact with literal types, so the confusion is not that critical.
5. Backward compatibility: I don't know if providing a flag to select the precedence is good or not. IMHO, it is better to create a tool that adds brackets to convert code to the old associativity. @jvican's suggestion to use a tool to analyze libraries and check if they are compatible or not is interesting. Don't know if I have time to make it. It is more useful for me to explore the scala compiler code, and make a PR for this SIP 😄

- Modified the example to `/` instead of `*` because currently dotty has bug and does not allow `*` infix type. 
- Removed scala meta section.
- Removed extended proposal alternative:
It is possible to extend this proposal and allow the developer to annotate the expected associativity and precedence per operation. 
I personally don't like this, but if such a solution is better for the community, then I will gladly modify this SIP to reflect that.
See the following [Typelevel Scala issue](typelevel/scala#69) for the suggestion.
milessabin pushed a commit that referenced this issue Jul 31, 2017
Non local returns aren't eliminated after inlined in 2.11 or 2.12

```
⚡ scala
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112).
Type in expressions for evaluation. Or try :help.

scala> @inlune def foo(a: => Any) = if ("".isEmpty) a else ""
<console>:11: error: not found: type inlune
       @inlune def foo(a: => Any) = if ("".isEmpty) a else ""
        ^

scala> @inline def foo(a: => Any) = if ("".isEmpty) a else ""
foo: (a: => Any)Any

scala> class InlineReturn { def test: Any = foo(return "") }
defined class InlineReturn

scala> :javap -c InlineReturn#test
  public java.lang.Object test();
    Code:
       0: new           #4                  // class java/lang/Object
       3: dup
       4: invokespecial #32                 // Method java/lang/Object."<init>":()V
       7: astore_1
       8: getstatic     #36                 // Field $line4/$read$$iw$$iw$.MODULE$:L$line4/$read$$iw$$iw$;
      11: aload_1
      12: invokedynamic #59,  0             // InvokeDynamic #0:apply:(Ljava/lang/Object;)Lscala/Function0;
      17: invokevirtual #63                 // Method $line4/$read$$iw$$iw$.foo:(Lscala/Function0;)Ljava/lang/Object;
      20: goto          44
      23: astore_2
      24: aload_2
      25: invokevirtual #66                 // Method scala/runtime/NonLocalReturnControl.key:()Ljava/lang/Object;
      28: aload_1
      29: if_acmpne     39
      32: aload_2
      33: invokevirtual #69                 // Method scala/runtime/NonLocalReturnControl.value:()Ljava/lang/Object;
      36: goto          41
      39: aload_2
      40: athrow
      41: goto          44
      44: areturn
    Exception table:
       from    to  target type
           8    20    23   Class scala/runtime/NonLocalReturnControl
```

```
⚡ ~/scala/2.11.8/bin/scala
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112).
Type in expressions for evaluation. Or try :help.

scala> @inline def foo(a: => Any) = if ("".isEmpty) a else ""
foo: (a: => Any)Any

scala> class InlineReturn { def test: Any = foo(return "") }
defined class InlineReturn

scala> :javap -c InlineReturn#test
  public java.lang.Object test();
    Code:
       0: new           #4                  // class java/lang/Object
       3: dup
       4: invokespecial #13                 // Method java/lang/Object."<init>":()V
       7: astore_1
       8: getstatic     #19                 // Field .MODULE$:L;
      11: new           #21                 // class InlineReturn$$anonfun$test$1
      14: dup
      15: aload_0
      16: aload_1
      17: invokespecial #24                 // Method InlineReturn$$anonfun$test$1."<init>":(LInlineReturn;Ljava/lang/Object;)V
      20: invokevirtual #28                 // Method .foo:(Lscala/Function0;)Ljava/lang/Object;
      23: goto          39
      26: astore_2
      27: aload_2
      28: invokevirtual #31                 // Method scala/runtime/NonLocalReturnControl.key:()Ljava/lang/Object;
      31: aload_1
      32: if_acmpne     40
      35: aload_2
      36: invokevirtual #34                 // Method scala/runtime/NonLocalReturnControl.value:()Ljava/lang/Object;
      39: areturn
      40: aload_2
      41: athrow
    Exception table:
       from    to  target type
           8    26    26   Class scala/runtime/NonLocalReturnControl

scala> :quit
```
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

6 participants