eliom icon indicating copy to clipboard operation
eliom copied to clipboard

let-rec defined in shared section, rec call from inner client section: doesn't work

Open pwbs opened this issue 9 years ago • 10 comments

{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?

pwbs avatar Nov 19 '15 11:11 pwbs

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.

vasilisp avatar Nov 19 '15 12:11 vasilisp

In my very particular case, I prefer using a reference than duplicating the code, because the function is quite large. :-/

pwbs avatar Nov 19 '15 13:11 pwbs

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.

Drup avatar Nov 19 '15 15:11 Drup

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?

sagotch avatar Dec 15 '16 13:12 sagotch

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?

pwbs avatar Jun 15 '17 14:06 pwbs

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.

vasilisp avatar Jun 15 '17 15:06 vasilisp

On the server we have:

let rec f x = [%client ~%f ~%x ]

Precisely. The question is: is this what we want?

pwbs avatar Jun 15 '17 15:06 pwbs

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?

pwbs avatar Jun 27 '17 08:06 pwbs

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.

vasilisp avatar Jun 27 '17 09:06 vasilisp

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.

pwbs avatar Jun 27 '17 12:06 pwbs