openlang

Why warn about evidence?

This warning has me puzzled"

[warn] -- [E198] Unused Symbol Warning: /Users/.../polycheck/helpers.scala:25:30 
[warn] 25 |def hasStandardForm[P: PolyFamily](entry: P): Boolean = entry.asMatchable match ...
[warn]    |                              ^
[warn]    |                              unused implicit parameter

Although the implicit isn't used directly, it prevents hasStandardForm from accepting types outside the PolyFamily typeclass. Doesn't that make an (unused) implicit perfectly legitimate here?

The conversation continues 3

Follow the reasoning
  1. Permalink

    Right, that's what people call evidence.

    If memory serves, naming it ev avoids warnings in Scala 2, though I don't know whether Scala 3 honors that convention.

    Alternatively, simply apply @nowarn.

  2. Permalink

    Calling it ev still warns:

    [warn] -- [E198] Unused Symbol Warning: /Users/tavin/work/exercises-853_962/5/PolyFamily/src/test/scala/polycheck/helpers.scala:25:34 
    [warn] 25 |def hasStandardForm[P](entry: P)(using ev: PolyFamily[P]): Boolean = entry.asMatchable match
    [warn]    |                                  ^^
    [warn]    |                                  unused implicit parameter
  3. Permalink

    Certain familiar types are exempt from this warning, as are memberless types (“marker interfaces”).

    Comparable, for instance, triggers it. If nothing gets compared, perhaps the constraint has become unnecessary, or perhaps you neglected to make a comparison.

    scala> def inspect[A: Comparable] = "57".toInt
    1 warning found
    -- [E198] Unused Symbol Warning: -----------------------------------------------
    1 |def inspect[A: Comparable] = "57".toInt
      |                   ^
      |                   unused implicit parameter
    def inspect[A](using evidence$1: Comparable[A]): Int

    I believe you have to mark it unused in this expanded version:

    scala> def inspect[A](item: A)(using @unused witness: Comparable[A]) = item.toString
    def inspect[A](item: A)(using witness: Comparable[A]): String

    That's somewhat cleaner than @nowarn, although the latter accommodates context-bound notation.

    (I suspect name-based checks date to before selecting

    -Wunused:explicits,implicits,synthetics

    In fact, synthetics isn't available in Scala 3 yet, only Scala 2:

      -Wunused:synthetics               Warn if a synthetic implicit parameter (context bound) is unused.
      -Wunused:nowarn                   Warn if a @nowarn annotation does not suppress any warnings.
      -Wunused:params                   Enable -Wunused:explicits,implicits,synthetics.

    That arrived near the pandemic's beginning, presumably as a way of filling the hours.)

Other sides of the same question

  1. How can I subclass a class inside another class?

    Hi, In a package whose code is outside my control, there is a hierarchy of classes arranged as follows: I'm trying to add a w…

    Replies 1Latest activity scala
  2. Comparing have with let bindings in Lean4

    I've observed that these two expressions and behave identically. This also happens in theorem proofs. Are they interchangeabl…

    Replies 3Latest activity lean-4
  3. TypeScript Map initialization with string array entries

    I'm creating a Map whose entries each hold an array of strings. How can I declare its type and initialize it together in one…

    Replies 2Latest activity typescript