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

Clarification: By-name varargs unsupported

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: Scala 2.10.0
    • Fix Version/s: Scala 2.11.0
    • Component/s: Specification
    • Labels:
      None
    • Environment:

      Welcome to Scala version 2.10.0-20120501-234146-b27abca41a (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_22).

      Description

      This is edge-use-case, but:

      scala> def m(a:Int,bs: =>Int*) = 7
      <console>:1: error: ')' expected but identifier found.
             def m(a:Int,bs: =>Int*) = 7
                                  ^
      
      scala> def n(is: (=>Int)*) = 7
      <console>:1: error: no by-name parameter type allowed here
             def n(is: (=>Int)*) = 7
                        ^
      
      scala> def q(is: =>(Int *)) = 5  // not my intention
      <console>:1: error: no * parameter type allowed here
             def q(is: =>(Int *)) = 5
      
      

      Am I the only one who experiences a cognitive hiccup every time I have to disambiguate "named parameter" and "by-name parameter?" Internally (to myself), I've started calling (denoting) params that have call-by-name semantics "eval params" because of the loose notion that they are evaluated on reference. ("Deferred params" conveys the idea that evaluation is deferred, but people get confused about deferred to when, especially under partial application, and deferred doesn't suggest multiple evaluation. I hope Paul reads this and has a better word for it – besides "evil params", of course.)

      I haven't thought closely about this, except my terminology hangup, but the Seq[=>T] view might be a reason to ignore the use case.

        Activity

        Hide
        Paul Phillips added a comment -

        Yes, the terminology we have to describe evaluation semantics is unreasonably impoverished. I have no better word, but if ambiguity is a concern I call by-name parameters thunks (whether that's an accurate use of that word or not, people at least tend to know what I mean.)

        I have asked martin for by-name + varargs before, the use case I often encounter being logging - I'd really like to be able to write

        def log(fmt: String, args: =>Any*) = if (logging) println(fmt.format(args: _*))

        log("%s: %s %s", foo, bar, baz)

        A single instance could serve to hold all three (or N) methods, something like

        class AnonVarargs extends (Int => T) {
          def apply(index: Int) = index match {
            case 0 => foo
            case 1 => bar
            case 2 => baz
          }
        }
        

        There was some objection which I no longer remember.

        Show
        Paul Phillips added a comment - Yes, the terminology we have to describe evaluation semantics is unreasonably impoverished. I have no better word, but if ambiguity is a concern I call by-name parameters thunks (whether that's an accurate use of that word or not, people at least tend to know what I mean.) I have asked martin for by-name + varargs before, the use case I often encounter being logging - I'd really like to be able to write def log(fmt: String, args: =>Any*) = if (logging) println(fmt.format(args: _*)) log("%s: %s %s", foo, bar, baz) A single instance could serve to hold all three (or N) methods, something like class AnonVarargs extends (Int => T) { def apply(index: Int) = index match { case 0 => foo case 1 => bar case 2 => baz } } There was some objection which I no longer remember.
        Hide
        Lukas Rytz added a comment -

        spec clarification needed

        Show
        Lukas Rytz added a comment - spec clarification needed
        Hide
        Adriaan Moors added a comment -

        more notes from the meeting: would be useful to have, but let's clarify it's disallowed for now. Can always implement once we've come up for air after 2.10.0

        Show
        Adriaan Moors added a comment - more notes from the meeting: would be useful to have, but let's clarify it's disallowed for now. Can always implement once we've come up for air after 2.10.0
        Hide
        A. P. Marki added a comment -

        This might fall under the same rubric: var varargs. Given (var is: Int*), you can assign one Int, is=1, but not is=List(1,2,3). Also, someone wanted an implicit convert(Seq) to apply to a vararg, which is expected if vararg is type Seq inside the method. With respect to overloading (how to explain how it works), it was suggested the spec should talk about A* with the same reverence applied to =>A. (That is, a useful fiction.)

        Show
        A. P. Marki added a comment - This might fall under the same rubric: var varargs. Given (var is: Int*), you can assign one Int, is=1, but not is=List(1,2,3). Also, someone wanted an implicit convert(Seq) to apply to a vararg, which is expected if vararg is type Seq inside the method. With respect to overloading (how to explain how it works), it was suggested the spec should talk about A* with the same reverence applied to =>A. (That is, a useful fiction.)
        Hide
        Martin Odersky added a comment -

        Note that the spec is unambiguous wrt this.

        ParamType ::= Type

        `=>' Type
        Type `*'

        So it's clear they cannot be combined.

        Show
        Martin Odersky added a comment - Note that the spec is unambiguous wrt this. ParamType ::= Type `=>' Type Type `*' So it's clear they cannot be combined.
        Hide
        Grzegorz Kossakowski added a comment -

        Unassigning and rescheduling to M7 as previous deadline was missed.

        Show
        Grzegorz Kossakowski added a comment - Unassigning and rescheduling to M7 as previous deadline was missed.
        Hide
        Adriaan Moors added a comment -

        Apologies to those holding their breath. I will start working on spec cleanup as soon as RC1 is out the door. Promise.

        Show
        Adriaan Moors added a comment - Apologies to those holding their breath. I will start working on spec cleanup as soon as RC1 is out the door. Promise.
        Hide
        A. P. Marki added a comment -

        Whew. It was my mistake to misread the spec when I was learning the language (specese, as it's been called). I thought this would make an interesting (at the time) contribution, but paulp's use case is obviated by other features (macros). By coincidence, I was just touching this production in my last PR, wondering if Int`*` is a good param type, with star as a regular identifier instead of some intermediate category.

        Show
        A. P. Marki added a comment - Whew. It was my mistake to misread the spec when I was learning the language (specese, as it's been called). I thought this would make an interesting (at the time) contribution, but paulp's use case is obviated by other features (macros). By coincidence, I was just touching this production in my last PR, wondering if Int`*` is a good param type, with star as a regular identifier instead of some intermediate category.

          People

          • Assignee:
            Adriaan Moors
            Reporter:
            A. P. Marki
          • Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

            Dates

            • Created:
              Updated:

              Development