- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Why does this compile?
Thu, 2009-11-12, 02:05
Someone please explain to my feeble mind why this compiles:
object Foo {
def bar(i: Int) = println(i)
def bar(i: Int) (f: Float) = println(i*f)
}
object Foo {
def bar(i: Int) = println(i)
def bar(i: Int) (f: Float) = println(i*f)
}
Thu, 2009-11-12, 03:27
#2
Re: Why does this compile?
I suspect that it compiles because the second one merges the multiple parameter lists to
def bar(i:Int , f:Float)
which is a valid overloading of bar.
Unfortunately, the compiler is then confused because it likes to be able to convert this to
bar: (i:Int) => ( (f:Float)=>Unit )
by creating a class like so:
class F(i:Int) { def apply(f:Float) = bar(i,f) }
i.e. by converting the parameter lists to separate function applications.
But now it's faced with two valid interpretations of bar(i:Int), which is what you see when you write the code, and which is what might make you think that it shouldn't compile.
(On the .class file side, though, I'd think that
def bar(i:Int) (f:Float) = println(i*f)
def bar(i:Int,f:Float) = println(i+f)
would be the one that conflicts, however; how does Scala keep this straight?)
--Rex
On Wed, Nov 11, 2009 at 8:04 PM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:
def bar(i:Int , f:Float)
which is a valid overloading of bar.
Unfortunately, the compiler is then confused because it likes to be able to convert this to
bar: (i:Int) => ( (f:Float)=>Unit )
by creating a class like so:
class F(i:Int) { def apply(f:Float) = bar(i,f) }
i.e. by converting the parameter lists to separate function applications.
But now it's faced with two valid interpretations of bar(i:Int), which is what you see when you write the code, and which is what might make you think that it shouldn't compile.
(On the .class file side, though, I'd think that
def bar(i:Int) (f:Float) = println(i*f)
def bar(i:Int,f:Float) = println(i+f)
would be the one that conflicts, however; how does Scala keep this straight?)
--Rex
On Wed, Nov 11, 2009 at 8:04 PM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:
Someone please explain to my feeble mind why this compiles:
object Foo {
def bar(i: Int) = println(i)
def bar(i: Int) (f: Float) = println(i*f)
}
Thu, 2009-11-12, 04:47
#3
Re: Why does this compile?
On Wed, Nov 11, 2009 at 7:36 PM, Dean Wampler <deanwampler@gmail.com> wrote:
Actually neither can be referenced, at least on 2.8 trunk.
Looks like a bug to me, as there appears to be no way to reference the second definition without an "ambiguous reference" error.
Actually neither can be referenced, at least on 2.8 trunk.
Thu, 2009-11-12, 04:57
#4
Re: Why does this compile?
Irregardless of how its implemented on the JVM, I wouldn't think you should be allowed to have these two method signatures in the same class. Clearly there would be an ambiguity -- what type should "f" be here? It can't be inferred.
val f = bar(5);
I guess someone will have to dig in to the Scala lang spec to prove it is/is not allowed.
Best regards,
Brian Maso
(949) 395-8551
brian@blumenfeld-maso.com
twitter: @bmaso
skype: brian.maso
LinkedIn: http://www.linkedin.com/in/brianmaso
On Wed, Nov 11, 2009 at 6:17 PM, Rex Kerr <ichoran@gmail.com> wrote:
val f = bar(5);
I guess someone will have to dig in to the Scala lang spec to prove it is/is not allowed.
Best regards,
Brian Maso
(949) 395-8551
brian@blumenfeld-maso.com
twitter: @bmaso
skype: brian.maso
LinkedIn: http://www.linkedin.com/in/brianmaso
On Wed, Nov 11, 2009 at 6:17 PM, Rex Kerr <ichoran@gmail.com> wrote:
I suspect that it compiles because the second one merges the multiple parameter lists to
def bar(i:Int , f:Float)
which is a valid overloading of bar.
Unfortunately, the compiler is then confused because it likes to be able to convert this to
bar: (i:Int) => ( (f:Float)=>Unit )
by creating a class like so:
class F(i:Int) { def apply(f:Float) = bar(i,f) }
i.e. by converting the parameter lists to separate function applications.
But now it's faced with two valid interpretations of bar(i:Int), which is what you see when you write the code, and which is what might make you think that it shouldn't compile.
(On the .class file side, though, I'd think that
def bar(i:Int) (f:Float) = println(i*f)
def bar(i:Int,f:Float) = println(i+f)
would be the one that conflicts, however; how does Scala keep this straight?)
--Rex
On Wed, Nov 11, 2009 at 8:04 PM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:
Someone please explain to my feeble mind why this compiles:
object Foo {
def bar(i: Int) = println(i)
def bar(i: Int) (f: Float) = println(i*f)
}
Thu, 2009-11-12, 05:17
#5
Re: Why does this compile?
On Wed, Nov 11, 2009 at 9:56 PM, Brian Maso <brian@blumenfeld-maso.com> wrote:
Is it ambiguous? Isn't a trailing underscore *required* for currying?
Irregardless of how its implemented on the JVM, I wouldn't think you should be allowed to have these two method signatures in the same class. Clearly there would be an ambiguity -- what type should "f" be here? It can't be inferred.
val f = bar(5);
Is it ambiguous? Isn't a trailing underscore *required* for currying?
Thu, 2009-11-12, 18:57
#6
Re: Why does this compile?
Doh - I should really compile something before hitting send. Nils is definitely correct, "bar(5)" is unambiguously a reference to the first overloaded version of the method.
So now I'm wondering what the *spec* would say is illegal about this setup, if anything. Are these illegally overloaded methods? When you have a method with one argument list, and an overloading of that method with multiple argument lists, where the first argument list of both methods have the same type signature, is that illegal overloading?
In the general case, both methods could have multiple argument lists with some initial number of argument lists having the same type sig:
def bar(i: Int, x: String)(blah: List[Blah]):Unit = ...
def bar(i: Int, x: String)(flimflam: Seq[Pair[Int, Int]], hw: String)(d: Double): String = ...
Is this illegal according to the spec?
In the original example, it seems that there is a compiler error, but I'm not sure which of these two choices the error is:
1. Is it an error that the compiler didn't complain about the illegal method overloading?
2. Is it an error that the compiler doesn't support evaluating the expressions "bar(5) _" nor "bar(5)"?
Best regards,
Brian Maso
(949) 395-8551
brian@blumenfeld-maso.com
twitter: @bmaso
skype: brian.maso
LinkedIn: http://www.linkedin.com/in/brianmaso
On Wed, Nov 11, 2009 at 8:14 PM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:
So now I'm wondering what the *spec* would say is illegal about this setup, if anything. Are these illegally overloaded methods? When you have a method with one argument list, and an overloading of that method with multiple argument lists, where the first argument list of both methods have the same type signature, is that illegal overloading?
In the general case, both methods could have multiple argument lists with some initial number of argument lists having the same type sig:
def bar(i: Int, x: String)(blah: List[Blah]):Unit = ...
def bar(i: Int, x: String)(flimflam: Seq[Pair[Int, Int]], hw: String)(d: Double): String = ...
Is this illegal according to the spec?
In the original example, it seems that there is a compiler error, but I'm not sure which of these two choices the error is:
1. Is it an error that the compiler didn't complain about the illegal method overloading?
2. Is it an error that the compiler doesn't support evaluating the expressions "bar(5) _" nor "bar(5)"?
Best regards,
Brian Maso
(949) 395-8551
brian@blumenfeld-maso.com
twitter: @bmaso
skype: brian.maso
LinkedIn: http://www.linkedin.com/in/brianmaso
On Wed, Nov 11, 2009 at 8:14 PM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:
On Wed, Nov 11, 2009 at 9:56 PM, Brian Maso <brian@blumenfeld-maso.com> wrote:
Irregardless of how its implemented on the JVM, I wouldn't think you should be allowed to have these two method signatures in the same class. Clearly there would be an ambiguity -- what type should "f" be here? It can't be inferred.
val f = bar(5);
Is it ambiguous? Isn't a trailing underscore *required* for currying?
Thu, 2009-11-12, 19:17
#7
Re: Why does this compile?
Without trying it out or knowing how it is compiled or anything: such
methods (differing only in the return type) *can* be represented with
valid bytecode: at the VM level, the method signature *includes* the
return type (i.e. distinct return types means distinct methods).
I had an old blog post /quiz playing on this point:
http://code-o-matic.blogspot.com/2009/02/crazy-java-puzzler.html
At the java-the-language level, the signature of course does not
include the return type but includes type parameters. Sure enough,
there is a mismatch in these two concepts, meaning there are java
method signatures which cannot be translated to bytecode -yielding
name clashes- and bytecode method signatures which cannot be
translated to java.
Regards,
Dimitris
2009/11/12 Nils Kilden-Pedersen :
> Someone please explain to my feeble mind why this compiles:
>
> object Foo {
> def bar(i: Int) = println(i)
> def bar(i: Int) (f: Float) = println(i*f)
> }
>
Thu, 2009-11-12, 19:27
#8
Re: Why does this compile?
2009/11/12 Dimitris Andreou :
> Without trying it out or knowing how it is compiled or anything: such
> methods (differing only in the return type) *can* be represented with
> valid bytecode: at the VM level, the method signature *includes* the
> return type (i.e. distinct return types means distinct methods).
>
> I had an old blog post /quiz playing on this point:
> http://code-o-matic.blogspot.com/2009/02/crazy-java-puzzler.html
>
> At the java-the-language level, the signature of course does not
> include the return type but includes type parameters. Sure enough,
> there is a mismatch in these two concepts, meaning there are java
> method signatures which cannot be translated to bytecode -yielding
> name clashes- and bytecode method signatures which cannot be
> translated to java.
This should read: there are java method signatures which cannot be
translated to *unique* bytecode signatures, etc.
>
> Regards,
> Dimitris
>
> 2009/11/12 Nils Kilden-Pedersen :
>> Someone please explain to my feeble mind why this compiles:
>>
>> object Foo {
>> def bar(i: Int) = println(i)
>> def bar(i: Int) (f: Float) = println(i*f)
>> }
>>
>
Thu, 2009-11-12, 23:47
#9
Re: Why does this compile?
This very same scenario and questions have come up not two months ago, iirc. Personally, I think Scala should plain disallow the definition.
On Thu, Nov 12, 2009 at 3:49 PM, Brian Maso <brian@blumenfeld-maso.com> wrote:
--
Daniel C. Sobral
Veni, vidi, veterni.
On Thu, Nov 12, 2009 at 3:49 PM, Brian Maso <brian@blumenfeld-maso.com> wrote:
Doh - I should really compile something before hitting send. Nils is definitely correct, "bar(5)" is unambiguously a reference to the first overloaded version of the method.
So now I'm wondering what the *spec* would say is illegal about this setup, if anything. Are these illegally overloaded methods? When you have a method with one argument list, and an overloading of that method with multiple argument lists, where the first argument list of both methods have the same type signature, is that illegal overloading?
In the general case, both methods could have multiple argument lists with some initial number of argument lists having the same type sig:
def bar(i: Int, x: String)(blah: List[Blah]):Unit = ...
def bar(i: Int, x: String)(flimflam: Seq[Pair[Int, Int]], hw: String)(d: Double): String = ...
Is this illegal according to the spec?
In the original example, it seems that there is a compiler error, but I'm not sure which of these two choices the error is:
1. Is it an error that the compiler didn't complain about the illegal method overloading?
2. Is it an error that the compiler doesn't support evaluating the expressions "bar(5) _" nor "bar(5)"?
Best regards,
Brian Maso
(949) 395-8551
brian@blumenfeld-maso.com
twitter: @bmaso
skype: brian.maso
LinkedIn: http://www.linkedin.com/in/brianmaso
On Wed, Nov 11, 2009 at 8:14 PM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:
On Wed, Nov 11, 2009 at 9:56 PM, Brian Maso <brian@blumenfeld-maso.com> wrote:
Irregardless of how its implemented on the JVM, I wouldn't think you should be allowed to have these two method signatures in the same class. Clearly there would be an ambiguity -- what type should "f" be here? It can't be inferred.
val f = bar(5);
Is it ambiguous? Isn't a trailing underscore *required* for currying?
--
Daniel C. Sobral
Veni, vidi, veterni.
Tue, 2009-12-01, 18:47
#10
Re: Why does this compile?
Coincidentally, some days later, David Pollak's gave a presentation
which I just watched
(http://www.infoq.com/presentations/Scala-Basics-Bytecode-David-Pollak,
quite nice and informative for its length), which also mentioned (at
around 6:30) this little known fact about bytecode (i.e. that a
signature at the bytecode level includes the return type).
Regards,
Dimitris
2009/11/12 Dimitris Andreou :
> Without trying it out or knowing how it is compiled or anything: such
> methods (differing only in the return type) *can* be represented with
> valid bytecode: at the VM level, the method signature *includes* the
> return type (i.e. distinct return types means distinct methods).
>
> I had an old blog post /quiz playing on this point:
> http://code-o-matic.blogspot.com/2009/02/crazy-java-puzzler.html
>
> At the java-the-language level, the signature of course does not
> include the return type but includes type parameters. Sure enough,
> there is a mismatch in these two concepts, meaning there are java
> method signatures which cannot be translated to bytecode -yielding
> name clashes- and bytecode method signatures which cannot be
> translated to java.
>
> Regards,
> Dimitris
>
> 2009/11/12 Nils Kilden-Pedersen :
>> Someone please explain to my feeble mind why this compiles:
>>
>> object Foo {
>> def bar(i: Int) = println(i)
>> def bar(i: Int) (f: Float) = println(i*f)
>> }
>>
>
On Wed, Nov 11, 2009 at 7:04 PM, Nils Kilden-Pedersen <nilskp@gmail.com> wrote:
--
Dean Wampler
coauthor of "Programming Scala" (O'Reilly)
- http://programmingscala.com
twitter: @deanwampler, @chicagoscala
blog: http://blog.polyglotprogramming.com
Chicago-Area Scala Enthusiasts (CASE):
- http://groups.google.com/group/chicagoscala
- http://www.meetup.com/chicagoscala/ (Meetings)
http://www.linkedin.com/in/deanwampler
http://www.polyglotprogramming.com
http://aquarium.rubyforge.org
http://www.contract4j.org