Session.equals no longer (fully) reactive? [Meteor] - meteor

I need to if on the value of a Session variable in a reactive computation, and have the computation rerun when the value changes. According to the meteor docs this use case is ideal for Session.equals. So far so good, thus I have in my reactive computation code which calls Session.equals as in:
if (!Session.equals(key, undefined)) {
// now I know 'key' is defined
...
}
The code used to work well but for some reason it stopped doing so. Now (in ver METEOR#1.3.2.4) I'm noticing issues where although the Session value for keychanges, the reactive computation does not get rerun.
In one of my attempts to figure out the cause I've replaced the code with:
if (!!Session.get(key)) {
...
}
Which works - the computation is now getting rerun when expected!
Can anyone tell why would Sesssion.get() work, but not Session.equals()?
Could be relevant: the value of the Session variable changes but it is always 'defined' (e.g. from one non-empty string to another). Would that be sufficient to re-trigger the computation? IOW, maybe Session.equals is 'clever' enough to know the value changed from one defined value to another defined value, thus it establishes that a computation rerun isn't necessary, which causes the issue I'm experiencing?

You have actually answered it yourself.
Session.equals is an optimised version which reruns the computation only if the value has changed. Now as the value doesn't change from 'defined', it won't rerun the computation.

Related

How do I do jumps to a label in an enclosing function in LLVM IR?

I want to do an LLVM compiler for a very old language, PL/M. This has some peculiar features, not least of which is having nested functions with the ability to jump out of an enclosing function. In pseudocode:
toplevel() {
nested() {
if (something)
goto label;
}
nested();
label:
print("finished!");
}
The constraints here are:
you can only jump into the top-level function, luckily
the stack does get unwound (the language does not support destructors, so this is easy)
you do not have to have executed the statement at label before jumping (so the naive setjmp/longjmp method doesn't work).
code at label can be executed normally, i.e. it's not like catch
LLVM has a number of non-local jump mechanisms, such as the exception handling system, but I've never used that. Can this be implemented using LLVM exceptions, or are they not suitable for this? Is there an easier way?
If you want the stack to get unwound, you'll likely want it to be in a separate function, at least a separate LLVM IR function. (The only real exception is if your language does not have a construct like C's "alloca()" and you don't allow calling a nested function by address in which case you could inline it.)
That part of the problem you mentioned, jumping out of an enclosing function, is best handled by having some way for the callee to communicate "how it exited" to the caller, and the caller having a "switch()" on that value. You could stick it in the return value (if it already returns a value, make it a struct of both values), you could add a pointer parameter that it writes to, you could add it a thread-local global variable and fill that in before calling longjmp, or you could use exceptions.
Exceptions, they're complex (I can't describe how to make them work offhand but the docs are here: https://llvm.org/docs/ExceptionHandling.html ) and slow when the exception path is taken, and really intended for exceptional situations, not for normal code. Setjmp/longjmp does the same thing as exceptions except simpler to use and without the performance trade-off when executed, but unfortunately there are miscompiles in LLVM which you need will be the one to fix if you start using them in earnest (see the postscript at the end of the answer).
Those two options cover the ways you can do it without changing the function signature, which may be necessary if your language allows the address to be taken then called later.
If you do need to take the address of nested, then LLVM supports trampolines. See https://llvm.org/docs/LangRef.html#trampoline-intrinsics . Trampolines solve the problem of accessing the local variables of the calling function from the callee, even when the function is called by address.
PS. LLVM miscompiles setjmp/longjmp today. The current model is that a call to setjmp may return twice, and only functions with the returns_twice attribute may return twice. Note that this doesn't affect the whole call stack, only the direct caller of a function that returns twice has to deal with the twice-returning call-- just because function F calls setjmp does not mean that F itself can return twice. So far, so good.
The problem is that in a function with a setjmp, all function calls may themselves call longjmp. I'd say "unless proven otherwise" as with all things in optimizers, but there is no attribute in LLVM doesnotlongjmp or any code within LLVM that attempts to answer the question of whether a function could call longjmp. Adding that would be a good optimization, but it's a separate issue from the miscompile.
If you have code like this pseudo-code:
%entry block:
allocate val
val <- 0
setjmpret <- call setjmp
br i1 setjmpret, %first setjmp return block, %second setjmp return block
%first setjmp return block:
val <- 1;
call foo();
goto after;
%second setjmp return block:
call print(val);
goto after;
%after:
return
The control flow graph shows that is no path from val <- 0 to val <- 1 to print(val). The only path with "print(val)" has "val <- 0" before it therefore constant propagation may turn print(val) into print(0). The problem here is a missing control flow edge from foo() back to the %second setjmp return block. In a function that contains a setjmp, all calls which may call longjmp must have a CFG edge to the second setjmp return block. In LLVM that control flow edge is missing and LLVM miscompiles code because of it.
This problem also manifests in the backend. The first time I heard of this problem it was in the context of the backend losing track of the placement of variables on the stack, and this issue was the underlying root cause.
For the most part setjmp/longjmp seems to work because LLVM isn't usually able to analyze what calling foo() might do and can't perform the optimization. For instance if val was not a fresh allocation but was a pointer, then who's to say that foo() doesn't have access to the same pointer, and then performs "val <- 1" on it? If LLVM can't prove that impossible, that precludes the transform to print(0). Secondly, setjmp/longjmp are just not used often in real code.

Meteor reactive-var package is missing the equals() method, is this a bug?

I'm learning about reactive programming in Meteor:
https://stephenwalther.com/archive/2014/12/05/dont-do-react-understanding-meteor-reactive-programming
I believe that the idea behind Session.equals(key, value) is to remember an association between the reactive variable and the desired value so that updates only propagate to the surrounding code if the equality changes. That way if we have hundreds of views that depend on the variable, only the old and new views get their update code triggered when the value changes.
Note that this would not be the case if we called Session.get(key) === value because every view's code would be called when the variable changes. This is discussed further under the Session.get versus Session.equals() section of the article.
But I found an inconsistency under the Using Reactive Variables section where it says:
Notice that a reactive variable, unlike the Session object, does not have an equals() method. Yes, that is a shame.
So reactive-var is missing equals() but reactive-dict has ReactiveDict.equals().
I can't really see a conceptual reason to exclude ReactiveVar.equals(). Maybe they had no context for storing the association, or maybe there is some scoping or other issue with Javascript that prevents this that I don't fully understand.
So my question is: is this a bug?
Should I just always use reactive-dict? In which case I would change everything from:
let myReactiveVar = new ReactiveVar();
...
if(myReactiveVar.get() === 'myValue')
To the more verbose (but performant):
let myReactiveDict = new ReactiveDict();
...
if(myReactiveDict.equals('myReactiveVar', 'myValue'))
Which would match the functionality provided by Session.equals().
Another option would be to extend the ReactiveVar prototype with my own equals() method or inherit it in a child class and provide a MyReactiveVar.equals() method. Kudos if someone can provide examples to do either of these workarounds that we could submit as a pull request to the Meteor maintainers.
Update: I forgot to mention that ReactiveVar does take an equalsFunc optional parameter in its constructor. It might be possible to hack that as a reactive code block to partially implement equals() functionality without extending the class. Also, here is a related issue on GitHub.
Update: to save time, here is the relevant source code for ReactiveVar and ReactiveDict.equals(). I believe that the value parameter gets converted to serializedValue and is then added as a dependency in ReactiveDict, but I still don't see why it wouldn't be possible to do something similar for ReactiveVar.
The reason there's no equals method for ReactiveVar is because set only invalidates the computations is the new value differs from the current value.
Sets the current value of the ReactiveVar, invalidating the Computations that called get if newValue is different from the old value.
const example = new ReactiveVar(0);
Tracker.autorun(() => {
console.log(example.get());
});
example.set(1); // logs 1
example.set(0); // logs 0
example.set(0); // doesn't log
This is similar behaviour to ReactiveDict's equals method.
Note that set on ReactiveDict does not behave this way. Calling set broadcasts that the value has changed. If you want to prevent the computation from invalidating, that is when you would use equals.
Set a value for a key in the ReactiveDict. Notify any listeners that the value has changed (eg: redraw templates, and rerun any Tracker.autorun computations, that called ReactiveDict.get on this key.)

How to separate concerns functionally

I'm writing a program in Scala and trying to remain as functionally pure as is possible. The problem I am facing is not Scala specific; it's more to do with trying to code functionally. The logic for the function that I have to code goes something like:
Take some value of type A
Use this value to generate log information
Log this information by calling a function in an external library and evaluate the return status of the logging action (ie was it a successful log or did the log action fail)
Regardless of whether the log succeeded or failed, I have to return the input value.
The reason for returning the input value as the output value is that this function will be composed with another function which requires a value of type A.
Given the above, the function I am trying to code is really of type A => A i.e. it accepts a value of type A and returns a value of type A but in between it does some logging. The fact that I am returning the same value back that I inputted makes this function boil down to an identity function!
This looks like code smell to me and I am wondering what I should do to make this function cleaner. How can I separate out the concerns here? Also the fact that the log function goes away and logs information means that really I should wrap that call in a IO monad and call some unsafePerformIO function on it. Any ideas welcome.
What you're describing sounds more like debugging than logging. For example, Haskell's Debug.Trace.trace does exactly that and its documentation states: "These can be useful for investigating bugs or performance problems. They should not be used in production code."
If you're doing logging, the logging function should only log and have no further return value. As mentioned by #Bartek above, its type would be A -> IO (), i.e. returning no information () and having side-effects (IO). For example Haskell's hslogger library provides such functions.

Should every function which calls itself be considered a recursive function?

I understand what recursive functions are, but consider the following example of a function meant to get the local version of data on an item, check if there is new data about it available online based on locally stored cache time, and if there is, updating the local data with the new version, returning up-to-date data about it either way.
function getItemData(id){
var local=getLocalItemData(id);
if(!local.cacheTime.upToDate()){
var newData=getOnlineItemData(id);
updateLocalItemData(id, newData);
return getItemData(id);
}
else{
return local.returnHumanReadable();
}
}
My argument against considering it a recursive function is the fact that it will only end up calling itself on rare occasions when the cache time indicates the data has expired, and that the function only calls itself for convenience.
Instead of using return getLocalItemData(id).returnHumanReadable(); I can use return getItemData(id); because it will return the same result, as the newly saved data won't need to be refreshed again in the several microseconds it will take the function to call itself. Also, it is much shorter: in the actual code, I would use lower level commands instead of those function calls, resulting in code duplication which would make the entire function harder to read and maintain.
So, do you think that my argument makes any sense, or do you consider this to be nothing more than a matter of code organization?
The short answer is: yes it is recursive
It becomes important if you consider a platform that does not support recursion
Since it can call itself, your code will not work on that platform because it is technically recursion
For a trivial case like this replacing the recursive call with getLocalItemData(id).returnHumanReadable(); will allow it to work on this platform. In fact, you can change your code to:
function getItemData(id){
var local=getLocalItemData(id);
if(!local.cacheTime.upToDate()){
var newData=getOnlineItemData(id);
updateLocalItemData(id, newData);
local=getLocalItemData(id);
}
return local.returnHumanReadable();
}
NOTE: If you cannot 100% guarantee that only one call is needed, change the if to while

how does Tracker.autorun pick out its computation?

Looking at Tracker.autorun, this mostly works magically...but I'd like to know how it decides which variables are going to form the dependency for the computation. It picks out only "reactive" vars, for example the following:
window.bar = 1
Tracker.autorun (c) =>
bar = window.bar
foo = Session.get('foo')
console.log('autorun', foo, bar)
If I change the value of Session.set('foo') this will cause the computation to run again.
whereas just changing window.bar doesn't cause a rerun. If I use a subscribe result (not a collection) this also works, so that I guess is reactive too.
Are there any guides to understanding this behavior a bit better?
EDIT:
thanks for the comments below that clarify the computation is able to be inferred because accessors are used for reactive vars, so meteor can track deps.
However I need a bit more clarity to understand when a var is flagged. for instance in this example below, the subscribe call is outside the autorun, but it puts the results into an array. So that means that Tracker is not just tracking calls to (reactive var) accessor methods, but also any variables that are referenced within a block - even if the calls to setup those methods are outside the autorun() block.
subList = [
Meteor.subscribe("Players"),
Meteor.subscribe("Stuff" )
]
Tracker.autorun (c) =>
subReady = _.filter subList, (item) ->
return item.ready()
allDone = (subList.length == subReady.length)
# this code will rerun when the subs ready() are true
maybe i should add this as a new question... it's related to this question .
I'm not an expert and haven't read much about it, but I can try to explain it briefly.
All reactive variables have a thing called a dependency. For example, when one creates a new ReactiveVar, an new dependency is created. See here.
To retrieve the value from a reactive variable, one must call a function. In that "getter", the dependency is instructed to remember that it has a dependency. For example, see here for ReactiveVar.get.
To change the value for a reactive variable, one must call a function. In that "setter", the dependency is notified that something has changed, and that signals that all functions depending on the dependency must rerun. For example, see here for ReactiveVar.set.
Not complicated, right? Well, that was just the easy part, all that remains now is building the infrastructure that makes it work :) That's harder and more complicated to explain.
Reactive variables aren't reactive by themselves; they must be evaluated in a reactive environment in order to be reactive. A reactive environment is created by calling Tracker.autorun. See here.
When you call Tracker.autorun, the function you passed to it will be executed in a new reactive environment, and all dependencies the reactive variables notifies of with the depend method will be tracked by the environment. When you call aDependency.depend, this function will be executed, and it kind of adds the dependency to the environments list over dependencies it depends on.
When a reactive variable changes its value, this function will be executed. It tells the environment that one of the reactive variables it depends on has changed, and invalidates all the dependencies in the environment. After this has happened, the entire function you passed to Tracker.autorun will be re-run, and the new dependencies will be tracked.
Do you get the big picture? It's implementation is a bit more complicated than I've explained, but I think that's kind of how it works.
Notice that whenever you access a reactive variable, it's through a function call, like Session.get(...), or collection.find(...).fetch(), or Meteor.status(). A function like Session.get does not only get the value of a Session variable, but also registers a dependency on the current computation (the current computation is dynamically scoped, so Session.get knows that it was called from an autorun).
Here's how you can implement your own reactive variable using Tracker.Dependency:
dependency = new Tracker.Dependency()
currentValue = null
#setCurrentValue = (newValue) ->
if newValue isnt currentValue
# rerun computations which depend on this Dependency
dependency.changed()
currentValue = newValue
#getCurrentValue = ->
# register this dependency on the current computation (if there is one)
dependency.depend()
return currentValue
And here's how you could use it:
setCurrentValue("hello")
Tracker.autorun ->
console.log(getCurrentValue())
# => "hello" printed
setCurrentValue("goodbye") # => "goodbye" printed
For more information, you could look at this guide: https://meteor.hackpad.com/DRAFT-Understanding-Deps-aAXG6T9lkf6 (note that Tracker was originally called Deps in older versions of Meteor)

Resources