Scala Programming Language
  1. Scala Programming Language
  2. SI-1980

by-name argument incorrectly evaluated on :-ending operator

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Lint
    • Labels:
      None

      Description

      scala> def foo() = { println("foo") ; 5 }
      foo: ()Int
      
      scala> class C { def m1(f: => Int) = () ; def m2_:(f: => Int) = () }
      defined class C
      
      scala> val c = new C
      c: C = C@96d484
      
      scala> c m1 foo()
      
      scala> foo() m2_: c
      foo
      

      But it is not evaluated if invoked directly:

      scala> c.m2_:(foo())
      
      scala>
      

        Issue Links

          Activity

          Hide
          Paul Phillips added a comment -

          I apparently failed to update this ticket when I tried this out and found the real deal killer.

          scala> val nextid = { var x = 1 ; () => try "x" + x finally x += 1 }
          nextid: () => String = <function0>
          
          scala> nextid() #:: nextid() #:: nextid() #:: Stream[String]()
          res0: scala.collection.immutable.Stream[String] = Stream(x1, ?)
          
          scala> res1.toList
          res1: List[String] = List(x1, x2, x3)
          

          If this evaluates right to left you get List(x3, x2, x1), and because whether an argument is by-name or not is not visible at the call site, you always have to worry about it.

          Show
          Paul Phillips added a comment - I apparently failed to update this ticket when I tried this out and found the real deal killer. scala> val nextid = { var x = 1 ; () => try "x" + x finally x += 1 } nextid: () => String = <function0> scala> nextid() #:: nextid() #:: nextid() #:: Stream[String]() res0: scala.collection.immutable.Stream[String] = Stream(x1, ?) scala> res1.toList res1: List[String] = List(x1, x2, x3) If this evaluates right to left you get List(x3, x2, x1), and because whether an argument is by-name or not is not visible at the call site, you always have to worry about it.
          Hide
          Jason Zaugg added a comment -

          Another type inference implication: dependent types from SI-4518.

          class Broke {
          
            val tempval = new AnyRef {val roleA = new AnyRef with Bar}.roleA
          
            new AnyRef {} -: tempval // when not assigning to anything, no problem
            val broke_val = new AnyRef {} -: tempval // type mismatch error only when assigning
          
            trait Foo[AnyRef] {  }
          
            trait Bar extends Foo[AnyRef] {
              def -:(core: AnyRef): this.type with Foo[core.type] = throw new Exception()
            }
          }
          
          Show
          Jason Zaugg added a comment - Another type inference implication: dependent types from SI-4518 . class Broke { val tempval = new AnyRef {val roleA = new AnyRef with Bar}.roleA new AnyRef {} -: tempval // when not assigning to anything, no problem val broke_val = new AnyRef {} -: tempval // type mismatch error only when assigning trait Foo[AnyRef] { } trait Bar extends Foo[AnyRef] { def -:(core: AnyRef): this.type with Foo[core.type] = throw new Exception() } }
          Hide
          Jason Zaugg added a comment -

          A good suggestion from the mailing list:

          From: Roman Janusz <romeqjanoosh@gmail.com>
          Date: Sat, Aug 17, 2013 at 11:40 PM
          Subject: Re: [scala-user] Colon-ending operators and by-name parameters
          To: scala-user@googlegroups.com
          Cc: Roman Janusz <romeqjanoosh@gmail.com>, Sergii Starodubtsev <ses.box@gmail.com>

          Anyway, this is really counterintuitive and effectively means that by-name parameters make no sense with right-associative operators. I think it would be nice if the compiler at least issued a warning about this.

          W dniu sobota, 17 sierpnia 2013 23:18:44 UTC+2 użytkownik Jason Zaugg napisał:
          On Sat, Aug 17, 2013 at 11:07 PM, Roman Janusz <romeqj...@gmail.com> wrote:
          SLS 4.6.1 says that call-by-name argument "is not evaluated at the point of function application, but instead is evaluated at each use within the function".

          So as for me, current behavior is clearly against the spec.

          But 6.12.3 offers:

          "If op is right- associative, the same operation is interpreted as

          Unknown macro: { val x=e1; e2.op(x ) }

          , where x is a fresh name."

          -jason

          Show
          Jason Zaugg added a comment - A good suggestion from the mailing list: From: Roman Janusz <romeqjanoosh@gmail.com> Date: Sat, Aug 17, 2013 at 11:40 PM Subject: Re: [scala-user] Colon-ending operators and by-name parameters To: scala-user@googlegroups.com Cc: Roman Janusz <romeqjanoosh@gmail.com>, Sergii Starodubtsev <ses.box@gmail.com> Anyway, this is really counterintuitive and effectively means that by-name parameters make no sense with right-associative operators. I think it would be nice if the compiler at least issued a warning about this. W dniu sobota, 17 sierpnia 2013 23:18:44 UTC+2 użytkownik Jason Zaugg napisał: On Sat, Aug 17, 2013 at 11:07 PM, Roman Janusz <romeqj...@gmail.com> wrote: SLS 4.6.1 says that call-by-name argument "is not evaluated at the point of function application, but instead is evaluated at each use within the function". So as for me, current behavior is clearly against the spec. But 6.12.3 offers: "If op is right- associative, the same operation is interpreted as Unknown macro: { val x=e1; e2.op(x ) } , where x is a fresh name." -jason
          Hide
          Jason Zaugg added a comment -
          Show
          Jason Zaugg added a comment - Adding a lint warning: https://github.com/scala/scala/pull/2852
          Hide
          Roman Janusz added a comment -

          If I understand correctly, another problem with this parser behaviour is that right-associative macros also make no sense.

          Show
          Roman Janusz added a comment - If I understand correctly, another problem with this parser behaviour is that right-associative macros also make no sense.

            People

            • Assignee:
              Martin Odersky
              Reporter:
              Paul Phillips
              TracCC:
              archontophoenix, Christos KK Loverdos, Eric Torreborre, Eric Willigers, Olivier Pernet, Paul Phillips, Seth Tisue
            • Votes:
              6 Vote for this issue
              Watchers:
              9 Start watching this issue

              Dates

              • Created:
                Updated:

                Development