chapel-lang / chapel

a Productive Parallel Programming Language
https://chapel-lang.org
Other
1.78k stars 418 forks source link

[feature request] Attach "[...]" for the output of arrays with writeln() #16188

Open ty1027 opened 4 years ago

ty1027 commented 4 years ago

(Not an issue of "high priority" for me, but just stylistic(?) or readability things as compared to other languages...)

When printing an array to standard output (with no format given), the elements of arrays are printed like 1 2 3... rather than [1, 2, ...] (i.e., no square parentheses):

proc run()
{
  var A:[1..5] int = [1,2,3,4,5];
  var t = (A, A);
  writeln( A );     // 1 2 3 4 5
  writeln( t );      //  (1 2 3 4 5, 1 2 3 4 5)
}
run();

I think this output style is rather similar to the "list-directed" output in Fortran:

program main
    implicit none
    integer, allocatable :: A(:)
    A = [1,2,3,4,5]
    print *, A       !! 1 2 3 4 5
end

Here, I think the output will become easier to understand if [...] are attached to the array values (at least for 1-dim arrays, such that elements in one array are enclosed with [...]), particularly when arrays appear in a collection type.


Here are similar codes in other languages:

# Python
def run():
  A = [1,2,3,4,5]
  t = (A, A)
  print( A )   # [1, 2, 3, 4, 5]
  print( t )    # ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])
#
run()
# Julia
function run()
  A = [1,2,3,4,5]
  t = (A, A)
  println( A )    # [1, 2, 3, 4, 5]
  println( t )     # ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])
end
run()
// D
import std.stdio;
import std.typecons;

void main()
{
  int[] A = [1,2,3,4,5];
  auto t = Tuple!(int[], int[])(A, A);
  writeln( A );    // [1, 2, 3, 4, 5]
  writeln( t );    // Tuple!(int[], int[])([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])
}
# Nim
proc run() =
  var A = @[1,2,3,4,5]
  var t = (A, A)
  echo( A )    # @[1, 2, 3, 4, 5]
  echo( t )     # (@[1, 2, 3, 4, 5], @[1, 2, 3, 4, 5])
#
run()
// Rust
fn main()
{
  let a = vec![1,2,3,4,5];
  let t = (&a, &a);
  println!( "{:?}", a );   // [1, 2, 3, 4, 5]
  println!( "{:?}", t );   // ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])
}

As for N-dim arrays, nested parentheses ([ [...], [...] ]) or tabulated forms seem popular, although details vary...

bradcray commented 4 years ago

@ty1027: In designing Chapel's I/O, one of the ideas we kicked around a bit was the notion of having different choices for how output was formatted given that there's often no single right answer that works well for everyone. I can't recall whether we ever enabled some of the other options like this for arrays, though. @mppf, can you help my memory?

mppf commented 4 years ago

We do have the ability to select a "Chapel" format for arrays with writef:

proc run()
{ 
  var A:[1..5] int = [1,2,3,4,5];
  var t = (A, A);
  writef( "%ht\n", A );     // 1 2 3 4 5
  writef( "%ht\n", t );      //  (1 2 3 4 5, 1 2 3 4 5)
}
run();

Additionally that is possible with the I/O style mechanism but that is pretty esoteric and I'm not certain we will keep it, long term.

However I didn't see that as answering @ty1027's request - I interpreted

When printing an array to standard output (with no format given) ... Here, I think the output will become easier to understand if [...] are attached to the array values...

as a request for the default behavior to change.

bradcray commented 4 years ago

The I/O style mechanism is what I was thinking of (I'm thinking back on discussions of lossy vs. lossless formats for writing things out... e.g., should strings include quotes in order to preserve whitespace? How should an array of strings, some of which might contain the characters [ or , print out, etc.?

However I didn't see that as answering @ty1027's request - I interpreted

When printing an array to standard output (with no format given) ... Here, I think the output will become easier to understand if [...] are attached to the array values...

as a request for the default behavior to change.

I was trying to address this in saying:

there's often no single right answer that works well for everyone.

(which is why I liked the feature of being able to control such stylistic choices via channel controls or the like).

ty1027 commented 4 years ago

@mppf I did not know this format option ("%ht"), thanks very much!

And as suggested above, my request is to change the default behavior to %ht because that style seems widely used for the output style. Another good point is that it will make arrays in a record more visible when displayed on the standard output (when used w/o format), e.g.,

record Rec
{
    var n = 100;
    var A = [1,2,3,4,5];
    var B = [1,2,3];
    var x = 1.23;
}

proc run()
{ 
    var x: Rec;
    writeln( x );
    writef( "%ht\n", x );
}

run();
// which gives:
//   (n = 100, A = 1 2 3 4 5, B = 1 2 3, x = 1.23)
//   new Rec(n = 100, A = [1, 2, 3, 4, 5], B = [1, 2, 3], x = 1.230000e+00)

But I am afraid that, if the default format is changed, some existing analysis codes may become broken if they assume no [...] in the output (e.g., when parsing the output via scripting languages). So, this is not "high priority" things at all, but just my impression (that the output with [...] seems more popular and visible).

I think it may be useful if an example of "%ht" is given somewhere in tutorials, e.g., in an array part (also to illustrate the flexiblity of changing output formats).