Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala IDE warning: "anonymous function convertible to method value"

Let's say I want to create an alias for a method:

def foo = bar(_)

This will warn that

Anonymous function convertible to a method value

And I'm not quite sure what that's supposed to mean, because when I try what I think this might mean:

def foo = bar

I get an error

Missing arguments for method bar(a:A)

Cannot resolve reference bar with such signature.

like image 936
User1291 Avatar asked Jul 05 '15 11:07

User1291


2 Answers

First, If you want to create an "alias" for method, that's enough:

scala> val foo = bar(_) //val instead of def, still warning from Idea
foo: Int => Int = <function1>

Second, this shoud remove Idea's warning:

scala> val foo = bar _
foo: Int => Int

Actually, it's not just alias - your method becomes converted into a function (eta-expansion). You cant' just specify method (compile-time entity) as compiler will expect parameters - you need to convert it into a function (using underscore) first. Sometimes it's done automatically when compiler expects a function:

scala> val foo: Int => Int = bar
foo: Int => Int = <function1>

So this probably what Idea wants from you. In other cases - you have to use eta-expansion operator (_) explicitly.

P.S/1. def foo = bar(_) (def instead of val) makes no sense as it will return new (but same) function every time, val (or lazy val to be safe from NullPointerException) just returns it once.

P.S/2. The difference between (_) and _ is that first is partially applied function (which does _ eta-expansion automatically), which means that for let's say:

scala> def bar(a: Int, b: Int) = a
bar: (a: Int, b: Int)Int

scala> def foo = bar _
foo: (Int, Int) => Int

scala> def foo = bar(_)
<console>:8: error: missing parameter type for expanded function ((x$1) => bar(x$1))
       def foo = bar(_)
                     ^
<console>:8: error: not enough arguments for method bar: (a: Int, b: Int)Int.
Unspecified value parameter b.
       def foo = bar(_)
                    ^

scala> def foo = bar(_, _)
foo: (Int, Int) => Int

you have to specify bar(_, _) as there are two arguments.

like image 51
dk14 Avatar answered Nov 13 '22 17:11

dk14


That's a suggestion from IntelliJ. If you click "More" in the suggestion, you'll see the following (sorry it's graphic, I can't copy the text):

enter image description here

You can either ignore or use bar _ instead of bar(_).

like image 40
bjfletcher Avatar answered Nov 13 '22 16:11

bjfletcher