- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Cannot use methods that named as +, -, ~, !
Wed, 2011-10-26, 01:01
Hi all,
Consider
scala> def !(x: Any) {println("method '!'")}
$bang: (x: Any)Unit
scala> !(5)
:12: error: value unary_! is not a member of Int
!(5)
^
scala> !("x")
:12: error: value unary_! is not a member of java.lang.String
!("x")
^
The method is definitely here:
scala> $bang(5)
method '!'
I know, why this happens: the Scala parser treats symbols +,-,~,! at the beginning of expressions
*always* as unary operators regardless of the real presence of corresponding methods "unary_x". (The
only exception is if the '-' is a part of numeric literal at the same time). Whether there is a
method with the same name, is simply ignored (understandable, since that info isn't here yet):
http://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_9_1_final/src/c...
I think that the error messages above are misleading.
But don't know how to change that behavior. I see this as related to the common question about
handling of infix, postfix, and prefix operators:
Relative precedence of postfix and infix operators
http://groups.google.com/group/scala-language/browse_thread/thread/c204b...
What do you think about?
--
Best regards,
Eugen
Wed, 2011-10-26, 17:07
#2
Re: Cannot use methods that named as +, -, ~, !
Hi Erik,
On 2011-10-26 15:35, Erik Osheim wrote:
> On Wed, Oct 26, 2011 at 02:01:38AM +0200, Eugen Labun wrote:
>> scala> def !(x: Any) {println("method '!'")}
>> $bang: (x: Any)Unit
>>
>> scala> !(5)
>> :12: error: value unary_! is not a member of Int
>> !(5)
>> ^
>>
>> scala> !("x")
>> :12: error: value unary_! is not a member of java.lang.String
>> !("x")
>> ^
>>
>> The method is definitely here:
>
> The messages says "unary_! is not a member of Int". If you check you'll
> see that there is no method called "unary_!" in the Int class. Seems
> pretty correct to me.
>
> While I can see the appeal of trying to craft a message that a beginner
> will more easily understand, I also worry that this will actually
> hinder their ability to see what's going on. Learning that "!(3)" is
> interpreted as "(3).unary_!()" is useful.
Yoe are right, of course. But I assumed that a beginner would rather ask "why is my method !(x:Any)
not called?"
>
Wed, 2011-10-26, 17:27
#3
Re: Cannot use methods that named as +, -, ~, !
I disagree, it looks pretty wrong to me.
A method is defined and used as intended, still the compiler doesn't accept it. He isn't talking about implicit conversions at all, but about a very simple and explicit method call.
There might be reasons why we don't want to accept this code, but the error message doesn't make any sense.
Bye
A method is defined and used as intended, still the compiler doesn't accept it. He isn't talking about implicit conversions at all, but about a very simple and explicit method call.
There might be reasons why we don't want to accept this code, but the error message doesn't make any sense.
Bye
Wed, 2011-10-26, 18:37
#4
Re: Cannot use methods that named as +, -, ~, !
On Wed, Oct 26, 2011 at 8:57 AM, Eugen Labun wrote:
> Actually I'm not shure, that this behevior (unconditional treatment of some characters as prefix
> operators) is really intended (therefore, asking here). At least, cannot find this in SLS.
It's implied by the grammar. This production:
PrefixExpr ::= [‘-’ | ‘+’ | ‘~’ | ‘!’] SimpleExpr
Is considered before
SimpleExpr1 ArgumentExprs
which means -(x) is parsed as -x and will never be considered for
this.-(x). It is generally considered a bad idea, with good reason I
think, to incorporate this kind of not-yet-available semantic
information into parsing (i.e. "if there's no unary_- in the operand,
go looking for a - method on "this".)
Thu, 2011-10-27, 19:17
#5
Re: Cannot use methods that named as +, -, ~, !
On Wednesday, October 26, 2011 12:10:12 PM UTC-4, Paul Phillips wrote:
It seems to me that this _might_ be worthwhile of a compiler warning (you can define a method with a normally unary name, but the compiler could tell you that it's only possible to invoke it via explicit dot and parens). But yes, adding it as a valid SLS case might just make things more ambiguous overall.
Note of clarification, this should be s/method on "this"/method that is in scope/ to satisfy the original post's description, which simply defined an in-scope method !(Any).which means -(x) is parsed as -x and will never be considered for
this.-(x). It is generally considered a bad idea, with good reason I
think, to incorporate this kind of not-yet-available semantic
information into parsing (i.e. "if there's no unary_- in the operand,
go looking for a - method on "this".)
It seems to me that this _might_ be worthwhile of a compiler warning (you can define a method with a normally unary name, but the compiler could tell you that it's only possible to invoke it via explicit dot and parens). But yes, adding it as a valid SLS case might just make things more ambiguous overall.
On Wed, Oct 26, 2011 at 02:01:38AM +0200, Eugen Labun wrote:
> scala> def !(x: Any) {println("method '!'")}
> $bang: (x: Any)Unit
>
> scala> !(5)
> :12: error: value unary_! is not a member of Int
> !(5)
> ^
>
> scala> !("x")
> :12: error: value unary_! is not a member of java.lang.String
> !("x")
> ^
>
> The method is definitely here:
The messages says "unary_! is not a member of Int". If you check you'll
see that there is no method called "unary_!" in the Int class. Seems
pretty correct to me.
While I can see the appeal of trying to craft a message that a beginner
will more easily understand, I also worry that this will actually
hinder their ability to see what's going on. Learning that "!(3)" is
interpreted as "(3).unary_!()" is useful.