Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function* not specialized on Boolean for arguments #5285

Closed
scabug opened this issue Dec 7, 2011 · 4 comments
Closed

Function* not specialized on Boolean for arguments #5285

scabug opened this issue Dec 7, 2011 · 4 comments

Comments

@scabug
Copy link

scabug commented Dec 7, 2011

Going through the docs, I realized that Function1, Function2 are
only specialized on return type Boolean, not for arguments. For
higher-order methods such as fold, a specialization on Boolean
would be quite handy for performance.

@scabug
Copy link
Author

scabug commented Dec 7, 2011

Imported From: https://issues.scala-lang.org/browse/SI-5285?orig=1
Reporter: Marc Millstone (splittingfield)
Affected Versions: 2.9.1
See #5267

@neonxray
Copy link

Wouldn't think it is necessary to specialize for Boolean. Boolean only has two values true and false. When it is "boxed", it is actually referencing two pre-defined java.lang.Boolean objects, which does not impact performance at all. Can definitely close this one.

@SethTisue
Copy link
Member

agree

@SethTisue SethTisue closed this as not planned Won't fix, can't repro, duplicate, stale Oct 13, 2023
@som-snytt
Copy link

  val q: Boolean => Boolean = b => !b
  def h(x: Boolean) = q(x)

Am I supposed to expect boxing? The same with Int param does not box.

Here, h boxes before calling the lambda, which unboxes before calling my static !_.

You can mix in a specialized trait:

  trait P { def apply(b: Boolean): Boolean }
  val p: (Boolean => Boolean) with P = new Function1[Boolean, Boolean] with P {
    override def apply(b: Boolean) = !b
  }

Boxed apply unboxes and calls apply(Z) as you would hope. Of course h would use unboxed P#apply.

I recently

  def f(xs: List[Int]): Option[Int] =
    xs.collectFirst { case i: Int if i > 42 => i > 50 }
      .map {
        if (_) 1
        else  -1
      }

I see that this form is actually worse, as you don't get to handle the boxed value; it always unboxes, so it reboxes for the eq!

  def ffs(xs: List[Int]): Option[Int] =
    xs.collectFirst { case i: Int if i > 42 => i > 50 }
      .map(b => if (b eq java.lang.Boolean.TRUE) 1 else -1)

Presumably, only by taking Any (and casting to AnyRef) can you wind up doing the obvious:

def testit[A >: Boolean <: Any](v: A): Int  = if (v.asInstanceOf[AnyRef] eq java.lang.Boolean.TRUE) 1 else -1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants