This page is no longer maintained — Please continue to the home page at www.scala-lang.org

A little generics/inference question

3 replies
Roshan Dawrani
Joined: 2010-07-20,
User offline. Last seen 42 years 45 weeks ago.
Hi,
Can someone please help me understand why call "A1" and "A2" to generic methods foo()/bar() compile even though they don't pass the argument needed?

------------------------------------------------------
class Test {
    def test() {
        foo() // A1
        bar() // A2
    }
   
    def foo[T](y:T):T = {
        println("foo called with " + y)
        y
    }

    def bar[T](y:T) {
        println("bar called with " + y)
        y
    }
}
------------------------------------------------------

rgds,
Roshan
Stephen Tu
Joined: 2010-02-24,
User offline. Last seen 42 years 45 weeks ago.
Re: A little generics/inference question
$ scalac -Xprint:typer test1.scala
[[syntax trees at end of typer]]// Scala source: test1.scala
package <empty> {
  class Test extends java.lang.Object with ScalaObject {
    def this(): Test = {
      Test.super.this();
      ()
    };
    def test(): Unit = {
      Test.this.foo[Unit](());
      Test.this.bar[Unit](())
    };
    def foo[T >: Nothing <: Any](y: T): T = {
      scala.this.Predef.println("foo called with ".+(y));
      y
    };
    def bar[T >: Nothing <: Any](y: T): Unit = {
      scala.this.Predef.println("bar called with ".+(y));
      {
        y;
        ()
      }
    }
  }
}

so type Unit was inferred, and since () is unit, it compiles. here's the output if you call test():
scala> val t = new Test
t: Test = Test@1c9fe7e

scala> t.test
foo called with ()
bar called with ()
Roshan Dawrani
Joined: 2010-07-20,
User offline. Last seen 42 years 45 weeks ago.
Re: A little generics/inference question
Oh, you mean foo() has been taken as foo(())?

A corner grammar case perhaps - where foo() was chosen to mean foo(()) (i.e., parentheses-less call "foo ()") instead of foo(<no_arg>).

Thanks,
Roshan

On Sun, Aug 8, 2010 at 1:18 PM, Stephen Tu <steve33671 [at] gmail [dot] com> wrote:
$ scalac -Xprint:typer test1.scala
[[syntax trees at end of typer]]// Scala source: test1.scala
package <empty> {
  class Test extends java.lang.Object with ScalaObject {
    def this(): Test = {
      Test.super.this();
      ()
    };
    def test(): Unit = {
      Test.this.foo[Unit](());
      Test.this.bar[Unit](())
    };
    def foo[T >: Nothing <: Any](y: T): T = {
      scala.this.Predef.println("foo called with ".+(y));
      y
    };
    def bar[T >: Nothing <: Any](y: T): Unit = {
      scala.this.Predef.println("bar called with ".+(y));
      {
        y;
        ()
      }
    }
  }
}

so type Unit was inferred, and since () is unit, it compiles. here's the output if you call test():
scala> val t = new Test
t: Test = Test@1c9fe7e

scala> t.test
foo called with ()
bar called with ()

Stephen Tu
Joined: 2010-02-24,
User offline. Last seen 42 years 45 weeks ago.
Re: A little generics/inference question
On Sun, Aug 8, 2010 at 1:06 AM, Roshan Dawrani <roshandawrani [at] gmail [dot] com> wrote:
Oh, you mean foo() has been taken as foo(())?

A corner grammar case perhaps - where foo() was chosen to mean foo(()) (i.e., parentheses-less call "foo ()") instead of foo(<no_arg>).

I could be wrong, but I think its more to do with, in your specific case, interpreting the () as Unit instead of a function application with no arguments is the only way to make the expression type check correctly. it definitely isn't an assumption tied to the grammar, since then you could never call a function of no arugments.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland