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

Better (prettier) output for printing lists of records #547

Open
rmunn opened this Issue Mar 1, 2017 · 6 comments

Comments

Projects
None yet
5 participants
@rmunn

rmunn commented Mar 1, 2017

Better (prettier) output for printing lists of records

I propose we improve the output of printfn "%A" listOfRecords by preventing it from "stair-stepping".

Currently, if you run the following code:

type CityAndState = { City : string; State : string }
let cities = [{City="Seattle";State="WA"};{City="New York";State="NY"};{City="Chicago";State="IL"}]
printfn "%A" cities

The output will be:

[{City = "Seattle";
  State = "WA";}; {City = "New York";
                   State = "NY";}; {City = "Chicago";
                                    State = "IL";}]

What I'd like to see instead:

[{City = "Seattle";
  State = "WA";};
 {City = "New York"}
  State = "NY";};
 {City = "Chicago";
  State = "IL";}]

Or possibly omitting the semicolons that aren't necessary when things are lined up vertically (note that this example also omits the unnecessary semicolons in record rendering, which isn't strictly part of this proposal but would also make sense to do):

[{City = "Seattle"
  State = "WA"}
 {City = "New York"}
  State = "NY"}
 {City = "Chicago"
  State = "IL"}]

The specific proposal I'm making is to change the %A rendering logic for lists (and sequences and arrays) as follows:

  • If the items in the list render on one line (e.g., numbers or strings, whose rendered form does not contain a newline), then use the existing rendering logic, where items are separated by a semicolon and a space.
  • If the items in the list render on more than one line (their rendered form contains a newline), such as is the case with records, then line the items up vertically, with the start of each item in the same character position (so in the example, since the opening { of the first record was in column 2, each subsequent record is indented by 1 space so that each record's opening { will be in column 2).
  • Since it would probably be expensive to check the rendering of every item in the list, check only how the first item renders before making the decision about whether to separate items with semicolons or newlines-plus-indentation. Since lists must be homogenous, this will produce good results most of the time, and any time when it doesn't produce good results, it will look no worse than the current stair-stepping.
  • Optionally, if the list is rendering each item on a new line, the semicolons between items could still be present rather than being removed. I don't know the internals of how a list renders itself for the %A format specifier, so if it would be expensive or complicated to omit semicolons when a newline is inserted, then the semicolons could be kept. The main thrust of my proposal is to eliminate the stair-stepping; if there's a good reason to keep the semicolons when the stair-stepping is eliminated, then keep them.

This change would apply to all uses of the %A format specifier: printfn, sprintf, kprintf, etc.

Pros and Cons

The advantages of making this adjustment to F# are that lists (and seqs and arrays) would have a nicer rendering in FSI. I was inspired by seeing the FSI output in the lower right corner of the screen during this "Intro to F#" presentation: the stair-stepping looked ugly, and if I were an F# newbie, it would have distracted me from getting the rest of his point. Since he was demonstrating type providers (one of F#'s great strengths) at the time, that would have been a shame.

The disadvantages of making this adjustment to F# are that large lists might take even more vertical screen space at this rate, so a cutoff of (say) 100 lines might be needed instead of 100 items. Or maybe the cutoff could be dependent on whether the items are vertically or horizontally arranged: keep the cutoff at 100 items for lists whose items are arranged horizontally, but if the items are arranged vertically, drop the cutoff down to 20 or 30 items.

Extra information

Estimated cost (XS, S, M, L, XL, XXL): M? Maybe S, depending on what the current code looks like.

Related suggestions: None found

Affidavit (must be submitted)

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on Stack Overflow) and I have searched Stack Overflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.

Please tick all that apply:

  • This is not a breaking change to the F# language design
  • I would be willing to help implement and/or test this
  • I or my company would be willing to help crowdfund F# Software Foundation members to work on this
@smoothdeveloper

This comment has been minimized.

Show comment
Hide comment
@smoothdeveloper

smoothdeveloper Mar 1, 2017

@rmunn what would happen with nested records (or other)? Are those going to be pretty-printed with nice indentation we sometime see in say JSON?

smoothdeveloper commented Mar 1, 2017

@rmunn what would happen with nested records (or other)? Are those going to be pretty-printed with nice indentation we sometime see in say JSON?

@dsyme

This comment has been minimized.

Show comment
Hide comment
@dsyme

dsyme Mar 1, 2017

Collaborator

@rmunn I definitely approve of this - I think it's just a matter of adjusting the structured layout code in the F# compiler and/or core library (they share the same code)

To be honest we don't really even need to track this as a language suggestion since it's really a tooling thing, and a definite improvement, So please feel free to just go ahead and make the improvement if possible

Collaborator

dsyme commented Mar 1, 2017

@rmunn I definitely approve of this - I think it's just a matter of adjusting the structured layout code in the F# compiler and/or core library (they share the same code)

To be honest we don't really even need to track this as a language suggestion since it's really a tooling thing, and a definite improvement, So please feel free to just go ahead and make the improvement if possible

@rmunn

This comment has been minimized.

Show comment
Hide comment
@rmunn

rmunn Mar 1, 2017

Which repo would be the one to make this change in? https://github.com/fsharp/fsharp, or https://github.com/Microsoft/visualfsharp? I'm finding open-source coding time in very short supply at the moment, so I can't say "I'll take this" right now. But if nobody else gets to it before I find some more open-source coding time, I'm still not quite clear on which of those two repos is the one that open-source contributors should be forking and submitting PRs to.

rmunn commented Mar 1, 2017

Which repo would be the one to make this change in? https://github.com/fsharp/fsharp, or https://github.com/Microsoft/visualfsharp? I'm finding open-source coding time in very short supply at the moment, so I can't say "I'll take this" right now. But if nobody else gets to it before I find some more open-source coding time, I'm still not quite clear on which of those two repos is the one that open-source contributors should be forking and submitting PRs to.

@AviAvni

This comment has been minimized.

Show comment
Hide comment
@AviAvni

AviAvni Mar 1, 2017

@rmunn https://github.com/Microsoft/visualfsharp and you can look at my pr Microsoft/visualfsharp#1776
It touch in this code
if you want help ping me

AviAvni commented Mar 1, 2017

@rmunn https://github.com/Microsoft/visualfsharp and you can look at my pr Microsoft/visualfsharp#1776
It touch in this code
if you want help ping me

@saul

This comment has been minimized.

Show comment
Hide comment
@saul

saul Mar 8, 2017

To be honest we don't really even need to track this as a language suggestion since it's really a tooling thing, and a definite improvement, So please feel free to just go ahead and make the improvement if possible

@dsyme I was just about to raise a language suggestion for pretty printing of strings with %A - in that nothing is escaped (back slashes, new lines, control characters, etc). Am I okay to just make this change in a PR as opposed to a language suggestion?

saul commented Mar 8, 2017

To be honest we don't really even need to track this as a language suggestion since it's really a tooling thing, and a definite improvement, So please feel free to just go ahead and make the improvement if possible

@dsyme I was just about to raise a language suggestion for pretty printing of strings with %A - in that nothing is escaped (back slashes, new lines, control characters, etc). Am I okay to just make this change in a PR as opposed to a language suggestion?

@dsyme

This comment has been minimized.

Show comment
Hide comment
@dsyme

dsyme Mar 9, 2017

Collaborator

@dsyme I was just about to raise a language suggestion for pretty printing of strings with %A - in that nothing is escaped (back slashes, new lines, control characters, etc). Am I okay to just make this change in a PR as opposed to a language suggestion?

That's a much harder change since it would almost certainly break code. I think we would need to add an option to %A, e.g. %!A or something

Collaborator

dsyme commented Mar 9, 2017

@dsyme I was just about to raise a language suggestion for pretty printing of strings with %A - in that nothing is escaped (back slashes, new lines, control characters, etc). Am I okay to just make this change in a PR as opposed to a language suggestion?

That's a much harder change since it would almost certainly break code. I think we would need to add an option to %A, e.g. %!A or something

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