Skip to content

Pushing the evaluation of default expression for optional arguments is not specified #5975

@vicuna

Description

@vicuna

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions