Here goes basic hello world example using scala.rx in version 0.3.1.
It doesn't compile because of lack of implicit ownerCtx: rx.Ctx.Owner. How do I get this instance?
import rx._
val a = Var(1)
val b = Var(2)
val c = Rx{ a() + b() }
This Rx might leak! Either explicitly mark it unsafe (Rx.unsafe) or ensure an implicit RxCtx is in scope!
[error] val c = Rx{ a() + b() }
[error] ^
[error] one error found
The interesting thing is that in scala REPL it works!?
scala> import rx._
val a = Var(1)
val b = Var(2)
val c = Rx{ a() + b() }
import rx._
scala> a: rx.Var[Int] = Var@2c(1)
scala> b: rx.Var[Int] = Var@2f(2)
scala> c: rx.Rx.Dynamic[Int] = Rx@d1(3)
scala>
Update:
After adding implicit val ctx = Ctx.Owner.Unsafe code compiles. But this doesn't look safe...
It seems that providing implicit value of
rx.Ctx.Owneris done auto-macro-magically only when code requesting forrx.Ctx.Owneris inside code block which will run only once. This includesobjects,vals,lazy vals, etc.This example will compile without an issue because
val c = ...will evaluate only once.Similarly example mentioned in question but pasted in scala REPL.
Such limitation is because of Rx leaks problem in scala.rx library. They are present when creating higher ordered Rx variables (Rx variable which contains another Rx variable). More about an issue of leaks can be read on sala.rx project site.
As remedy to leaks - concept of
rx.Ctx.Ownerwas introduced and voodo-macro. This exceprt from scala.rx shows interesting parts. NoteOwnercompanion object andimplicit def voodoo: Owner:It turns out that static blocks of code evaluate only once and are immune of leaks. This is why
voodooallows compiler to find implicit. Try to design code in such way.In cases when code is not in static one and you are sure that your code will evaluate only once (scripts in test for example) the common solution is to provide
Unsafeimplicit instance fromOwnercompanion object. Just importimport Ctx.Owner.Unsafe._then.Here how it is done in BasicTests of scala.rx sources: