Skip to content

Fix Mantis PR#7767: interaction between labels and let rec check#1712

Merged
gasche merged 3 commits intoocaml:trunkfrom
yallop:letrec-labels
Apr 11, 2018
Merged

Fix Mantis PR#7767: interaction between labels and let rec check#1712
gasche merged 3 commits intoocaml:trunkfrom
yallop:letrec-labels

Conversation

@yallop
Copy link
Member

@yallop yallop commented Apr 9, 2018

A partially-applied labeled function, like this:

let f () ~y = e in f ~y

is translated into code that builds a function value, like this:

let f () ~y = e in let g = f in let z = y in fun () -> g ~y:z ()

Consequently, the let rec check used to accept definitions whose rhss were partial applications of this form (Mantis PR 7767).

This PR adds a case for partially-applied labeled functions to the new let rec check, to restore the old behaviour.

when is_ref vd -> Static
| Texp_apply (_,args)
when List.exists (function (_,None) -> true | _ -> false) args ->
Static
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To someone reading the code without the full typedtree structure in mind, it is very unclear what this case is about (is_ref above is self-explanatory). Maybe you could avoid the when here, have a single (non-ref) Texp_apply case, and have on the test a comment explaining what the test is about? (Or you could make the test an auxiliary function with a self-explanatory name.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or you could make the test an auxiliary function with a self-explanatory name.

I picked this option, so that the named function could be reused in the two locations where it's needed.

(* an expression abstracted over a missing argument *)
let arg env (_, eo) = option expression env eo in
let ty = Use.join (list arg env args) (expression env e) in
Use.(join (discard ty) (delay ty))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't remember the details well, but isn't join (discard ty) (delay ty) equal to delay ty?

I think it could be nice if you merged the two cases. If it is the case that inspect (join a b) is equal to join (inspect a) (inspect b), you could write a single logic, with a test that applies either a delay or an inspect depending on whether the application is delayed by a missing argument.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't join (discard ty) (delay ty) equal to delay ty?

It's equal to discard ty, I think.

Thanks for the suggestions. I've merged the two cases, and added a comment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked and indeed discard, which is an alias for guard, is less permissive than delay, so their union is discard. This is still a bit non-intuitive to me, but I guess that in a call-by-value setting it is natural that evaluating now (and then not using) demands more than evaluating later.

@gasche gasche merged commit 335e111 into ocaml:trunk Apr 11, 2018
@yallop yallop deleted the letrec-labels branch April 11, 2018 07:48
gasche added a commit that referenced this pull request Apr 11, 2018
@gasche
Copy link
Member

gasche commented Apr 11, 2018

Merged in 4.07 by 92a0f54.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants