View mode: basic / threaded / horizontal-split · Log in · Help
January 16, 2013
[Issue 9326] New: writeln to simply show pointed data
http://d.puremagic.com/issues/show_bug.cgi?id=9326

          Summary: writeln to simply show pointed data
          Product: D
          Version: D2
         Platform: All
       OS/Version: All
           Status: NEW
         Severity: enhancement
         Priority: P2
        Component: Phobos
       AssignedTo: nobody@puremagic.com
       ReportedBy: bearophile_hugs@eml.cc


--- Comment #0 from bearophile_hugs@eml.cc 2013-01-16 02:24:58 PST ---
A small demo program:


import std.stdio: writeln;
struct Foo {
   int x;
}
struct Node {
   Node* next;
}
void main() {
   Foo f = Foo(1);
   writeln("Simple struct: ", f);
   Foo* pf = new Foo(2);
   writeln("Struct from pointer: ", pf);
   Node* ptr = new Node(new Node(null));
   writeln("Singly linked list: ", ptr);
   Node* n1 = new Node(null);
   Node* n2 = new Node(n1);
   n1.next = n2;
   writeln("Circular singly linked list: ", n1);
}


Currently prints (dmd 2.062alpha):

Simple struct: Foo(1)
Struct from pointer: 1601F90
Singly linked list: 19C1F80
Circular singly linked list: 1601F60


For debugging, or just during the writing of code, I'd often like to see what's
pointed by those pointers.

So I suggest to enhance Phobos textual formatting a little, to produce
something simple like (on 64 bit pointers are longer):

Simple struct: Foo(1)
Struct from pointer: <1601F90*>Foo(2)
Singly linked list: <1601F80*>Node(<19C1F70*>Node(null))
Circular singly linked list: <1551F60*>Node(<1551F50*>Node(<1551F60*>...))


Notes:
- Numbers like 1551F50 are the pointer values in hex;
- The "*" helps remember that they are deferenced;
- The <> of <1551F50*> help better tell apart the pointer from the pointed
data.
- The ellipsis ... in Node(<1551F60*>...) means that this call to writeln has
already shown what this pointer points to.

- - - - - - - - - - - - - -

This change in textual formatting is not meant to influence the result of "%x",
just "%s":


import std.stdio: writefln;
struct Foo {
   int x;
}
void main() {
   Foo* pf = new Foo(100);
   writefln("%s", pf);
   writefln("%x", pf);
}


Currently prints:

1981F90
1981f90



After that improvement it should print something like:

<1581F90*>Foo(100)
1581f90

- - - - - - - - - - - - - -

To keep things simple it's better to not follow untyped pointers (void*):


import std.stdio: writefln;
struct Foo {
   int x;
}
void main() {
   Foo* pf = new Foo(100);
   void* ptr = cast(void*)pf;
   writefln("%s", pf);
}


It should print just:

1571F90

Or maybe something similar to:

<1581F90*>void

- - - - - - - - - - - - - -

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 16, 2013
[Issue 9326] writeln to simply show pointed data
http://d.puremagic.com/issues/show_bug.cgi?id=9326


Dmitry Olshansky <dmitry.olsh@gmail.com> changed:

          What    |Removed                     |Added
----------------------------------------------------------------------------
                CC|                            |dmitry.olsh@gmail.com


--- Comment #1 from Dmitry Olshansky <dmitry.olsh@gmail.com> 2013-01-16 02:53:08 PST ---
(In reply to comment #0)

I don't think that stuffing various debugging trickery into writeln is a good
idea.

What about a dedicated primitive that may (by default!) use more convenient
formating fot this purpose?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 16, 2013
[Issue 9326] writeln to simply show pointed data
http://d.puremagic.com/issues/show_bug.cgi?id=9326



--- Comment #2 from bearophile_hugs@eml.cc 2013-01-16 03:11:59 PST ---
(In reply to comment #1)

Thank you for your comment.

> I don't think that stuffing various debugging trickery into writeln is a good
> idea.

I keep hearing similar comments since few years ago I asked for a better
printing of associative arrays and arrays in D. But once you give D programmers
such better printing (thanks to Hara work), they seem happy and unwilling to go
back to a more limited printing.

It's not a trick, showing what a pointer points to is printing of a basic
built-in data structure of the language.

Probably I got spoiled by modern dynamic languages, that being often used on
the REPL, enjoy having good default printing.

If you think this enhancement request is not a good idea, you must explain why.
I have explained why it's a handy thing to have.

(The implementation of this feature requires the formatting function to keep a
set of already seen pointers. For simplicity I think a built-in associative
array of void* is enough).


> What about a dedicated primitive that may (by default!) use more convenient
> formating fot this purpose?

Once the improved format() is implemented in Phobos, what's the point of
artificially restricting the usefulness of writeln()?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 16, 2013
[Issue 9326] writeln to simply show pointed data
http://d.puremagic.com/issues/show_bug.cgi?id=9326



--- Comment #3 from bearophile_hugs@eml.cc 2013-01-16 04:48:06 PST ---
Beside dynamic arrays, associative arrays and enums, D writeln is able to print
lazy ranges, so writeln is already rather capable:


import std.stdio, std.range;
void main() {
   writeln(iota(6));
}


Shows:

[0, 1, 2, 3, 4, 5]

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 16, 2013
[Issue 9326] writeln to simply show pointed data
http://d.puremagic.com/issues/show_bug.cgi?id=9326



--- Comment #4 from Dmitry Olshansky <dmitry.olsh@gmail.com> 2013-01-16 04:57:33 PST ---
(In reply to comment #2)
> (In reply to comment #1)
> 
> Thank you for your comment.
> 
> > I don't think that stuffing various debugging trickery into writeln is a good
> > idea.
> 
> I keep hearing similar comments since few years ago I asked for a better
> printing of associative arrays and arrays in D. But once you give D programmers
> such better printing (thanks to Hara work), they seem happy and unwilling to go
> back to a more limited printing.

What Kenji did was a better printing for ranges in general that is far more
powerful (and better integrated) then arrays.

> 
> It's not a trick, showing what a pointer points to is printing of a basic
> built-in data structure of the language.
> 
> Probably I got spoiled by modern dynamic languages, that being often used on
> the REPL, enjoy having good default printing.
> 
> If you think this enhancement request is not a good idea, you must explain why.
> I have explained why it's a handy thing to have.
> 
> (The implementation of this feature requires the formatting function to keep a
> set of already seen pointers. For simplicity I think a built-in associative
> array of void* is enough).
> 

It's good that you answered it already: not everybody needs it yet it requires
more complex code to be pulled in for everybody. 

Dynamic languages doesn't ever consider cost-to-benefit ratio it seems.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 16, 2013
[Issue 9326] writeln to simply show pointed data
http://d.puremagic.com/issues/show_bug.cgi?id=9326



--- Comment #5 from Dmitry Olshansky <dmitry.olsh@gmail.com> 2013-01-16 05:11:45 PST ---
(In reply to comment #4)
> > If you think this enhancement request is not a good idea, you must explain why.
> > I have explained why it's a handy thing to have.
> > 
> > (The implementation of this feature requires the formatting function to keep a
> > set of already seen pointers. For simplicity I think a built-in associative
> > array of void* is enough).
> > 

BTW if writeln starts allocating GC memory like that we'll have a revolt among 
users. The special case of debugging output doesn't look good enough to
compromise the basic "no garabage involved" guarantee.

Plus debug prints inside of a finalizer risk killing a program with current GC.
This situation with GC should/might improve in the future though but it's just
another problem to be aware of.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 16, 2013
[Issue 9326] writeln to simply show pointed data
http://d.puremagic.com/issues/show_bug.cgi?id=9326



--- Comment #6 from bearophile_hugs@eml.cc 2013-01-16 09:47:44 PST ---
(In reply to comment #5)

> BTW if writeln starts allocating GC memory like that we'll have a revolt among
> users. The special case of debugging output doesn't look good enough to
> compromise the basic "no garabage involved" guarantee.
>
> Plus debug prints inside of a finalizer risk killing a program with current GC.
> This situation with GC should/might improve in the future though but it's just
> another problem to be aware of.

Thank you for the answer. I didn't know writeln has strictly zero allocations.

To detect clycles this enhancement needs some kind of set of untyped pointers.
Such pointers never get deferenced and they must not used by the GC to keep
data alive (so they are weak pointers). So such pointers are essentially of
type uintptr_t (unsigned integral type large enough to hold a pointer).

Such set of uintptr_t is allocated by the writeln, and it stops being useful
when writeln ends (so it's possible to deallocate it). So maybe if necessary
it's possible to allocate such memory from the C heap, and avoid that problem
with the finalizer.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 16, 2013
[Issue 9326] writeln to simply show pointed data
http://d.puremagic.com/issues/show_bug.cgi?id=9326



--- Comment #7 from bearophile_hugs@eml.cc 2013-01-16 09:54:23 PST ---
(In reply to comment #4)

> What Kenji did was a better printing for ranges in general that is far more
> powerful (and better integrated) then arrays.

Kenji (with help from others) has done many things on the writeln, like
improving string printing, improving array printing, significantly improving
associative array printing (maybe introducing xformat too). And I think he has
added the printing for lazy ranges. He has also improved or added the printing
of struct literals, improved the output in presence of const/immutable,
improved the function literals, and other important details.


> It's good that you answered it already: not everybody needs it yet it requires
> more complex code to be pulled in for everybody. 

That's mostly true for every improvement listed above. There is also
printf/puts.


> Dynamic languages doesn't ever consider cost-to-benefit ratio it seems.

considering how much common they are (and they are becoming) it seems a good
deal. (But they usually don't have chains of raw pointers).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Top | Discussion index | About this forum | D home