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

selectDynamic/applyDynamic logic fails too eagerly

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: Scala 2.11.0-M8
    • Component/s: None

      Description

      This should work.

      import scala.language.dynamics
      
      class A extends Dynamic {
        def selectDynamic(method: String): B = new B(method)
      }
      class B(method: String) {
        def apply(args: Any*) = println("Called " + method)
      }
      
      object Test {
        def main(args: Array[String]): Unit = {
          val x = new A
          println(x.bippy("arg"))
        }
      }
      

      Instead, the compile fails:

      % scalac3 ./a.scala 
      ./a.scala:13: error: value applyDynamic is not a member of A
      error after rewriting to x.<applyDynamic: error>("bippy")
      possible cause: maybe a wrong Dynamic method signature?
          println(x.bippy("arg"))
                  ^
      one error found
      

      It does compile like this:

        println(x.bippy.apply("arg"))
      

      But that renders it unsuitable for most plausible uses of Dynamic.

      This is especially important because if this worked it would offer a way to achieve a more general form of overload than is currently possible.

        Issue Links

          Activity

          Hide
          Adriaan Moors added a comment -

          Unassigning and rescheduling to M6 as previous deadline was missed.

          Show
          Adriaan Moors added a comment - Unassigning and rescheduling to M6 as previous deadline was missed.
          Hide
          Eugene Burmako added a comment -

          Interestingly enough, if one changes `selectDynamic` to `applyDynamic`, everything works fine.

          Show
          Eugene Burmako added a comment - Interestingly enough, if one changes `selectDynamic` to `applyDynamic`, everything works fine.
          Hide
          Eugene Burmako added a comment -

          One might say that this behavior is warranted by SIP-17: http://docs.scala-lang.org/sips/completed/type-dynamic.html. Here's a relevant excerpt:

          • If qual.sel is followed by a type argument list [Ts] (optionally) and an argument list (arg1, …, argn), where none of the arguments argi are named, and argn is not a sequence argument, i.e., of the shape e: _* (the argument list is required, though it may be empty), as in: qual.sel[Ts](arg1, …, argn), rewrite the expression to: qual.applyDynamic[Ts](“sel”)(arg1, …, argn)
          • If qual.sel is not followed by arguments or an assignment operator: qual.selectDynamic[Ts](“sel”).

          If we follow the letter of the SIP, then x.bippy in x.bippy("arg") is followed by an argument list, hence it should get desugared into applyDynamic, not selectDynamic. Do you agree?

          Show
          Eugene Burmako added a comment - One might say that this behavior is warranted by SIP-17: http://docs.scala-lang.org/sips/completed/type-dynamic.html . Here's a relevant excerpt: If qual.sel is followed by a type argument list [Ts] (optionally) and an argument list (arg1, …, argn), where none of the arguments argi are named, and argn is not a sequence argument, i.e., of the shape e: _* (the argument list is required, though it may be empty), as in: qual.sel[Ts](arg1, …, argn), rewrite the expression to: qual.applyDynamic[Ts](“sel”)(arg1, …, argn) If qual.sel is not followed by arguments or an assignment operator: qual.selectDynamic[Ts](“sel”) . If we follow the letter of the SIP, then x.bippy in x.bippy("arg") is followed by an argument list, hence it should get desugared into applyDynamic, not selectDynamic. Do you agree?
          Hide
          Paul Phillips added a comment -

          I agree that's what the sip says, but as you know I do not generally find such documents particularly relevant. If there's a better way to do things then it's a bug in the sip. I see zero utility in intentionally generating a call to a method which can be seen not to exist and in so doing making it impossible to reach the method which does exist.

          Show
          Paul Phillips added a comment - I agree that's what the sip says, but as you know I do not generally find such documents particularly relevant. If there's a better way to do things then it's a bug in the sip. I see zero utility in intentionally generating a call to a method which can be seen not to exist and in so doing making it impossible to reach the method which does exist.
          Show
          Eugene Burmako added a comment - https://github.com/scala/scala/pull/3310

            People

            • Assignee:
              Eugene Burmako
              Reporter:
              Paul Phillips
            • Votes:
              1 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:

                Development