byname parameters for constructors

43 views
Skip to first unread message

pschaus

unread,
May 7, 2013, 4:34:09 AM5/7/13
to scala...@googlegroups.com, Sascha Van Cauwelaert

Are byname parameters supposed to work for constructors?

In this example, I did not expect to see "hello" printed.

Thank you in advance,


Pierre


class Test(a: => Unit) {

}


object Test extends App {


val t = new Test{

      println("hello")

}

}

Naftoli Gugenheim

unread,
May 7, 2013, 4:42:04 AM5/7/13
to pschaus, scala-user, Sascha Van Cauwelaert
That's not a by-name parameter, that's a class body.
In the case of
method { ... }
scala can only interpret the curly braces as being an argument, however in the case of
new Clazz { ... }
there is another possible interpretation, which is given higher priority. To the objection that in this case that interpretation would be invalid since Test requires an argument, there are two possible answers (not sure which is the correct one). First, perhaps this syntax processing is done in the parser, before Scala knows anything about Test or if it even exists. Second:

scala> class C[A](a: A) { println(a) }
defined class C

scala> new C {}
()
res0: C[Unit] = $anon$1@4c92e44a



--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Johannes Rudolph

unread,
May 7, 2013, 4:50:24 AM5/7/13
to Naftoli Gugenheim, pschaus, scala-user, Sascha Van Cauwelaert
On Tue, May 7, 2013 at 10:42 AM, Naftoli Gugenheim <nafto...@gmail.com> wrote:
> That's not a by-name parameter, that's a class body.
> In the case of
> method { ... }
> scala can only interpret the curly braces as being an argument, however in
> the case of
> new Clazz { ... }
> there is another possible interpretation, which is given higher priority.

Here's a ticket which comes with a similar conclusion:

https://issues.scala-lang.org/browse/SI-4149

For me the question is the difference between

class C(a: => String)

and

class C(a: => Unit)

The first one fails with an appropriate error message while for the
second one an empty block is inferred as argument (in the expression
`new C`). Why?


--
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net

Som Snytt

unread,
May 7, 2013, 10:43:40 AM5/7/13
to Johannes Rudolph, Naftoli Gugenheim, pschaus, scala-user, Sascha Van Cauwelaert
This was a good one.

I sense itchy fingers over at scalapuzzlers.

I'd guess the difference for the Unit CBN case is SLS 5.1.1:

If no explicit arguments are
given, an empty list () is implicitly supplied.

$ skala -Xprint:parser,typer

scala> class D(a: => Unit)

scala> new D
[[syntax trees at end of                    parser]] // <console>
val res0 = new D()
[[syntax trees at end of                     typer]] // <console>
private[this] val res0: D = new $line3.$read.$iw.$iw.D(());


It's also refreshing to hear, on the issue thread, "This won't happen."   Instead of the more usual sense that a nuance might be nice to have, after a SIP and a bug fix in type inference and the arrival of type macros etc, coming to a compiler near you in Summer 2014.  The early teaser syndrome.

Instead of "refreshing", I was going to say "bracing", but I could already hear the groans of pundom.




Johannes Rudolph

unread,
May 7, 2013, 11:20:18 AM5/7/13
to Som Snytt, Naftoli Gugenheim, pschaus, scala-user, Sascha Van Cauwelaert
On Tue, May 7, 2013 at 4:43 PM, Som Snytt <som....@gmail.com> wrote:
> I'd guess the difference for the Unit CBN case is SLS 5.1.1

Good catch!

> It's also refreshing to hear, on the issue thread, "This won't happen."

I'm not completely sure what "This won't happen." related to. IMO the
sane thing to do wouldn't be allowing more syntax as suggested in the
issue but restricting the rules in a way which disallows the effect
seen here (i.e. that `new D` is valid).

And now I know why it works the way it does (-Ywarn-adapted-args):

scala> class C(x: => Unit)
defined class C

scala> new C()
<console>:9: warning: Adapting argument list by inserting (): this is
unlikely to be what you want.
signature: C(x: => Unit): C
given arguments: <none>
after adaptation: new C((): Unit)
new C()
^

It's the auto-tupling converting the empty parameter list into the
0-tuple. In which cases is this what you want to do?

Som Snytt

unread,
May 7, 2013, 1:21:33 PM5/7/13
to Johannes Rudolph, Naftoli Gugenheim, pschaus, scala-user, Sascha Van Cauwelaert

> (-Ywarn-adapted-args)

That is precious.

scala> class Huh(a: Any)

scala> new Huh

<console>:9: warning: Adapting argument list by inserting (): leaky (Object-receiving) target makes this especially dangerous.


My bash completion is out of date!  Maybe way out of date.

$ skala  -Yno-adapted-args
Welcome to Scala version 2.11.0-20130423-194141-5ec9dbd6a9 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_06).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class Huh(a: Any)
defined class Huh

scala> new Huh
<console>:9: warning: No automatic adaptation here: use explicit parentheses.
        signature: Huh(a: Any): Huh
  given arguments: <none>
 after adaptation: new Huh((): Unit)
              new Huh
              ^
<console>:9: error: not enough arguments for constructor Huh: (a: Any)Huh.
Unspecified value parameter a.
              new Huh
              ^


I have so much trouble with the long list of options, that I've considered something like:

$ scalac -Yish:adapt

to narrow it down for me.
Reply all
Reply to author
Forward
0 new messages