-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
client/server annotations on local functions #907
Comments
So after simply adding syntax, this seems to work in some cases, but not in general. In particular variants of the example in #219 do not work, encountering an assertion failure in evailr. A smaller example that seems to encounter the same problem is this:
This creates a form that when submitted calls a client function that replaces another node with content provided by a server function that refers to the argument
If instead we manually lambda-lift and hoist the inner client and server functions to the top level everything works:
Likewise, if we lambda-lift the anonymous server function in-place things also work:
The assertion failure in evalir line 246 seems to be an unhandled case where it is expected that either we have both free variables and an environment, or neither free variables nor an environment, in a server call. So somewhere something things are getting out of sync. |
NOTE: the following code is a slightly revised JC's original example as 'fun () server' is changed into 'fun ()' with no location for making it runnable on Links 0.9.3.
This (client-side) error above is actually caused by a (server-side) error in evalir.ml Line 241 in 6ec7f5b
where find_fun f throws a NotFound exception because it cannot find serverTime (Variable 144) in fun_defs. It is a primitive function that can be found in env. Line 240-250 could be replaced by the following code
The code suggested above is merely a combination with a PrimitiveFunction case of apply in evalir.ml: Line 509 in 6ec7f5b
There is a need to clarify why the two variants, which are manually rewritten by JC, do work. The point is this. Requests with a global function (in fun_defs) work but those with a primitive function (that cannot be found there) do not work.
The example above does a request with a primitive function, serverTime, because the anonymous function that serverTime is inside is a client function (though the location is marked as Unknown). The two variants do requests with global functions. In parse_remote_call of webif.ml, every remote call request from clients is made to be represented with FunctionPtr all the time. This makes the evalir (apply) confused, and so any primitive functions would be attempted to be searched in fun_defs in the FunctionPtr case of apply in evalir.ml. Line 39 in 6ec7f5b
In Line 41 of the parse_remote_call function (webif.ml) Line 41 in 6ec7f5b
can be changed as shown in the following code.
By doing so, at least one problem is resolved. But another problem with not properly handling "l:action" and "l:href" seems to need a separate solution. Closures (in JavaScript) being created for handling "l:action" and "l:href" do not seem to be passed to the server properly. This is a totally different problem that should be resolve to have client/server annotations on local functions. |
Thanks for looking into this @kwanghoon ! I suggest we create a separate bug report with the breaking example, and then you can submit a PR to fix it. I'll do so now. The original enhancement suggestion was to add support for client and server annotations to the surface language, but this is not strictly necessary to deal with #219. Links already supports such annotations on arbitrary functions in the frontend abstract syntax, there is just no way to write them in source code. However, by trying to enable this to see if we can fix #219 by a local translation (as described in the issue comments) I ran into problems like those you describe. So it may be that if we fix these problems, things will just work, or if not hopefully we will have a better idea of what is needed without the problem you've identified confusing matters. |
In concrete syntax, Links only allows toplevel functions to carry client or server annotations. Inner and anonymous functions are not allowed to have locations in Links source code, and the location component of the abstract syntax is initialized to
loc_unknown
for these.Internally, there are a few places where functions with explicit locations are created by desugaring (e.g. in
desugarLAttributes
) and it seems that these do not cause problems.This issue proposes that the concrete syntax be extended to allow client/server locations on any function. Relatedly, we could also support
client
andserver
blocks, which would simply be syntactic sugar for:The implications of allowing client and server annotations anywhere are not clear. There may be places where we implicitly assume only top-level definitions have such annotations, which may result in wrong behavior if this is not the case. An initial experiment with this discussed in #906 resulted in an assertion failure in
evalir
, suggesting that in at least one place the existing code is not dealing with located local functions correctly. The non-working example is as follows:(Manually lambda-lifting this example and hoisting the server-functions to the toplevel resulted in correct behavior.)
The text was updated successfully, but these errors were encountered: