scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
230 stars 21 forks source link

Unexpected partial function behaviour #12811

Closed Angel-O closed 1 year ago

Angel-O commented 1 year ago

Reproduction steps

Scala version: 2.13.9

Problem

Passing a PartialFunctiioin to a higher order function behaves differently depending on the syntax. When using the underscore notation the partial function behaves as a Function, ignoring the fallback logic and producing a MatchError.

I'm wondering if this is the expected behaviour


val pf: PartialFunction[Int, String] = {
     case 0 => "zero"
     case 1 => "one"
}

def hof(arg: Int, pf: PartialFunction[Int, String]): Unit = {
    val output = pf.applyOrElse(arg, (_:Int) => "invalid number")
    println(output)
}

hof(2, pf(_)) // produces MatchError
hof(2, pf)    // prints "invalid number"
lrytz commented 1 year ago

It's according to the language spec. Not sure if it's common enough for an -Xlint to be of value?

Angel-O commented 1 year ago

hi @lrytz thanks for the heads up, do you have a link to the specs where this specific feature is explained?

it's a bit unfortunate that it turns a PartialFunction into a Function but it still compiles. Causes a runtime error that it's hard to discover if you don't know about it

lrytz commented 1 year ago

https://scala-lang.org/files/archive/spec/2.13/06-expressions.html#placeholder-syntax-for-anonymous-functions

You can use a forum or discord for questions: https://www.scala-lang.org/community/

som-snytt commented 1 year ago

This is due to the more generous adaptation in 2.13.1.

It errors in 2.12, where you'd have to write

hof(2, x => x match { case y => pf(y) })

It could be specified to adapt x => pf(x) in the obvious way.

A discussion could be opened on the forum. (Scala 3 has the same behavior.)