I'm using rx-scala, which is a subproject of rx-java. I'll be using Scala syntax and hope that everyone understands.
I'm encountering odd behavior, and I don't know whether it's a bug or misusage of rx operators on my behalf.
Problem Statement
I have an ox: Observable[X] and a trigger observable tr: Observable[()]. I want an observable oy that is a transformation of ox using function f: Function[X,Y], but only when triggered, since f is potentially expensive.
If there is no transformed value for the last value of ox, then oy should be null.
Some remarks:
ox is hot, as it is the result of UI events.
ox behaves correctly (both values and timing), as I checked with println debugging.
oy fires at the correct times; it's just using outdated values of ox, when its a not-null value.
Current Code
oy = ox.sample(tr).map(f).merge(ox.map(x => null))
The problem with the above code is: It works initally, but after some time, when triggering tr, oy is applying f to old values of ox. When not changing ox, if I trigger tr repeatedly, the results get newer and eventually catch up.
If I remove the merge to not reset to null, then everything works fine (probably, as the effect appears non-deterministic).
Question
My presented code is buggy.
I'd like to know whether I'm doing something wrong.
I welcome alternative ways of achieving what I need.
For the Jave people
generics/type annotation: ox: Observable[X] means Observable<X> ox
lambdas: x => null means x -> null
I'm now using the following solution, which is short and apparently doesn't cause the problem to turn up:
tr.withLatestFrom(ox)((_,x) => f(x)) merge problem.map(_ => null)
Related
The following is the constraint I tried to implement in MiniZinc
constraint forall (t in trucks)
(all_different(c in customers where sequence[t,c] !=0) (sequence[t,c]));
that is, I want every row element to be different for the sequence matrix when the sequence value doesn't equal to 0.
and got the error
MiniZinc: type error: no function or predicate with this signature found: all_different(array[int] of var opt int)'.
As indicated by some other threads I've added include "alldifferent.mzn"; command, still showing that error.
This is part of assignment, sorry for not able to push all my code here, please let me know if there is any extra information needed.
To clearly understand what you are doing, you can write your expression in a different way:
all_different([sequence[t,c] | c in customers where sequence[c,t] != 0])
Note that this uses array comprehensions. These are great to express a lot of things, but if sequence is an array of variables then the number of variables in this comprehension is unknown. This is a big problem for many solvers. And is thus not supported by many of them.
It is at least impossible with the all_different predicate.
Your problem however is a well known one, thus a different predicate is available. You can express the same constraint in the following way:
for(t in trucks) (
alldifferent_except_0([sequence[c,t] | c in customers])
)
There are a couple of bindings to moment.js I'd like to use for rendering time spans in my Halogen UI which have types something like
diffMins :: forall eff. Moment -> Moment -> Eff (now :: NOW | eff) Number
If I want to use this function in my UI like this:
H.span_ [H.text $ diffMins (fromEpoch_ 0) (fromEpoch_ myTimeStamp)]
But this is in Eff so I can't.
What I can do is call into moment with this function:
js:
exports.duration_ = function (millis) {
return moment.duration(millis).humanize();
};
ps:
foreign import duration_ :: Number -> String
humanizeMilliseconds :: Milliseconds -> String
humanizeMilliseconds (Milliseconds n) = duration_ n
My question (or several) then:
Is it "cheating" to call into javascript without saying it's an Eff. If not when is it considered ok and when not? I could squit either way and see these functions as side effecting or not.
If I couldn't have changed the way I'm calling moment, or indeed it is a bad idea, is there a way to do this in HTML?
It is indeed not possible to perform anything effectful during renders in Halogen, as HTML is only data and render is state -> HTML.
As Phil says in the comment, you don't have to use Eff in the signature of FFI functions though, if you're sure they perform no effects. In this case, it's probably safe, since it's basically arithmetic on dates - but there may be some locale-specific stuff going on? If so it's only a little bit dodgy, as at least it will always give the same result on the same machine, unless the OS clock is messed with. I'd be a little hesitant to accept that as being effect free, but if it was really a problem and I needed to do it I'd at least ensure the function is not exported so it can't be used anywhere else except in the exceptional circumstance.
You could just do this in the component eval somewhere though and store the value in the component state - myTimeStamp must already be in there, so you could compute this value at the same time? That way you're not recomputing a static value with each render too.
What is the definition of a "glitch" in the context of Functional Reactive Programming?
I know that in some FRP frameworks "glitches" can occur while in others not. For example RX is not glitch free while ReactFX is glitch free [1].
Could someone give a very simple example demonstrating how and when glitches can occur when using RX and show on the same example how and why the corresponding ReactFX solution is glitch free.
Thanks for reading.
Definition
My (own) favorite definition:
A glitch is a temporary inconsistency in the observable state.
Definition from Scala.Rx:
In the context of FRP, a glitch is a temporary inconsistency in the dataflow graph. Due to the fact that updates do not happen instantaneously, but instead take time to compute, the values within an FRP system may be transiently out of sync during the update process. Furthermore, depending on the nature of the FRP system, it is possible to have nodes be updated more than once in a propagation.
Example
Consider integer variables a, b. Define sum and prod such that
sum := a + b,
prod := a * b.
Let's rewrite this example to JavaFX:
IntegerProperty a = new SimpleIntegerProperty();
IntegerProperty b = new SimpleIntegerProperty();
NumberBinding sum = a.add(b);
NumberBinding prod = a.multiply(b);
Now let's write a little consistency check:
InvalidationListener consistencyCheck = obs -> {
assert sum.intValue() == a.get() + b.get();
assert prod.intValue() == a.get() * b.get();
};
sum.addListener(consistencyCheck);
prod.addListener(consistencyCheck);
a.set(1);
b.set(2);
This code fails with an assertion error on the last line, because:
b is updated (to 2)
sum is updated (to 3)
`consistencyCheck` is triggered, `a == 1`, `b == 2`, but `prod == 0`, because `prod` has not been updated yet
This is a glitch — prod is temporarily inconsistent with a and b.
Glitch Elimination Using ReactFX
First note that ReactFX is not "glitch free" out of the box, but it gives you tools to eliminate glitches. Unless you take some conscious effort to use them, ReactFX is not more glitch-free than RX (e.g. rxJava).
The techniques to eliminate glitches in ReactFX rely on the fact that event propagation is synchronous. On the other hand, event propagation in RX is always asynchronous, thus these techniques cannot be implemented in an RX system.
In the example above, we want to defer listener notifications until both sum and prod have been updated. This is how to achieve this with ReactFX:
import org.reactfx.Guardian;
import org.reactfx.inhibeans.binding.Binding;
IntegerProperty a = new SimpleIntegerProperty();
IntegerProperty b = new SimpleIntegerProperty();
Binding<Number> sum = Binding.wrap(a.add(b)); // Binding imported from ReactFX
Binding<Number> prod = Binding.wrap(a.multiply(b)); // Binding imported from ReactFX
InvalidationListener consistencyCheck = obs -> {
assert sum.getValue().intValue() == a.get() + b.get();
assert prod.getValue().intValue() == a.get() * b.get();
};
sum.addListener(consistencyCheck);
prod.addListener(consistencyCheck);
// defer sum and prod listeners until the end of the block
Guardian.combine(sum, prod).guardWhile(() -> {
a.set(1);
b.set(2);
});
Short answer : glitch = inonconsistent/illegal/meaningless state.
Here is a relevant link : https://social.msdn.microsoft.com/Forums/en-US/bc2c4b71-c97b-428e-ad71-324055a3cd03/another-discussion-on-glitches-and-rx?forum=rx
Also, see the 29th minute of Sodium's author talk for another answer : http://youtu.be/gaG3tIb3Lbk.
And a relevant SOF answer : how to avoid glitches in Rx
So here is my understanding of what a glitch is based on Tomas' answer.
There is a dataflow graph, with 3 nodes : A, B, C
A->B
A->C
In this simple example, a glitch happens if I change A and that causes to change B but C has not been updated yet. This is a glitch.
C is not consistent with B.
Say B=2*A, C=2*A.
Then if B is not equal C then that is a glitch.
Here is an extremely short and theoretical example of a fatal "glitch" situation in C# RX
var t = Observable
.Interval(TimeSpan.FromSeconds(1))
.Publish()
.RefCount();
var s = t.CombineLatest(t, (t1,t2) => 1/(1-(t1-t2));
Since t1 and t2 both represent the latest value of the hot observable t, one would assume t1-t2 to always be 0. So s should always be 1.
But when subscribing to s, we indeed get 1 as the first observed value, but then we get a division by zero exception. In RxJS we would get NaN.
The reason is simple: a.CombineLatest(b, f) will react when either a or b produces a value, combining this new value and the last observed value of the other observable. This is by design, but from my experience, people using RX sometimes consider these to be glitches, especially when coming from other FRP libraries that have a different notion of "latest".
This is of course a contrived example, just meant to illustrate a misconception about CombineLatest.
Maybe CombineLatest should have been called WhenAny as in the ReactiveUI library, this would clarify the operational semantics?
Why using foreach, map, flatMap etc. are considered better than using get for Scala Options? If I useisEmpty I can call get safely.
Well, it kind of comes back to "tell, don't ask". Consider these two lines:
if (opt.isDefined) println(opt.get)
// versus
opt foreach println
In the first case, you are looking inside opt and then reacting depending on what you see. In the second case you are just telling opt what you want done, and let it deal with it.
The first case knows too much about Option, replicates logic internal to it, is fragile and prone to errors (it can result in run-time errors, instead of compile-time errors, if written incorrectly).
Add to that, it is not composable. If you have three options, a single for comprehension takes care of them:
for {
op1 <- opt1
op2 <- opt2
op3 <- opt3
} println(op1+op2+op3)
With if, things start to get messy fast.
One nice reason to use foreach is parsing something with nested options. If you have something like
val nestedOption = Some(Some(Some(1)))
for {
opt1 <- nestedOption
opt2 <- opt1
opt3 <- opt2
} println(opt3)
The console prints 1. If you extend this to a case where you have a class that optionally stores a reference to something, which in turn stores another reference, for comprehensions allow you to avoid a giant "pyramid" of None/Some checking.
There are already excellent answers to the actual question, but for more Option-foo you should definitely check out Tony Morris' Option Cheat Sheet.
The reason it's more useful to apply things like map, foreach, and flatMap directly to the Option instead of using get and then performing the function is that it works on either Some or None and you don't have to do special checks to make sure the value is there.
val x: Option[Int] = foo()
val y = x.map(_+1) // works fine for None
val z = x.get + 1 // doesn't work if x is None
The result for y here is an Option[Int], which is desirable since if x is optional, then y might be undetermined as well. Since get doesn't work on None, you'd have to do a bunch of extra work to make sure you didn't get any errors; extra work that is done for you by map.
Put simply:
If you need to do something (a procedure when you don't need to capture the return value of each invocation) only if the option is defined (i.e. is a Some): use foreach (if you care about the results of each invocation, use map)
If you need to do something if the option defined and something else if it's not: use isDefined in an if statement
If you need the value if the option is a Some, or a default value if it is a None: use getOrElse
Trying to perform our Operations with get is more imperative style where u need to tel what to do and how to do . In other words , we are dictating things and digging more into the Options internals. Where as map,flatmap are more functional way of doing things where we are say what to do but not how to do.
I'm following a tutorial. (Real World Haskell)
And I have one beginner question about head and tail called on empty lists: In GHCi it returns exception.
Intuitively I think I would say they both should return an empty list. Could you correct me ? Why not ? (as far as I remember in OzML left or right of an empty list returns nil)
I surely have not yet covered this topic in the tutorial, but isnt it a source of bugs (if providing no arguments)?
I mean if ever passing to a function a list of arguments which may be optionnal, reading them with head may lead to a bug ?
I just know the GHCi behaviour, I don't know what happens when compiled.
Intuitively I think would say they both should return an empty list. Could you correct me ? Why not ?
Well - head is [a] -> a. It returns the single, first element; no list.
And when there is no first element like in an empty list? Well what to return? You can't create a value of type a from nothing, so all that remains is undefined - an error.
And tail? Tail basically is a list without its first element - i.e. one item shorter than the original one. You can't uphold these laws when there is no first element.
When you take one apple out of a box, you can't have the same box (what happened when tail [] == []). The behaviour has to be undefined too.
This leads to the following conclusion:
I surely have not yet covered this topic in the tutorial, but isnt it a source of bugs ? I mean if ever passing to a function a list of arguments which may be optionnal, reading them with head may lead to a bug ?
Yes, it is a source of bugs, but because it allows to write flawed code. Code that's basically trying to read a value that doesn't exist. So: *Don't ever use head/tail** - Use pattern matching.
sum [] = 0
sum (x:xs) = x + sum xs
The compiler can guarantee that all possible cases are covered, values are always defined and it's much cleaner to read.