-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Pushing the evaluation of default expression for optional arguments is not specified #5975
Description
Original bug ID: 5975
Reporter: @alainfrisch
Assigned to: @alainfrisch
Status: resolved (set by @alainfrisch on 2015-12-03T12:57:35Z)
Resolution: suspended
Priority: normal
Severity: minor
Target version: 4.03.0+dev / +beta1
Category: ~DO NOT USE (was: OCaml general)
Related to: #6610
Monitored by: @gasche "Julien Signoles" @hcarty @yakobowski
Bug description
The expression provided to compute the default value of optional arguments are pushed inside lambdas in the typedtree (cf Translcore.push_defaults). I assume this is done for performance purposes (efficient compilation of n-ary urried functions), but it can lead to surprising semantics (and I did not find it documented in the manual):
let f ?(x = print_endline "XXX"; 1) y = function z -> x + y + z;;
let g = f 2;;
g 1;;
g 2;;
will print XXX twice.
The default expressions are not pushed under "functions" with several branches:
let f ?(x = print_endline "XXX"; 1) = function Some y -> (function z -> x + y + z) | None -> (function z -> x + z);;
let g = f (Some 2);;
Here, "XXX" is printed directly (not each time g is called), contrary to:
let f ?(x = print_endline "XXX"; 1) = function Some y -> (function z -> x + y + z);;
let g = f (Some 2);;
Shouldn't we restrict the optimization to cases where the default expression is pure?
As a side note: Typeclass puts the "Default" mode on the generated let binding for default expressions on class arguments, but it is not recognized in a special way. I.e.:
class c ?(x = print_endline "XXX"; 1) y z = object method m = x + y + z end;;
let _ = new c 2
will print "XXX" immediately.