links
links copied to clipboard
Semantics of alien ground values?
What's the semantics of alien ground values? For example, one can conceive of the following program:
alien javascript "val.js" foo : Event;
var x server = foo;
fun mainPage(_) {
var p = spawnClient {
print(intToString(getPageX(x)))
};
page <#>Madness</#>
}
fun main() {
addRoute("/", mainPage);
servePages()
}
main()
The binding x = foo
essentially references an existential on the client side before the client has been booted! The program also fails fatally:
Links Error
***: Runtime error: Can't jsonize alien
However, what is the intended semantics of alien ground values? I suppose we must disallow them, because otherwise we would have to bind them, but with our current setup we have to delay binding them until after the client has been booted, meaning programs may no longer be read from top to bottom, however, then what happens when one eagerly references a delayed bound variable as above? Madness ensues.
This leads me to think that we should prohibit alien ground value declarations (it is called a Foreign Function Interface afterall).
Huh, I wasn't aware that "client" and "server" could go on var declarations...
One could interpret such "located constants" as functions which, when called, yield the constant value.
That is what e.g. ML5-style designs do, by tracking the locations of any located things in the type system, and forcing you to do an explicit "get" to move / copy them to the current location before being able to do anything else.
So one could perhaps also interpret an attempt to read a "var server" on the client, or vice versa, as an error, but we aren't currently keeping track of the locations in the type system so it would have to be a run-time error (as is currently the case).
If you call a server-side function that just prints its argument and pass it x
, does the right thing happen?
Of course, what I just wrote completely ignored the fact that x
is defined as an alien JavaScript thing, that is supposedly placed on the server - that seems nonsensical, and it makes sense to me that we should disallow alien things from being declared "server" (constant or function). Perhaps there is more that I'm missing here as well.
If you call a server-side function that just prints its argument and pass it x, does the right thing happen?
No it will die, because it cannot "jsonize" (what an awful word by the way) the variable foo
which is bound by the alien declaration. The "jsonizer" doesn't understand alien values of any kind. However, "jsonizing" happens before compilation to JavaScript to ensure that side effects are only played once.
That is what e.g. ML5-style designs do, by tracking the locations of any located things in the type system, and forcing you to do an explicit "get" to move / copy them to the current location before being able to do anything else.
I thought about that too, and it should work properly once the client has been booted. But here I am more concerned about the start up phase.
One could imagine booting/building the client incrementally, in which case I can envisage giving a sensible semantics to the above program.
By making the alien declaration a value binding it compiles (I had to change the type too, because I cannot produce a value of type Event
):
var foo client = 42;
var x server = foo;
fun mainPage(_) {
var p = spawnClient {
print(intToString(x))
};
page <#>Madness</#>
}
fun main() {
addRoute("/", mainPage);
servePages()
}
main()
However, this only works as long as the rhs of the binding var foo client = ...
contains no client side computation (which is another instance of the problem I described above).
From the above we can deduce that top-level client side variables are initialised on the server before being sent to the client.