Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0007715OCamlstandard librarypublic2018-01-23 17:012018-06-11 17:31
Reportergmelquiond 
Assigned To 
PrioritynormalSeverityminorReproducibilityalways
StatusconfirmedResolutionopen 
PlatformOSOS Version
Product Version4.06.0 
Target VersionFixed in Version 
Summary0007715: Format: strange behavior of basic compacting boxes
DescriptionAbout basic compacting boxes, the documentation of Format says:

  "a break hint also splits the line if the splitting ``moves to the left'' (i.e. the new line gets an indentation smaller than the one of the current line)."

and the Bonichon-Weis paper agrees with it:

  "if splitting the line reduces the current indentation, a break hint splits the line, even if there is still enough room left on the current line."

So, when executing

  Format.printf "@[<2>a@ @[<v 2>(b@,c@,d)@]@ e@]@.";;

I expect the following output

  a.(b
  ....c
  ....d)
  ..e

Indeed, even if there is still some space on the line starting with d, since the current indentation is 4 while the indentation of e is 2, the box containing e should be put on a new line. But in practice, the output is the same as for a hov box:

  a.(b
  ....c
  ....d).e

Even stranger, since the width of the broken output above is 8, reducing the margin to 9 should not change the output. Yet it actually fixes the bug.

More generally, as long as there are sufficiently many boxes, the output eventually becomes as documented. For example, with the default margin of 78, the following code starts behaving correctly once 71 iterations are reached.

  Format.printf "@[<2>a@ @[<v 2>(";
  for i = 1 to 71 do Format.printf "b@," done;
  Format.printf "b)@]@ e@]@.";;
TagsNo tags attached.
Attached Files

- Relationships

-  Notes
(0018859)
octachron (developer)
2018-01-29 23:56

The documentated behavior and the implemented behavior are indeed at odd.

This phenomenon is maybe easier to see by setting the margin to 20, and extending your examples by defining two new functions

let f = Format.printf "@[<%s 2>a@ @[<v 2>(b@,c@,d)@]@ e@]@.";;
let g = Format.printf "@[<%s 2>a@ @[<v 2>(b@,c@,d)@]@ e@ f@ g@ h@ i@ j@ k@ @]@.";;

As expected, the output of 'g ""' and 'g "hov"' differ

g "" prints:

a (b
    c
    d)
  e f g h i j k

and g "hov" prints
a (b
    c
    d) e f g h i j
  k

However, as you constated and contrarily to the documented behavior, 'f ""' and 'f "hov"' gives the same output.

The critical difference between "f" and "g" is that the content of the box fits in one line for the function "f".
Internally, in this situation (see format.ml, l322), the structural box is replaced by a "fits" box (an internal type of box); which suppresses the structural behavior of the structural box.
And indeed, setting the margin to 9 in your example makes it fall in the not-fit category.

In other words, the implemented behavior is

*If* a structural box does not fit fully on a simple line, a break hint also splits the line if the splitting ``moves to the left''.

Either the documentation or implementation should be updated to be synchronized with each other.

- Issue History
Date Modified Username Field Change
2018-01-23 17:01 gmelquiond New Issue
2018-01-29 23:56 octachron Note Added: 0018859
2018-01-29 23:56 octachron Status new => confirmed
2018-06-11 17:31 herbelin Note Added: 0019180
2018-06-11 17:48 herbelin Note Deleted: 0019180


Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker