eliom
eliom copied to clipboard
let-rec defined in shared section, rec call from inner client section: doesn't work
{client{
let g = ...
}}
{shared{
let rec f x =
...
{{ g f }}
}}
==> in {{ g f }}, f is unknown (Error: Unbound value.). I can use a reference as a work around for this, but it's not very pleasant nor elegant.
Any thoughts? Any chance for this to be fixed?
Maybe you could try something like:
{client{
let rec f x =
...
g f
}}
{server{
let rec f x =
...
{{ g f }}
}}
In the client value {{ g f }}, f refers to the one implemented in the client section.
We need to revisit name binding and injections, but it is quite complicated. Your case is particularly tricky, because f (or even %f if you try that) really needs to refer to the client version, even for the version of {{ g f }} that appears in the server code.
In my very particular case, I prefer using a reference than duplicating the code, because the function is quite large. :-/
I have an idea to solve that by changing the translation of shared sections, but I have to check that it doesn't introduce other issues.
We still have this issue.
let%client foo' = ref (fun () -> assert false)
let%client bar' = ref (fun () -> assert false)
let%shared foo () = f [%client fun _ -> (!~%bar') ()]
let%shared bar () = f [%client fun _ -> (!~%foo') ()]
let%client () =
foo' := foo ;
bar' := bar
We have plenty of this pattern in besport, it quite heavy, quite difficult to read as well, and I woul LOVE us to be able to write something like
let%shared rec foo () = f [%client fun _ -> ~%bar ()]
and bar () = f [%client fun _ -> ~%foo ()]
Is there any hope to have this problem solved?
@Drup , what about your idea?
let%shared rec f x = [%client ~%f ~%x ]
Is there any situation where it actually makes sense that ~%f or ~%x refer to the server-side variables instead of the client-side ones?
f is tricky, but x is simple. On the server we have:
let rec f x = [%client ~%f ~%x ]
How are we supposed to know the x that f receives on the client? Which particular application? All we know is the server-side argument to f.
On the server we have:
let rec f x = [%client ~%f ~%x ]
Precisely. The question is: is this what we want?
I wish I could simply write
let%shared rec f x = [%client f ~%x]
and that would simply expand to
let%client rec f x = f x
let%server rec f x = [%client f ~%x]
Would that introduce issues?
None that comes to mind. In this version you don't inject f, so the semantics looks intuitive enough. @Drup ?
On the client, this expands to something like
let _eliom_fragment_UFyFI'1 _eliom_escaped_ident_1 =
f _eliom_escaped_ident_1
let rec f x =
_eliom_fragment_UFyFI'1 x
It shouldn't be too hard to make the fragment definition(s) and f mutually recursive and thus enable what you want.
It would change the semantics of
let%client f () = ()
let%shared rec f () = [%client f () ]
Then, what's weird is that it doesn't seem it would work with x in
let%client rec f x = f x
let%server rec f x = [%client f x]
That being said, that "weirdness" would still be quite convenient.