Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • 08:42
    mkeskells commented #8824
  • 08:41
    mkeskells synchronize #8824
  • 07:36
    mkeskells review_requested #8825
  • 07:33
    mkeskells review_requested #8841
  • 06:31
    eed3si9n commented #8820
  • 06:25
    eed3si9n edited #8820
  • 05:29
    eed3si9n synchronize #8820
  • 04:13
    eed3si9n synchronize #8820
  • 03:52
    eed3si9n synchronize #8820
  • 02:42
    SethTisue commented #8855
  • 00:47
    Ichoran commented #8856
  • 00:41
    som-snytt commented #8848
  • 00:31
    SethTisue commented #8036
  • 00:29
    SethTisue edited #8848
  • 00:28
    SethTisue edited #8848
  • 00:28
    SethTisue commented #8848
  • 00:28
    SethTisue commented #8848
  • 00:25
    SethTisue ready_for_review #8848
  • 00:25
    SethTisue edited #8848
  • 00:21
    scala-jenkins milestoned #8857
Lukas Rytz
@lrytz
@joshlemer thanks, i unblocked the queuing tool (https://scala-ci.typesafe.com/benchq/tasks)
Jasper Moeys
@Jasper-M
View contains a bunch of useful Iterator implementations such as dropRight and takeRight. Is there a reason why they are not available through the Iterator (and perhaps IterableOnceOps) API?
Jasper Moeys
@Jasper-M
Now you have to iterator.to(View).init.iterator 🤔
Josh
@joshlemer
Yeah I don't think that there was an explicit reason for not having those methods but I could be wrong
Ichoran
@Ichoran
There was an explicit reason, which is that Iterator is expected to not cache all of its elements most of the time, whereas View suggests a permanent backing. So iterator.to(View) actually allocates all the elements of the iterator, and then the view can, at least potentially, use more efficient implementations for dropRight and stuff. Does it actually? Dunno about those cases.
Hanns Holger Rutz
@Sciss

Is @specialized still bug ridden in 2.13?

object SpecializedTest {
  def main(args: Array[String]): Unit = {
    new Logic[Int]((a, b) => a + b)
  }

  private final class Logic[@specialized(Int, Long, Double) A](protected val inc: (A, A) => A)
    extends AbstractSeqGen[A]

  final class InAux[@specialized(Int, Long, Double) A](protected val cond: A => A = identity[A] _)
    extends AbstractInAux[A]

  trait AbstractInAux[@specialized(Int, Long, Double) A] {
    private var value: A = _
  }

  trait AbstractSeqGen[@specialized(Int, Long, Double) A] {
    new InAux[A]()
  }
}

this gives me:

Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
    at scala.runtime.BoxesRunTime.unboxToInt(BoxesRunTime.java:99)
    at de.sciss.fscape.SpecializedTest$AbstractInAux.$init$(SpecializedTest.scala:15)
    at de.sciss.fscape.SpecializedTest$InAux.<init>(SpecializedTest.scala:12)
    at de.sciss.fscape.SpecializedTest$AbstractSeqGen.$init$(SpecializedTest.scala:19)
    at de.sciss.fscape.SpecializedTest$Logic.<init>(SpecializedTest.scala:9)
    at de.sciss.fscape.SpecializedTest$Logic$mcI$sp.<init>(SpecializedTest.scala:8)
    at de.sciss.fscape.SpecializedTest$.main(SpecializedTest.scala:5)
    at de.sciss.fscape.SpecializedTest.main(SpecializedTest.scala)

What's going on here, and how can I work around it?

Seth Tisue
@SethTisue

Is @specialized still bug ridden in 2.13?

in short yes, @specialized has barely been touched since 2.10 days

I don't recognize this bug in particular
Hanns Holger Rutz
@Sciss
that's a bummer. can't find a work-around so far

I get the "reverse" error with this variant:

object SpecializedTest {
  trait Num[@specialized(Int, Long, Double) A] {
    def zero: A
  }

  implicit object IntNum extends Num[Int] {
    val zero = 0
  }

  def main(args: Array[String]): Unit =
    new Logic[Int]((a, b) => a + b)

  private final class Logic[@specialized(Int, Long, Double) A](protected val inc: (A, A) => A)
                                                              (implicit protected val num: Num[A])
    extends AbstractSeqGen[A]

  final class InAux[@specialized(Int, Long, Double) A](protected val cond: A => A = identity[A] _)
                                                      (implicit protected val num: Num[A])
    extends AbstractInAux[A]

  trait AbstractInAux[@specialized(Int, Long, Double) A] {
    protected def num: Num[A]

    private var value: A = num.zero
  }

  trait AbstractSeqGen[@specialized(Int, Long, Double) A] {
    protected def num: Num[A]

    new InAux[A]()(num)
  }
}

Now it's

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Double
    at scala.runtime.BoxesRunTime.unboxToDouble(BoxesRunTime.java:112)
    at de.sciss.fscape.SpecializedTest$AbstractInAux.$init$(SpecializedTest.scala:26)
    at de.sciss.fscape.SpecializedTest$InAux.<init>(SpecializedTest.scala:21)
    at de.sciss.fscape.SpecializedTest$AbstractSeqGen.$init$(SpecializedTest.scala:32)
    at de.sciss.fscape.SpecializedTest$Logic.<init>(SpecializedTest.scala:17)
    at de.sciss.fscape.SpecializedTest$Logic$mcI$sp.<init>(SpecializedTest.scala:15)
    at de.sciss.fscape.SpecializedTest$.main(SpecializedTest.scala:13)
    at de.sciss.fscape.SpecializedTest.main(SpecializedTest.scala)
Guillaume Martres
@smarter
l mean, there's always the workaround of not using specialized
you can consider it soft-deprecated since it's not in dotty and there's no plan to add it
Hanns Holger Rutz
@Sciss
well the system is built around Array because I need max performance for Array[Int] and Array[Double]. so giving up specialized would be a bad decision in my case. Only other solution would be to copy the source code three times LOL
Looks like scala/bug#10094
I could return to Scala 2.11.8 haha
but that bug seems gone, though
Hanns Holger Rutz
@Sciss
Similar to scala/bug#10094

Reduced:

// works
trait T[@specialized(Int) S] {
  var value: S = _
}

final class C[@specialized(Int) S] extends T[S]

object Test extends App {
  new C[Int]
}
// crashes at runtime
trait T[@specialized(Int, Double) S] {
  var value: S = _
}

final class C[@specialized(Int, Double) S] extends T[S]

object Test extends App {
  new C[Int]
}

I will file a bug even if nobody wants to touch specialized

Seth Tisue
@SethTisue
:+1: it's good to document the problems
sinanspd
@sinanspd
Anybody know where tapEach on Options is defined? Can't seem to locate it in the source code https://github.com/scala/scala/blob/2.13.x/src/library/scala/Option.scala
Guillaume Martres
@smarter
there's an implicit conversion from Option to Iterable
sinanspd
@sinanspd
@smarter perfect! found it! thank you
Guillaume Martres
@smarter
protip: in the scala 2 repl, you can write Option(1).tapEach // print then press tab and it will print the typechecked code corresponding to what was written
so you'll see the implicit conversion
Seth Tisue
@SethTisue
sadly you end up with an Iterable rather than an Option
Hanns Holger Rutz
@Sciss
what's the alternative to @specialized? mini-boxing seems abandoned. @specialized is still utterly broken, running now into IllegalAccessError and AbstractMethodError and what not. preferably something that works cross-platform (JVM, SJS, SN)
Guillaume Martres
@smarter
the alternative is wating years for Valhalla
sinanspd
@sinanspd
@SethTisue Is that something we want to change? I can dig in and see if we can work around with a small PR
Guillaume Martres
@smarter
if you're feeling very adventurous you could try doing specialization using staging: https://dotty.epfl.ch/docs/reference/metaprogramming/staging.html
Hanns Holger Rutz
@Sciss
wasn't there an sbt plugin to automatically generate multple source files or something. like templating?
Guillaume Martres
@smarter
but personally I'm just going to wait for valhalla, we've had enough broken half-solutions already
yeah you can do codegen too
som-snytt
@som-snytt
@Sciss in case it is fixed for you, there is @specialized(Specializable.Args) for short.
Hanns Holger Rutz
@Sciss
@som-snytt yes, it's these three. Do you think that helps with the bug? Or is it just to have shorter code?
Hanns Holger Rutz
@Sciss
java.lang.IllegalAccessError: Update to non-static final field de.sciss.fscape.stream.impl.SeqGenLogic$mcI$sp.de$sciss$fscape$stream$impl$SeqGenLogic$$hLen attempted from a different class (de.sciss.fscape.stream.impl.SeqGenLogic$mcI$sp) than the field's declaring class
lalalalala :weary:
Hanns Holger Rutz
@Sciss

And what do you do with

[error] Error while emitting SeqGenLogic.scala
[error] => de.sciss.fscape.stream.impl.SeqGenLogic (of class scala.reflect.internal.Types$NullaryMethodType)
[error] Error while emitting SeqGenLogic.scala
[error] => de.sciss.fscape.stream.impl.SeqGenLogic (of class scala.reflect.internal.Types$NullaryMethodType)
[error] Error while emitting SeqGenLogic.scala
[error] => de.sciss.fscape.stream.impl.SeqGenLogic (of class scala.reflect.internal.Types$NullaryMethodType)

?

Seems to come from a specialised class (not trait) calling a specialised method that returns a specialised class.
I think I will do the dynamic dispatch myself now.
som-snytt
@som-snytt
Yes, I only meant that it is easier to type. If there is a branch to try, I'll give it a try. Is this an upgrade that broke everything?
Hanns Holger Rutz
@Sciss
Not an upgrade, but me extending a lot of cases from just supporting Double to supporting the triplet Int, Long, Double
I'll try to get back to compile and testable stage
Hanns Holger Rutz
@Sciss

For instance, https://github.com/Sciss/FScape-next/blob/bcfec017ae2361034aebb7f2666614fe26fcdea9/core/src/main/scala/de/sciss/fscape/stream/impl/SeqGenLogic.scala#L30

If I go to console sbt fscape-core/console and :javap de.sciss.fscape.stream.impl.SeqGenLogicI, I see the run method boxes before calling hOut.next:

  public int run(int, int);
    descriptor: (II)I
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=3, locals=6, args_size=3
         0: iload_1
         1: istore_3
         2: iconst_0
         3: istore        4
         5: iload         4
         7: iload_2
         8: if_icmpge     60
        11: aload_0
        12: invokevirtual #44                 // Method hOut:()Lde/sciss/fscape/stream/impl/Handlers$OutIMain;
        15: iload_3
        16: invokestatic  #50                 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
        19: invokeinterface #54,  2           // InterfaceMethod de/sciss/fscape/stream/impl/Handlers$OutIMain.next:(Ljava/lang/Object;)V
        24: aload_0
        25: invokevirtual #56                 // Method hStep:()Lde/sciss/fscape/stream/impl/Handlers$InIAux;
        28: invokeinterface #59,  1           // InterfaceMethod de/sciss/fscape/stream/impl/Handlers$InIAux.next:()Ljava/lang/Object;
        33: invokestatic  #63                 // Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
        36: istore        5
        38: aload_0
        39: getfield      #65                 // Field inc:Lscala/Function2;
        42: iload_3
        43: iload         5
        45: invokeinterface #70,  3           // InterfaceMethod scala/Function2.apply$mcIII$sp:(II)I
        50: istore_3
        51: iload         4
        53: iconst_1
        54: iadd
        55: istore        4
        57: goto          5
        60: iload_3
        61: ireturn

Can I define OutIMain - without using the cursed @specialized so that in SeqGenLogicI.run the boxing is avoided?

Hanns Holger Rutz
@Sciss

Aha. If I "override" a method, like

  trait OutIMain extends OutMain[Int   , BufI] {
    override def next(v: Int): Unit
  }

then the call becomes

        11: aload_0
        12: invokevirtual #44                 // Method hOut:()Lde/sciss/fscape/stream/impl/Handlers$OutIMain;
        15: iload_3
        16: invokeinterface #48,  2           // InterfaceMethod de/sciss/fscape/stream/impl/Handlers$OutIMain.next:(I)V

Is this the "regular" way to avoid boxing, when having interface

trait Foo[A] {
  def next(v: A): Unit
}

to add

trait FooI extends Foo[A] {
  override def next(v: Int): Unit
}

?

Seth Tisue
@SethTisue
@sinanspd thanks for your PR, but we can't add anything to stdlib until Scala 3.1 or so, sadly, because of bincompat constraints
Ichoran
@Ichoran
@Sciss - Yes, that's the regular way. And you then pattern match out FooI so you get the specialized version. And this is probably back in scala/scala territory, not contributors any longer, since @specialized basically isn't being fixed any longer.
(Not that it was fixed all that much before, but more than none.)
sinanspd
@sinanspd
@SethTisue I realized that, reading through the CI logs. No worries. I ran into complaints a few times now that Futures don't support tapEach so figured I would take care of that. Would like me to submit a PR to dotty instead? Fully understanding we won't see 3.1 until mid/late-2021 earliest, I had a few other such small things I wanted to improve on. Might as well get those done while i am stuck at home :) :P
Seth Tisue
@SethTisue
@sinanspd there isn't anywhere to submit such changes at present, I'm afraid. scala/scala-dev#661
sinanspd
@sinanspd
got it. I will subscribe to the conversation for the time being and continue the changes on my fork until the time comes, they can be revisited