Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0007586OCamllanguage featurespublic2017-07-14 14:492017-08-31 16:54
Assigned Tofrisch 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0007586: Request: evaluation order of 'let ... and ...'
DescriptionIt would be useful if the evaluation order of `let p1 = e1 and p2 = e2 in ...` were the same as `match e1, e2 with p1, p2 -> ...`.

According to the manual, the evaluation order is currently unspecified, with the only constraint being that e1 is evaluated before p1 and e2 before p2. Concretely, both ocamlc and ocamlopt choose the order e1, p1, e2, p2.

I would like to specify that both e1 and e2 are evaluated (in whatever order) before p1 and p2 are evaluated (in whatever order). This would make `let ... and ...` consistent with `match`, where the scrutinee is evaluated before the pattern, choosing for instance the order `e1, e2, p1, p2`.

This would be particularly useful for multicore, where I envisage having a combinator:

    val async : (unit -> 'a) -> 'a Lazy.t

which may begin forcing the supplied computation in a different thread. With the modified semantics for `let ... and ...`, we could then write:

    let lazy x = async f and lazy y = async g in ...

allowing f and g to be evaluated in parallel, rather than forcing f before computation of g begins.

Technically, this change would affect existing programs. However, the difference between the evaluation order is only observable to programs that use side-effecting patterns and rely on the intentionally undocumented evaluation order of let rec.
TagsNo tags attached.
Attached Files

- Relationships

-  Notes
gasche (administrator)
2017-07-15 15:28

At first I wasn't fond of the proposal cause it means that

  let p1 = e1 and p2 = e2 in e

cannot be desugared into

  let p1 = e1 in
  let p2 = e2 in e

(or "let p2 .. let p1 ..")

where scope allows. On the other hand, it does allow desugaring into

  let x1 = e1 in
  let x2 = e2 in
  let p1 = x1 in
  let p2 = x2 in e

(or "let x2 .. let x1 ..", or "let p2 .. let p1 ..")
yallop (developer)
2017-07-15 18:30

There's also the following scope-preserving desugaring, similar to the 'match' equivalence mentioned in the description

   let p1 = e1 and p2 = e2 in e
   let p1, p2 = e1, e2 in e

With the current semantics this is a valid desugaring. With the proposed semantics the desugaring can actually be used as a *definition* of 'let ... and', since it doesn't introduce any additional constraints on evaluation order.

(Nit: the current implementation has some additional differences in the typing of 'let in', which supports GADT refinement and existentials, and 'let ... and', which doesn't. To really use the desugaring as a definition those would probably need to be addressed.)
frisch (developer)
2017-07-17 18:56

> However, the difference between the evaluation order is only observable to programs that use side-effecting patterns and rely on the intentionally undocumented evaluation order of let rec.

The change also affects the case of partial patterns and side-effecting or non-terminating expressions.

It also affects life-time of values (and memory usage) since it forces keeping the values for e1 and e2, while the patterns could only keep sub-values live.


Without the change, users can write:

   let lazy x, lazy y = async f, async g in ...

This form makes it explicit that the async calculations start before the results are forced. Is it worth changing the language spec and implementation?
frisch (developer)
2017-08-31 16:54

I don't see a strong case for changing the specification (undefined order) or the current behavior. It is possible to request an explicit evaluation order by binding the tuple (with a let or match...with). At least, nothing prevents from experimenting with the async combinator in the context of the multicore work.

So I'm suspending this request for now. We can always revisit if the need arises later.

- Issue History
Date Modified Username Field Change
2017-07-14 14:49 stedolan New Issue
2017-07-15 15:28 gasche Note Added: 0018080
2017-07-15 18:30 yallop Note Added: 0018081
2017-07-17 18:56 frisch Note Added: 0018086
2017-08-31 16:54 frisch Note Added: 0018208
2017-08-31 16:54 frisch Status new => resolved
2017-08-31 16:54 frisch Resolution open => suspended
2017-08-31 16:54 frisch Assigned To => frisch

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker