Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    S
    @SRGOM
    @jhegedus42 I know this was December lol but I hope you either fixed it earlier or my solution worked
    Felix Dietze
    @fdietze
    @SRGOM is there any semantic difference between a.update(a.now + 1) and a() = a() + 1?
    Felix Dietze
    @fdietze
    I'd like to have some feedback on my proposal for safe data consistency mappings: lihaoyi/scala.rx#82
    S
    @SRGOM
    @fdietze I am very new myself and struggling a lot. Also, I've actually not seen a.update before. The difference between using a.now and a() on the right hand side is that a() can be used only inside reactive context. a.now can be used outside reactive context in which it gives the current value of a and inside reactive context in which it doesn't add a dependency to a from the reactive variable that the context is computing. Contrast this with using a() inside the context which adds a dependency
    Felix Dietze
    @fdietze
    @SRGOM that makes sense, thank you. The scala compiler provides syntactic sugar for apply() and update(): http://otfried.org/scala/apply.html, so a() = 5 is exactly the same as a.update(5)
    Probably interesting for everyone: I think we have a bit too many reactive dom libraries with the same goals: scala-js/scala-js#2843 What do you think?
    S
    @SRGOM
    I like scala.rx- You can learn it in 30 minutes. While I did battle it for a day in absense of any DOM example (which later told me how to add the ctx) it still beats anything else.
    Jean-Philippe Pellet
    @jppellet

    I'm trying the first example and it fails:

        val a = Var(1)
        val b = Var(2)
        val c = Rx { a() + b() }
        println(c.now) // 3
        a() = 4
        println(c.now) // 6

    fails with: This Rx might leak! Either explicitly mark it unsafe (Rx.unsafe) or make an implicit RxCtx available

    The docs don't seem to indicate I need to provide a Ctx in this case. And if I provide one, I'm afraid to override accidentally others that are supposed to be generated by macros at other places. Any hint?
    Jean-Philippe Pellet
    @jppellet
    Looks like the test classes use import Ctx.Owner.Unsafe._
    Felix Dietze
    @fdietze
    @jppellet I'm using: implicit val ctx: Ctx.Owner = Ctx.Owner.safe()
    Jean-Philippe Pellet
    @jppellet
    @fdietze OK, what's the difference? Yours is produced by a macro which seems to look for a safe context but fails when there isn't. So at the root of your app, don't you need to use unsafe somewhere?
    Felix Dietze
    @fdietze
    @jppellet I only have this line once at the root of my project
    I don't exactly know what's the difference
    S
    @SRGOM
    @fdietze I was just going through your google groups discussion and I would agree with you and say (here, don't want to use google groups) that I understand and partially share your concern. My fear was that scala-js has too little people working relative to the goods it offers and wish that the efforts were in sync. I don't have any numbers on scala-js usage, nor do I know if we're gathering a bigger audience and at what rate, but I would say that if our numbers are increasing then surely I (and I'm guessing you too?) don't mind this explosion since the number in a way legitimizes the existence of scala.js
    Felix Dietze
    @fdietze
    @SRGOM I agree with you. A huge audience would justify this kind of diversity. But I believe that we don't have enough library developers to have ~7 different libraries with the same goals.
    Zoo Sky
    @zoosky
    @lihaoyi what's the state of this project?
    Li Haoyi
    @lihaoyi
    it works, feel free to use it
    Fabian Schmitthenner
    @fkz
    @Voltir @lihaoyi hey, may you have a look at this issue #89, please?
    Nick Childers
    @Voltir
    Thanks for the sample @fkz - I can find some time to poke at it at the very least, and try to figure out way it happens
    Fabian Schmitthenner
    @fkz
    @Voltir Have you been able to reproduce it?
    Nick Childers
    @Voltir
    @fkz Yea - I was able to repo it, how very interesting
    Nick Childers
    @Voltir
    it looks to be related to something about mapping Rx'es..
    to be fair, I wrote that before I knew what the functor laws were.. i should probably revisit that code to make sure those things are lawful!
    Fabian Schmitthenner
    @fkz

    I don’t think this has anything to do with map or functor laws, as replacing map with the corresponding Rx construct leads to the same problem:

    import $ivy.`com.lihaoyi::scalarx:0.3.2`, rx._
    object Example {
    val v1 = Var(0)
    val v2 = Rx { v1() }
    val v22 = Rx { v1() }
    val v23 = Rx { v22() }
    val v3 = Rx { v23() }
    def q(implicit trackDependency: Ctx.Data) = {
        if (v1() == 0) v2()
        else {
          val b = v3() != v2()
          if (b)
            103
          else
            17
        }
      }
    val v = Rx { q }
    val list = {
        var result = List.empty[Int]
        val obs = v.trigger { result = result :+ v.now }
        v1() = 1
        v1() = 2
        result
      }
    }
    println(Example.list)

    This prints List(0, 103, 17) instead of List(0, 17), too.

    Felix Dietze
    @fdietze
    Hi, does anyone know which guarantees regarding frp glitches and multiple updates I get in a synchronous setting?
    Roland Reckel
    @rreckel

    Hi,
    I've got a problem with calling Futures out of Rx.
    Just copy and paste the following code into ScalaFiddle:

    import rx._
    import rx.async._
    import scala.concurrent.Future
    import scala.concurrent.Promise
    import scala.concurrent.ExecutionContext.Implicits.global
    
    def request(id: Int): Future[String] = {
      val p = Promise[String]()
      js.timers.setTimeout(500) {
        println(s"Request: $id")
        p.success(id.toString)
      }
      p.future
    }
    
    val id = Var[Int](0)
    val idString = id.flatMap(i => request(i).toRx("...")) 
    
    id() = 10
    println("End...")

    And you fall into a loop, with the following output:

    End...
    Request: 0
    Request: 10
    Request: 10
    Request: 10
    Request: 10
    Request: 10
    Request: 10
    Request: 10
    etc....

    Is this a known behaviour? or is this a bug?
    Is there a workaround for this kind of pattern?

    Thanks for your help.
    Roll

    Nick Childers
    @Voltir

    @rreckel Yea, currently the way flatMap works, it recreates the inner rx whenever the inner rx changes - this interacts poorly with toRx because, as you see in your test, it throws it in an infinite loop.

    Im having a hard time coming up with an alternate definition of toRx that actually works within flatmap and am considering just removing it all together.

    Nick Childers
    @Voltir

    So ive been playing around with alternatives, and this seems to work:

      implicit class FutureCombinators[T](val v: rx.Rx[Future[T]]) extends AnyVal {
        def flatten(initial: T)(implicit ec: ExecutionContext, ctx: Ctx.Owner): Rx[T] = {
          var result = Var(initial)
          v.foreach { x => x.foreach(result.update) }
          result
        }
      }

    And its used this way:
    id.map { x => request(x) }.flatten("...")

    @rreckel would something like that work? @fdietze what do you think?
    Nick Childers
    @Voltir
    Bleh, that actually doesnt work if you end up having the flattened future inside of a flatMap
    Roland Reckel
    @rreckel

    I tried your flatten function:

    import rx._
    import rx.async._
    import scala.concurrent.Future
    import scala.concurrent.Promise
    import scala.concurrent.ExecutionContext
    
    implicit class FutureCombinators[T](val v: rx.Rx[Future[T]]) extends AnyVal {
      def flatten(initial: T)(implicit ec: ExecutionContext, ctx: Ctx.Owner): Rx[T] = {
        val result = Var(initial)
        v.foreach { x => x.foreach(result.update) }
        result
      }
    }
    
    def request(id: Int): Future[String] = {
      val p = Promise[String]()
      js.timers.setTimeout(500) {
        println(s"Request: $id")
        p.success(id.toString)
      }
      p.future
    }
    
    import scala.concurrent.ExecutionContext.Implicits.global
    
    val id = Var[Int](0)
    val idString = id.map(i => request(i)) .flatten("...")
    
    val result = for {
      i <- id
      is <- idString
    } yield s"$i -> $is"
    
    result.foreach(println(_))
    
    id() = 10
    id() = 20
    println("End...")

    This code generates the following result in ScalaFiddle:

    0 -> ...
    10 -> ...
    20 -> ...
    End...
    Request: 0
    20 -> 0
    Request: 10
    20 -> 10
    Request: 20
    20 -> 20

    This is not exactly what I expected..... but still better than an infinite loop ;-)
    What do you think?

    Nick Childers
    @Voltir
    Interesting - I tried a similar test but had the map/flatten in the for loop and that created an infinite loop
    Maybe this and a section in the readme explaining this is sufficient?
    Felix Dietze
    @fdietze
    Are you trying with a 0.3 version or with latest master? To me it looks like the flatMap leak, which we fixed recently.
    Roland Reckel
    @rreckel
    I am using version 0.3.2
    I integrated the flatten function in my project now, and I don't have any loops anymore.
    Does an "official" latest version of scala.rx exist? I often try some snippets of code in ScalaFiddle but there the only version is 0.3.2
    Anyway I can test the code with the latest master and keep you informed.
    Roland Reckel
    @rreckel

    Hi again,
    I am sorry to report that the latest master does not resolve the loop in flatMap with toRx.
    The following script can be executed in ammonite:

    import $ivy.`com.lihaoyi::scalarx:0.4.0-SNAPSHOT`, rx._, rx.async._
    import Ctx.Owner.Unsafe._
    
    import scala.concurrent._
    import scala.concurrent.duration._
    import scala.concurrent.ExecutionContext.Implicits.global
    
    object FlatMap {
    
      def test() = {
        def request(id: Int): Future[String] = Future {
          Thread.sleep(500)
          println(s"Request: $id")
          id.toString
        }
    
        val id = Var[Int](0)
        val idString = id.flatMap(i => request(i).toRx("..."))
    
        id() = 10
        id() = 20
        println("End...")
        Await.result(Future{Thread.sleep(3000); println("Waited long enough")}, 30 seconds)
      }
    }
    
    FlatMap.test()

    and produces the following output:

    End...
    Request: 0
    Request: 10
    Request: 20
    Request: 20
    Request: 20
    Request: 20
    Request: 20
    Waited long enough
    Request: 20
    Felix Dietze
    @fdietze
    @rreckel Could you please open a PR with a failing test case?
    Nick Childers
    @Voltir
    I've been trying to tackle this problem - it's not the same issue as the flatmap problem. It also seems really hard to solve in a satisfying way.
    Making futures compose nicely in Rx contexts is hard because the re-evaluation step recreates the future, creating the cycle of infinite loop
    Roland Reckel
    @rreckel
    Call me crazy, but would it be possible to create a "toRx" function for Monix Task? Would that be easier perhaps, as those are lazy evaluated?
    I guess I will have to look at the scala.rx code a bit.
    Nick Childers
    @Voltir
    Sure - I think that's possible
    Perhaps something akin to how sttp does its effect encoding https://github.com/softwaremill/sttp
    I wouldn't want to add a dependency to monix in the core repo though
    Roland Reckel
    @rreckel
    You are right.... adding a dependency is not good.
    Nick Childers
    @Voltir
    What gives me hope is that toRx does appear to work if the definition is outside of the flatmap - I think if I can make the flatmap macro generate the equivalent of that, we might finally have a decent solution