How to indicate an unused function/method parameter

What is the correct way to name an unused but required method parameter?

  def validateCompatibility(em:EarthMap):Unit = {}

For this particular abstract class the validateCompatibility method has nothing to do, so the em parameter is unused. However, subclasses are free to override the method and write some assertion code for this method.

This declaration triggers a compiler warning, or at least a warning from IntelliJ about unused variable em. However, if I rename the variable to _ I now have compiler errors.

  def validateCompatibility(_:EarthMap):Unit = {}
')' expected
Definition or declaration expected
';' or newline expected
Definition or declaration expected
Reassignment to val
1 Like

I see this is already discussed ad nausium here naming unused variable

When I insert a comment on the previous line. The warning goes away, but I’m not sure what this comment is doing? Is it telling IntelliJ to emit no warnings for unused symbols for the next line?

  //noinspection ScalaUnusedSymbol
  def validateCompatibility(em:EarthMap):Unit = {}

Is it telling IntelliJ to emit no warnings for unused symbols for the next line?

Yes, exactly. See here: Disable and suppress inspections | IntelliJ IDEA Documentation

Personally, what I’d do is:

  • enable the Scala compiler unused warnings (e.g. -Wunused:params for unused parameters, see Scala Compiler Options | Scala Documentation for other options - personally I tend to enable all the unused warnings and a bunch of other -W and -Xlint options, but to each their own)
  • use @nowarn("cat=unused") in case of a false-positive warning (like your example)
  • disable that Intellij inspection in the Intellij preferences if it bothers you, since it’s redundant with the compiler warning anyway

If I am not mistaken you can just use the unused annotation, like this;

def validateCompatibility(@annotation.unused em:EarthMap):Unit = {}
6 Likes

thanks. Does that apply just to em, and not to other parameters in the parameter list?

Yeah, you need to add that annotation to each argument you want to mark as unused,

1 Like

the annotation doesn’t seem to be fully incorporated into the language.

  private val citiesByNameCountry = parseCities()
    .groupBy{case (name,country, @annotation.unused city) => (name,country)}
    .map{case ((name,country),s) => (name,country) -> s.map(_._3).head }

It would be nice to use syntax like case (name, country, _city) => (name,country) just to remind the human being reading the code that, oh we’re just stripping out the city.

In my opinion the code reads easier than case (name, country, _) => (name,country)

It was a similar proposal in the contributors room.

I kind of like that, but I liked even more a proposal where one could decide which fields to extract, since that would also solve another problems.
Sadly (for me) neither one got too much traction.

1 Like

Looking back at this thread several months later, I realize that the suggestion doesn’t seem to work.
Here’s the code I’m using

          val (colorization, bdd) = graphToBdd(List(biGraph.head._1), uniGraph, biGraph, biGraph.size,
                                               (@annotation.unused n: Double,
                                                @annotation.unused size: () => Double) => (),
                                               Nil,
                                               fold = 0,
                                               verbose = false)

And I get the following compilation errors

illegal start of simple expression
                                               (@annotation.unused n: Double,

/Users/jnewton/Repos/regular-type-expression/cl-robdd-scala/src/main/scala/bdd/MapColoring.scala:270:9
')' expected but '}' found.
        }

Here is a sample of this kind of syntax error

I’d be interested to update the thread with the correct syntax if anyone knows what that would be.

It doesn’t make much sense for a lambda functions I guess. If you don’t use the parameters, you could simply replace them with _:

(_, _) =>  ()

The unused annotation is mostly useful for overridden methods that need to match its base’s prototype when you don’t need all the parameters given. For lambda functions you don’t need to name the parameters in the first place.

3 Likes

Thanks for the explanation. I think I understand, but it sounds like a strange restriction.
As I recall it is illegal to use _ as a function parameter if the function is not anonymous. Right?

Both of the following trigger a compilation error. This is why I was thinking I could not use _ as a function parameter.

def bar(_) => 3.0
def bar(_:Double) => 3.0

These are methods, not functions. With functions, you can use underscore syntax for parameters, with methods you can’t.

3 Likes

@jimka I see an earlier post asked about patterns (not methods or functions).

The magic syntax is case X(foo @ _, bar @ _) => which tells linting that you want the name but not use it. It is an arbitrary convention, introduced before @unused annotation. val (a: Int @unused, b) = (17, 42) doesn’t do what you hope.

2 Likes