object and def with same name

Hi,
I’m wondering whether it is correct that the following declaration compiles. (See also stackoverflow question concerning inheritance: [1]):
    object A {      def m() = "" // with parentheses      object m     }     A.m() // method     A.m // object
On the other hand, the following does not compile:
    object A {      def m = "" // without parentheses      object m     } // error: method m is defined twice
And neither does any combination of def (with and without parentheses) and val or var compile.
As can be seen in the SO link, it gets more confusing when inheritance is used; but before filing a bug, I’d like to know which exactly is the expected behaviour.
Cheers/rike

[1]: http://stackoverflow.com/questions/7584400/overriding-a-method-with-an-object 

Re: object and def with same name

I believe this is correct. I can't remember the details, I don't run into them that often, but basically, when defining a method in Scala (as opposed to using a method defined in Java), whether or not the method is defined with parentheses determines wether or not it needs to be called with parentheses. In your first example, the method is defined with parentheses, so needs to be called with parentheses, so does not have a name clash with object m. This is in contrast to your second example.
I'm not sure how this applies to the val/var issue though. Like I say, I don't program in a fashion that I run into this sort of stuff much. But I'd check the Scala specification before filing a bug.
Ken

Re: object and def with same name



On Friday, September 30, 2011 10:11:40 PM UTC+2, Ken McDonald wrote:

But I'd check the Scala specification before filing a bug.

That’s basically why I’m asking because I’m not sure I find it in the specification.

Re: object and def with same name

Should I rather post this (as a potential bug report) to some other mailing list? It really bugs me that one can do:
    class T {      def t() = 10    }
    class TT extends T {      object t    }
And the method t from A is silently overridden and causes methods expecting an A to fail:
    scala> (new TT).t    res: object TT#t = TT$t$@78a16e6
    scala> ((new TT): T).t    java.lang.ClassCastException: TT$t$ cannot be cast to java.lang.Integer

(Sorry, got it wrong the first time I posted it…)
Cheers/rike

Re: object and def with same name

> Should I rather post this (as a potential bug report) to some other mailing
> list? It really bugs me that one can do:
>
> class T {
> def t() = 10
> }
>
> class TT extends T {
> object t
> }
>
> And the method t from A is silently overridden and causes methods expecting
> an A to fail:
>
> scala> (new TT).t
> res: object TT#t = TT$t$@78a16e6
>
> scala> ((new TT): T).t
> java.lang.ClassCastException: TT$t$ cannot be cast to java.lang.Integer

A `ClassCastException` without actually casting is definitely a bug. A
quick search didn't reveal any similar reports, so I think you should
file a bug.

Re: object and def with same name

Re: object and def with same name

Should I rather post this (as a potential bug report) to some other mailing list? It really bugs me that one can do:
    class A {      def t() = 10    }
    class B {      object t    }
And the method t from A is silently overridden and causes methods expecting an A to fail:
    scala> (new TT).t    res: object TT#t = TT$t$@78a16e6
    scala> ((new TT): T).t    java.lang.ClassCastException: TT$t$ cannot be cast to java.lang.Integer


Re: object and def with same name

> I believe this is correct. I can't remember the details, I don't run into
> them that often, but basically, when defining a method in Scala (as opposed
> to using a method defined in Java), whether or not the method is defined
> with parentheses determines wether or not it needs to be called with
> parentheses. In your first example, the method is defined with parentheses,
> so needs to be called with parentheses, so does not have a name clash with
> object m. This is in contrast to your second example.

It's not that easy :)

scala> def foo = 0
foo: Int

scala> foo
res0: Int = 0

scala> foo()
:9: error: Int does not take parameters
foo()
^

vs.

scala> def bar() = 0
bar: ()Int

scala> bar
res2: Int = 0

scala> bar()
res3: Int = 0

As demonstrated, defining a method with an empty parameter list (as
opposed to "no parameter list") also allows us to call it without
parentheses. However, I got the impression that this style is
discouraged as empty parameter lists usually indicate side effects both
at definition and at call site. Whether this is a good convention, is a
valid point for discussion (cf. State Transformers).

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