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

Unexpected error when combining default parameters, named arguments, currying, and parameterized type

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Misc Compiler
    • Labels:
      None

      Description

      This seems related to SI-4591

      object Control {
        def repeat[T](count: Int = 1, x: Boolean = true)(thunk: => T) : T = (0 until count).map(_ => thunk).last
        def repeat[T](thunk: => T) : T = repeat()(thunk)
      
        repeat(3.14)
        repeat(count=5)(3.14)
        repeat(count=5,x=false)(3.14)
      }
      

      === What is the expected behavior? ===

      No error when compiling.

      === What do you see instead? ===

       scalac repeat.scala 
      repeat.scala:8: error: not found: value count
        repeat(count=5)(3.14)
               ^
      one error found
      

      Interestingly, in SI-4591 (which is similar code except the the use of type parameter), the error location is the definition itself (and not usage). Error message is confusing in any case.

      === Additional information ===
      (for instance, a link to a relevant mailing list discussion)

      === What versions of the following are you using? ===

      • Scala: 2.9.final
      • Java: 1.6
      • Operating system: MacOS Snow Leopard

        Activity

        Hide
        Ramnivas Laddad added a comment -

        It gets weirder. When I remove the second parameter ("x"), it compiles fine.

        object Control {
          def repeat[T](count: Int = 1)(thunk: => T) : T = (0 until count).map(_ => thunk).last
          def repeat[T](thunk: => T) : T = repeat()(thunk)
        
          repeat(3.14)
          repeat(count=5)(3.14)
        }
        

        No error with scalac now.

        Show
        Ramnivas Laddad added a comment - It gets weirder. When I remove the second parameter ("x"), it compiles fine. object Control { def repeat[T](count: Int = 1)(thunk: => T) : T = (0 until count).map(_ => thunk).last def repeat[T](thunk: => T) : T = repeat()(thunk) repeat(3.14) repeat(count=5)(3.14) } No error with scalac now.
        Hide
        Ramnivas Laddad added a comment -

        Just wanted to add my thoughts on what may be going on here (partially) and why the bug exhibits only for methods with a type parameter. Hopefully, this helps you in analyzing and resolving the issue.

        First note that, compiler is quite happy with (reported with SI-4591):

        object Control {
          def repeat(count: Int = 1, x: Boolean = true)(thunk: => Double) : Unit = (0 until count).foreach(_ => thunk)
          def repeat(thunk: => Double) : Unit = repeat()(thunk)
         
          repeat(3.14)
          repeat(count=5)(3.14)
        }
        

        In the second call, "count=5" would have returned Unit (if count were to be in scope) and that would have not matched the "Double" type of the thunk, so the "repeat(count: Int = 1, x: Boolean = true)(thunk: => Double)" was used and it all worked fine.

        With the type parameter version (code reported in the original issue report), the compiler is probably trying to match the call in error to "repeat[T](thunk: => T)" with T bound to Unit (the return type of expression "count=5"). Unlike the "=> Double" case, there is no issue in resolving the thunk to return Unit. But, of course, there is no "count" in the scope and hence the error.

        This still doesn't explain why removing "x: Boolean = true" made the error go away.

        Really curious how you approach this and resolve it.

        Show
        Ramnivas Laddad added a comment - Just wanted to add my thoughts on what may be going on here (partially) and why the bug exhibits only for methods with a type parameter. Hopefully, this helps you in analyzing and resolving the issue. First note that, compiler is quite happy with (reported with SI-4591 ): object Control { def repeat(count: Int = 1, x: Boolean = true)(thunk: => Double) : Unit = (0 until count).foreach(_ => thunk) def repeat(thunk: => Double) : Unit = repeat()(thunk) repeat(3.14) repeat(count=5)(3.14) } In the second call, "count=5" would have returned Unit (if count were to be in scope) and that would have not matched the "Double" type of the thunk, so the "repeat(count: Int = 1, x: Boolean = true)(thunk: => Double)" was used and it all worked fine. With the type parameter version (code reported in the original issue report), the compiler is probably trying to match the call in error to "repeat [T] (thunk: => T)" with T bound to Unit (the return type of expression "count=5"). Unlike the "=> Double" case, there is no issue in resolving the thunk to return Unit. But, of course, there is no "count" in the scope and hence the error. This still doesn't explain why removing "x: Boolean = true" made the error go away. Really curious how you approach this and resolve it.
        Hide
        Commit Message Bot added a comment -

        (extempore in r25455) Fixed bug in the disambiguation of f(foo='bar') style method calls in
        the presence of overloading, parameterization, and by-name arguments.
        Took the opportunity to clean things up a little bit. Closes SI-4592,
        review by rytz.

        Show
        Commit Message Bot added a comment - (extempore in r25455 ) Fixed bug in the disambiguation of f(foo='bar') style method calls in the presence of overloading, parameterization, and by-name arguments. Took the opportunity to clean things up a little bit. Closes SI-4592 , review by rytz.

          People

          • Assignee:
            Paul Phillips
            Reporter:
            Ramnivas Laddad
            TracCC:
            Ismael Juma
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development