Skip to content
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

Ordre d'évaluation inattendu #4072

Closed
vicuna opened this issue Jul 27, 2006 · 7 comments
Closed

Ordre d'évaluation inattendu #4072

vicuna opened this issue Jul 27, 2006 · 7 comments

Comments

@vicuna
Copy link

vicuna commented Jul 27, 2006

Original bug ID: 4072
Reporter: @alainfrisch
Assigned to: @lefessan
Status: resolved (set by @xavierleroy on 2012-04-08T17:38:45Z)
Resolution: suspended
Priority: normal
Severity: feature
Version: 3.09.2
Fixed in version: 3.13.0+dev
Category: ~DO NOT USE (was: OCaml general)
Related to: #7346
Monitored by: @gasche @lefessan

Bug description

Soit code suivant:
(print_endline "A"; fun x -> x) (print_endline "B")

ocamlopt produit du code qui affiche d'abord A puis B, contrairement à ocamlc.
L'ordre d'évaluation entre la fonction et l'argument sera inversé dans le cas
d'un appel direct, avec une fonction qui n'utilise pas son environnement mais qui n'est pas pure.

La ligne:
else Usequence(ufunct, app)
dans Closure.direct_appply est la coupable toute désignée.

@vicuna
Copy link
Author

vicuna commented Jul 27, 2006

Comment author: @alainfrisch

En fait, ça arrive aussi avec une fonction qui utilise son environemment:

let f u = (print_endline "A"; fun x -> u) (print_endline "B") in f ()

Pour le coup, c'est à cause de:
if fundesc.fun_closed then uargs else uargs @ [ufunct] in
toujours dans Closure.direct_apply.

@vicuna
Copy link
Author

vicuna commented Jul 27, 2006

Comment author: @alainfrisch

Pour régler le problème, on peut remplacer direct_apply par:

let pure_direct_apply fundesc ufunct uargs =
let app_args =
if fundesc.fun_closed then uargs else uargs @ [ufunct] in
match fundesc.fun_inline with
None -> Udirect_apply(fundesc.fun_label, app_args)
| Some(params, body) -> bind_params params app_args body

let direct_apply fundesc funct ufunct uargs =
if is_pure funct then pure_direct_apply fundesc ufunct uargs
else
let args = List.map (fun _ -> Ident.create "arg") uargs in
let f = Ident.create "fun" in
List.fold_left2
(fun e u id -> Ulet (id,u,e))
(Ulet (f, ufunct,
pure_direct_apply fundesc (Uvar f)
(List.map (fun a -> Uvar a) args)))
uargs args

@vicuna
Copy link
Author

vicuna commented Jul 27, 2006

Comment author: @alainfrisch

On peut aussi vouloir optimiser pour le cas où la fonction est une abstraction (car is_pure renvoie alors false) puisqu'il s'agit alors seulement de faire apparaître la définition de fonction, mais l'ordre d'évaluation n'a pas d'importance. Ce cas peut se présenter si on fait de l'inlining.

@vicuna
Copy link
Author

vicuna commented Aug 29, 2006

Comment author: @damiendoligez

evaluation order is not guaranteed for the moment...

@vicuna
Copy link
Author

vicuna commented Jan 31, 2012

Comment author: @alainfrisch

evaluation order is not guaranteed for the moment...

The "official" position on this seems to be:

<<
An observable difference in evaluation order between
ocamlc and ocamlopt is a quality of implementation issue: even if it
doesn't contradict the documentation, it's undesirable and should be
avoided if we reasonably can.

Isn't it a case where we reasonably can?

@vicuna
Copy link
Author

vicuna commented Feb 1, 2012

Comment author: @lefessan

Fixed in commits r12108 and 12109, by changing the execution order in bytecode to be the same one as in native code (better to avoid changes in production executables).

@vicuna
Copy link
Author

vicuna commented Feb 18, 2012

Comment author: @xavierleroy

As discussed at the latest bug hunt meeting, I am very uncomfortable with changing ocamlc to implement an evaluation order different from that predicted by the push-enter model of the ZAM abstract machine. I reverted commits 12108 and 12109, and I'm putting this PR in the "suspended" category (= no immediate action necessary).

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

No branches or pull requests

2 participants