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

Complex lists always wrap at 80 columns or less #7528

Closed
vicuna opened this Issue May 4, 2017 · 4 comments

Comments

Projects
None yet
2 participants
@vicuna
Copy link
Collaborator

vicuna commented May 4, 2017

Original bug ID: 7528
Reporter: mars0i
Assigned to: @Octachron
Status: resolved (set by @Octachron on 2018-12-04T16:07:02Z)
Resolution: fixed
Priority: normal
Severity: minor
Platform: ocaml
OS: OS X
OS Version: 10.11.6
Version: 4.06.0 +dev/beta1/beta2/rc1
Fixed in version: 4.08.0+dev/beta1/beta2
Category: misc

Bug description

This is an issue observed in the ocaml toplevel. It can be demonstrated in utop as well. (This is my first time using Mantis. I'm not sure whether I entered all of the information correctly.)

When the display margin in a toplevel is set to > 80 columns, lists with simple elements will display using a margin greater than 80, but lists containing lists or tuples will wrap at or near 80 columns even when set_margin_function is used to specify a larger margin. If a margin smaller than 80 is set with set_margin_function, both simple lists and those with more complex elements wrap at the chosen margin. When the margin is subsequently set to a larger value, the complex lists continue to wrap at the narrower margin.

Steps to reproduce

The following was run in the OCaml toplevel, version 4.04.0 on OS X 10.11.6. To see the effect in utop, replace "Format.pp_set_margin Format.std_formatter " with "UTop.set_margin_function (fun _ -> Some )"

# Format.pp_set_margin Format.std_formatter 120;;
- : unit = ()
# let l = Batteries.List.range 0 `To 100;;
val l : int list =
  [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19; 20; 21; 22; 23; 24; 25; 26; 27; 28; 29; 30;
   31; 32; 33; 34; 35; 36; 37; 38; 39; 40; 41; 42; 43; 44; 45; 46; 47; 48; 49; 50; 51; 52; 53; 54; 55; 56; 57; 58; 59;
   60; 61; 62; 63; 64; 65; 66; 67; 68; 69; 70; 71; 72; 73; 74; 75; 76; 77; 78; 79; 80; 81; 82; 83; 84; 85; 86; 87; 88;
   89; 90; 91; 92; 93; 94; 95; 96; 97; 98; 99; 100]
# let ll = Batteries.List.map (fun x -> [x]) l;;
val ll : int list list =
  [[0]; [1]; [2]; [3]; [4]; [5]; [6]; [7]; [8]; [9]; [10]; [11]; [12];
   [13]; [14]; [15]; [16]; [17]; [18]; [19]; [20]; [21]; [22]; [23];
   [24]; [25]; [26]; [27]; [28]; [29]; [30]; [31]; [32]; [33]; [34];
   [35]; [36]; [37]; [38]; [39]; [40]; [41]; [42]; [43]; [44]; [45];
   [46]; [47]; [48]; [49]; [50]; [51]; [52]; [53]; [54]; [55]; [56];
   [57]; [58]; [59]; [60]; [61]; [62]; [63]; [64]; [65]; [66]; [67];
   [68]; [69]; [70]; [71]; [72]; [73]; [74]; [75]; [76]; [77]; [78];
   [79]; [80]; [81]; [82]; [83]; [84]; [85]; [86]; [87]; [88]; [89];
   [90]; [91]; [92]; [93]; [94]; [95]; [96]; [97]; [98]; [99]; [100]]
# Format.pp_set_margin Format.std_formatter 40;;
- : unit = ()
# l;;
- : int list =
[0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11;
 12; 13; 14; 15; 16; 17; 18; 19; 20;
 21; 22; 23; 24; 25; 26; 27; 28; 29;
 30; 31; 32; 33; 34; 35; 36; 37; 38;
 39; 40; 41; 42; 43; 44; 45; 46; 47;
 48; 49; 50; 51; 52; 53; 54; 55; 56;
 57; 58; 59; 60; 61; 62; 63; 64; 65;
 66; 67; 68; 69; 70; 71; 72; 73; 74;
 75; 76; 77; 78; 79; 80; 81; 82; 83;
 84; 85; 86; 87; 88; 89; 90; 91; 92;
 93; 94; 95; 96; 97; 98; 99; 100]
# ll;;
- : int list list =
[[0]; [1]; [2]; [3];
 [4]; [5]; [6]; [7];
 [8]; [9]; [10]; [11];
 [12]; [13]; [14]; [15];
 [16]; [17]; [18]; [19];
 [20]; [21]; [22]; [23];
 [24]; [25]; [26]; [27];
 [28]; [29]; [30]; [31];
 [32]; [33]; [34]; [35];
 [36]; [37]; [38]; [39];
 [40]; [41]; [42]; [43];
 [44]; [45]; [46]; [47];
 [48]; [49]; [50]; [51];
 [52]; [53]; [54]; [55];
 [56]; [57]; [58]; [59];
 [60]; [61]; [62]; [63];
 [64]; [65]; [66]; [67];
 [68]; [69]; [70]; [71];
 [72]; [73]; [74]; [75];
 [76]; [77]; [78]; [79];
 [80]; [81]; [82]; [83];
 [84]; [85]; [86]; [87];
 [88]; [89]; [90]; [91];
 [92]; [93]; [94]; [95];
 [96]; [97]; [98]; [99];
 [100]]
# Format.pp_set_margin Format.std_formatter 120;;
- : unit = ()
# l;;
- : int list =
[0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19; 20; 21; 22; 23; 24; 25; 26; 27; 28; 29; 30; 31;
 32; 33; 34; 35; 36; 37; 38; 39; 40; 41; 42; 43; 44; 45; 46; 47; 48; 49; 50; 51; 52; 53; 54; 55; 56; 57; 58; 59; 60;
 61; 62; 63; 64; 65; 66; 67; 68; 69; 70; 71; 72; 73; 74; 75; 76; 77; 78; 79; 80; 81; 82; 83; 84; 85; 86; 87; 88; 89;
 90; 91; 92; 93; 94; 95; 96; 97; 98; 99; 100]
# ll;;
- : int list list =
[[0]; [1]; [2]; [3];
 [4]; [5]; [6]; [7];
 [8]; [9]; [10]; [11];
 [12]; [13]; [14]; [15];
 [16]; [17]; [18]; [19];
 [20]; [21]; [22]; [23];
 [24]; [25]; [26]; [27];
 [28]; [29]; [30]; [31];
 [32]; [33]; [34]; [35];
 [36]; [37]; [38]; [39];
 [40]; [41]; [42]; [43];
 [44]; [45]; [46]; [47];
 [48]; [49]; [50]; [51];
 [52]; [53]; [54]; [55];
 [56]; [57]; [58]; [59];
 [60]; [61]; [62]; [63];
 [64]; [65]; [66]; [67];
 [68]; [69]; [70]; [71];
 [72]; [73]; [74]; [75];
 [76]; [77]; [78]; [79];
 [80]; [81]; [82]; [83];
 [84]; [85]; [86]; [87];
 [88]; [89]; [90]; [91];
 [92]; [93]; [94]; [95];
 [96]; [97]; [98]; [99];
 [100]]

Additional information

I originally reported this as an issue in utop (ocaml-community/utop#208), but it was suggested there that it was a bug in the OCaml pretty printer.

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented May 4, 2017

Comment author: mars0i

My apologies--there's some unnecessary junk at the beginning of the example text. I don't see a way to edit the report, however. I'd suggest beginning reading the example after these lines:

Format.pp_set_margin Format.std_formatter 120;;

Format.pp_set_margin Format.std_formatter 120;;

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented May 5, 2017

Comment author: mars0i

I discovered that lists with large elements may be displayed at a width that is less than the specified margin but that is nevertheless greater than 80 columns. This is illustrated by the third list below.

# Format.pp_set_margin Format.std_formatter 120;;
- : unit = ()
# let l = Batteries.List.range 0 `To 100;;
val l : int list =
  [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19; 20; 21; 22; 23; 24; 25; 26; 27; 28; 29; 30;
   31; 32; 33; 34; 35; 36; 37; 38; 39; 40; 41; 42; 43; 44; 45; 46; 47; 48; 49; 50; 51; 52; 53; 54; 55; 56; 57; 58; 59;
   60; 61; 62; 63; 64; 65; 66; 67; 68; 69; 70; 71; 72; 73; 74; 75; 76; 77; 78; 79; 80; 81; 82; 83; 84; 85; 86; 87; 88;
   89; 90; 91; 92; 93; 94; 95; 96; 97; 98; 99; 100]
# let ll = Batteries.List.map (fun x -> [float x]) l;;
val ll : float list list =
  [[0.]; [1.]; [2.]; [3.]; [4.]; [5.]; [6.]; [7.]; [8.]; [9.]; [10.];
   [11.]; [12.]; [13.]; [14.]; [15.]; [16.]; [17.]; [18.]; [19.]; [20.];
   [21.]; [22.]; [23.]; [24.]; [25.]; [26.]; [27.]; [28.]; [29.]; [30.];
   [31.]; [32.]; [33.]; [34.]; [35.]; [36.]; [37.]; [38.]; [39.]; [40.];
   [41.]; [42.]; [43.]; [44.]; [45.]; [46.]; [47.]; [48.]; [49.]; [50.];
   [51.]; [52.]; [53.]; [54.]; [55.]; [56.]; [57.]; [58.]; [59.]; [60.];
   [61.]; [62.]; [63.]; [64.]; [65.]; [66.]; [67.]; [68.]; [69.]; [70.];
   [71.]; [72.]; [73.]; [74.]; [75.]; [76.]; [77.]; [78.]; [79.]; [80.];
   [81.]; [82.]; [83.]; [84.]; [85.]; [86.]; [87.]; [88.]; [89.]; [90.];
   [91.]; [92.]; [93.]; [94.]; [95.]; [96.]; [97.]; [98.]; [99.]; [100.]]
# let ll = Batteries.List.map (fun x -> [(float x)**0.5]) l;;
val ll : float list list =
  [[0.]; [1.]; [1.41421356237309515]; [1.73205080756887719]; [2.]; [2.23606797749979];
   [2.44948974278317788]; [2.64575131106459072]; [2.82842712474619029];
   [3.]; [3.16227766016837952]; [3.3166247903554]; [3.46410161513775439];
   [3.60555127546398912]; [3.74165738677394133]; [3.87298334620741702];
   [4.]; [4.12310562561766059]; [4.24264068711928477]; [4.35889894354067398];
   [4.47213595499958]; [4.58257569495584]; [4.69041575982343]; [4.79583152331271911];
   [4.89897948556635576]; [5.]; [5.09901951359278449]; [5.19615242270663202];
   [5.29150262212918143]; [5.38516480713450374]; [5.47722557505166119];
   [5.56776436283002152]; [5.65685424949238058]; [5.74456264653802862];
   [5.83095189484530074]; [5.91607978309961613]; [6.]; [6.08276253029821934];
   [6.16441400296897601]; [6.24499799839839831]; [6.32455532033675905];
   [6.40312423743284853]; [6.48074069840786]; [6.557438524302]; [6.6332495807108];
   [6.70820393249936942]; [6.78232998312526814]; [6.85565460040104391];
   [6.92820323027550877]; [7.]; [7.07106781186547551]; [7.14142842854285];
   [7.21110255092797825]; [7.28010988928051805]; [7.34846922834953453];
   [7.41619848709566298]; [7.48331477354788266]; [7.54983443527075];
   [7.61577310586390865]; [7.68114574786860782]; [7.74596669241483404];
   [7.81024967590665398]; [7.87400787401181113]; [7.93725393319377215];
   [8.]; [8.06225774829855]; [8.12403840463596]; [8.18535277187245];
   [8.24621125123532117]; [8.30662386291807486]; [8.36660026534075563];
   [8.42614977317635905]; [8.48528137423857]; [8.54400374531753]; [8.60232526704262668];
   [8.6602540378443873]; [8.71779788708134795]; [8.77496438739212259];
   [8.83176086632784774]; [8.88819441731558868]; [8.94427190999916];
   [9.]; [9.0553851381374173]; [9.1104335791443]; [9.16515138991168];
   [9.21954445729288707]; [9.27361849549570394]; [9.32737905308881565];
   [9.38083151964686]; [9.43398113205660316]; [9.48683298050513812];
   [9.53939201416945615]; [9.59166304662543823]; [9.64365076099295493];
   [9.69535971483265868]; [9.74679434480896312]; [9.79795897113271153];
   [9.84885780179610393]; [9.89949493661166535]; [9.9498743710662]; [10.]]
@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Jul 10, 2017

Comment author: @Octachron

The issue stems from the fact that Format.pp_set_margin is highly non-reversible and can silently decrease the pp_max_indent setting. However, this pp_max_indent value is not increased back when the margin is increased.

For instance, in the sequence,
Format.set_margin 78 (the original value for the margin);;
Format.set_margin 11;;
Format.set_margin 78;;

The value of pp_max_indent evolves as
68;;
5;;
5;;

Since pp_max_indent controls the left most start of boxes, this implies that
after such sequence of Format.set_margin, boxes will nearly always start at the left margin, leading to the observed behavior.

The issue can be fixed by calling Format.set_max_indent (margin - 10), but I am not sure if this is the optimal user api here.

@vicuna

This comment has been minimized.

Copy link
Collaborator Author

vicuna commented Dec 4, 2018

Comment author: @Octachron

Since the opening of this ticket, the coupling of margin and max_indent has been documented inside the Format module. Moreover, OCaml 4.08 comes with a new function Format.set_geometry that makes it possible to set both values simultaneously, which is probably the safest choice for most users. I am thus marking this issue as resolved.

@vicuna vicuna closed this Dec 4, 2018

@vicuna vicuna added the bug label Mar 20, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.