dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.95k stars 4.65k forks source link

[API Proposal]: `ToString(...)` overloads for `Array`, `Array<T>`, `Memory<T>`, `Span<T>` for pretty printing underlying contents/elements and maybe a new general `System.Print(...)`/`System.PrettyPrint(...)` #106531

Open vadimkantorov opened 4 weeks ago

vadimkantorov commented 4 weeks ago

Background and motivation

For code working with arrays/tensors/interop, this is extremely useful to have such a shortcut in the standard library (especially for primitive number type elements like Int32[] or Memory<Int32>).

In Python / NumPy, str impl for lists prints the full contents and the default impl for NumPy arrays - prints some leading and trailing elements.

I propose to add an overload for ToString method accepting some format string (and then we could specify if we want all elements or some leading/trailing only). Same for char arrays.

Essentially, getting C# closer to Python's print(arr1, arr2) would be great. Currently a novice has to search online of how to print an array which adds friction.

It could also be nice to introduce a new method System.PrettyPrint(...) or System.Print(...) which would by default recursively print structs/records/classes/arrays in a more pretty way (e.g. for classes/structs/records - listing all fields and their values) - and it could also be closer to Python's print(...) which can accept multiple values without passing a format string as the first arg.

API Proposal

N/A

API Usage

N/A

Alternative Designs

No response

Risks

No response

julealgon commented 4 weeks ago

The second part of this proposal is odd to me..... I don't think the framework should be concerned with that. Can't you just Json-serialize the model?

vadimkantorov commented 4 weeks ago

Of course, one can json-serialize or do string.Join("\n", myarr) or write some custom code, or accomplish the task in another way. My point is that for people working a lot with arrays (and coming from Go/Pyhon/scientific/machine learning background or simply novices/students), it might be beneficial to have such shortcut in the standard library, so that printing contents of an array does not require googling / or loading up a JSON library (although maybe the code from the JSON library could be reused for implementing this feature in the standard library if adding this shortcut is deemed worthy).

(And as my proposal is about adding a shortcut, of course its need is subjective, understanding that)

dotnet-policy-service[bot] commented 4 weeks ago

Tagging subscribers to this area: @dotnet/area-system-runtime See info in area-owners.md if you want to be subscribed.

Clockwork-Muse commented 4 weeks ago

... part of the problem here is ToString() often ends up being a shortcut for two different behaviors:

(this is explicitly spelled out with Rust, which might be nice here too...)

Generally, getting a string like this is mostly useful for debug output (for cases when you can't attach to a debugger) - for everything else, getting "correct" serialized output (or outputting to whatever stream directly) is better. But I generally feel that debug output should be more targeted....

vadimkantorov commented 4 weeks ago

I was thinking of introducing an extra overload like Array.ToString(string format). Then at least we can do System.Console.WriteLine("{0:pretty}", array). This way the existing .ToString() behavior would be unchanged. And for recursive application - maybe a separate, new function would need to be introduced (like System.Print(...)) which would auto-pass in this format modifier for some known types and maybe do some custom logic for classes if they have only a default not very pretty ToString)

In theory, there may exist several such modifiers (e.g. pretty and debug), and there could be several high-level functions e.g. System.Print(...)/System.PrettyPrint(...) and System.DebugPrint(...) - haha, forgot if C# now can support static methods in namespaces or if they would still have to be put in some class... I had a long pause in C# usage...)

In any case, IMO current array print output coming as System.Single[] is not very useful in debugging numerical code...

colejohnson66 commented 4 weeks ago

If you're debugging, why not just use the debugger's collection viewer?

vadimkantorov commented 4 weeks ago

If you're debugging, why not just use the debugger's collection viewer?

I'm mainly using command-line and debug-printing.

Similar pretty/debug printing would be extremely useful if C#/.NET starts shipping an official REPL tool.

filipnavara commented 3 weeks ago

Similar pretty/debug printing would be extremely useful if C#/.NET starts shipping an official REPL tool.

Side note: There's already https://github.com/dotnet/interactive and https://github.com/jonsequitur/dotnet-repl built on top.

vadimkantorov commented 3 weeks ago

There's already

Yeah, in my personal view it's time for a C# REPL and a scripting tool (to be able to run a C# file without first calling the compiler - maybe like dotnet myscript.cs or dotnet run myscript.cs - similar to Python and Go) be officially shipped with dotnet tool by default - for education and quick/laconic scripting - like it is with F#. Especially if the underlying foundation is already built and officially supported for this notebook endeavor.