www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - stdio.h and std.stream

reply "Ben Hinkle" <bhinkle mathworks.com> writes:
I'm curious, how much D code is there that mixes FILE* from std.c.stdio and 
File objects from std.stream?
Do people mix them alot? Is it by accident or on purpose? For what purpose? 
May 26 2005
next sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <d74k3o$2gco$1 digitaldaemon.com>, Ben Hinkle says...
I'm curious, how much D code is there that mixes FILE* from std.c.stdio and 
File objects from std.stream?
Do people mix them alot? Is it by accident or on purpose? For what purpose? 

None here. But perhaps it would be worthwhile to rename D stdin and stdout for clarity anyway. din and dout follows the C++ convention, though I can't say I much like it. Any other suggestions? Sean
May 26 2005
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Sean Kelly wrote:

 None here.  But perhaps it would be worthwhile to rename D stdin and stdout for
 clarity anyway.  din and dout follows the C++ convention, though I can't say I
 much like it.  Any other suggestions?

I have my "douts" about those names, I must say. :-P --anders
May 26 2005
parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"Anders F Bj÷rklund" <afb algonet.se> wrote in message
news:d74svg$2ng2$2 digitaldaemon.com...
 Sean Kelly wrote:

 None here.  But perhaps it would be worthwhile to rename D stdin and
 stdout for
 clarity anyway.  din and dout follows the C++ convention, though I can't
 say I
 much like it.  Any other suggestions?

I have my "douts" about those names, I must say. :-P --anders

yeah, that is kindof clunky. But I don't think a rename is enough. There's something bigger that should be discussed - or at least I hope Walter will think about. My own worry is that D has two "standard" io mechanisms. Say someone is writing a book introducing D (hypothetical, I know!). The first program is presumably something like import std.stdio; int main(char[][] args) { writefln("hello world"); return 0; } or, if printf is still in object.d and the author prefer's C it will be int main() { printf("hello world\n"); return 0; } I hope, though, that the author is trying to teach the reader good habits and will use writefln instead. My question is what is next program that writes hello world to a file? I'm guessing it will be import std.stdio; int main(char[][] args) { FILE* f = fopen("out.txt","w"); fwritefln(f,"hello world"); fclose(f); return 0; } The alternative today would be import std.stream; int main(char[][] args) { File f = new File("out.txt",FileMode.OutNew); f.writefln("hello world"); f.close(); return 0; } The two versions have advantages and disadvantages - but the author has to choose one or the other. And if they choose to import different modules to direct io to a file as opposed to the console then that needs explanation. So if std.stdio talks about FILE* I'm tempted to say D's primary "stream" io is FILE* and uses writef and fwrite/fread (a nice symmetry there, actually). It's possible we could remove std.stream.stdout etc and add a class that wraps FILE* so that if a user really wanted a stream interface to stdio they could make one using something like new CFile(stdout). Basically streams would become a class interface to FILE* or wrapper around non-FILE* io. Another way of phrasing the issue is to put oneself in the shoes of a library writer who is writing a feature that takes a file input. How do they declare their function? Does it take a FILE*, File or mango file class or a callback like std.format or even something else? I think the D community would benefit from some clarity on what D's io story is (which also gets to clarity on phobos in general but that's a bigger question).
May 26 2005
next sibling parent "Kris" <fu bar.com> writes:
Mango.io takes care of all this, Ben <g>

All files, sockets, etc are all instances of Conduits. Once you have a
conduit instance, you can read/write it directly, or you can wrap it with a
Buffer. Buffers can be read/written directly, or they in turn can be wrapped
with a variety of readers & writers.

Mango.io provides pre-built Stdin, Stderr, and Stdout reader/writer
instances, which one can use in a variety of different ways:

#  Stdout << 10 << " green bottles";
#
#  Stdout (10) (" green bottles");
#
#  Stdout.print ("%d green bottles", 10);

Note that Stdout is nothing more than an instance of Writer ~ you can do the
above with any type of Conduit endpoint, an array within memory, or a
Memory-Mapped version of a file.

In addition, the classes representing files, paths, etc are fully cohesive ~
there's no overlap of functionality or confusion over what to use in any
given context (as you note that there is within Phobos). It's all very
simple.

Mango.io also supports the configuration of char/wchar/dchar encoders &
decoders, directly within the I/O layer itself. It also supports the full
range of native D types, plus the full range of native one-dimensional array
types, along with the ability to bind one's own classes directly to the I/O
system. In fact, the Mango version of printf supports all those native
arrays too. Reader instances know how to deal with arrays correctly, and
there are pluggable performance enhancements available to manage, or
sidestep, related memory allocation. Combined with class serialization, it's
a potent yet surprisingly simple package to use.

Mango has a bunch more besides:

- Wrappers around the unicode ICU project (with a very usable String module)
- A Log4D logging package, with hooks into Chainsaw plus a dynamic
application monitor/manager.
- Clustered caching and queuing
- High performance HTTP server, with Servlet engine
- HTTP client

Each of which use the mango.io package extensively.



"Ben Hinkle" <bhinkle mathworks.com>...

 yeah, that is kindof clunky. But I don't think a rename is enough. There's
 something bigger that should be discussed - or at least I hope Walter will
 think about. My own worry is that D has two "standard" io mechanisms. Say
 someone is writing a book introducing D (hypothetical, I know!). The first
 program is presumably something like
   import std.stdio;
   int main(char[][] args) {
     writefln("hello world");
     return 0;
   }
 or, if printf is still in object.d and the author prefer's C it will be
   int main() {
     printf("hello world\n");
     return 0;
   }
 I hope, though, that the author is trying to teach the reader good habits
 and will use writefln instead. My question is what is next program that
 writes hello world to a file? I'm guessing it will be
   import std.stdio;
   int main(char[][] args) {
     FILE* f = fopen("out.txt","w");
     fwritefln(f,"hello world");
     fclose(f);
     return 0;
   }
 The alternative today would be
   import std.stream;
   int main(char[][] args) {
     File f = new File("out.txt",FileMode.OutNew);
     f.writefln("hello world");
     f.close();
     return 0;
   }
 The two versions have advantages and disadvantages - but the author has to
 choose one or the other. And if they choose to import different modules to
 direct io to a file as opposed to the console then that needs explanation.
 So if std.stdio talks about FILE* I'm tempted to say D's primary "stream"

 is FILE* and uses writef and fwrite/fread (a nice symmetry there,

 It's possible we could remove std.stream.stdout etc and add a class that
 wraps FILE* so that if a user really wanted a stream interface to stdio

 could make one using something like new CFile(stdout). Basically streams
 would become a class interface to FILE* or wrapper around non-FILE* io.
 Another way of phrasing the issue is to put oneself in the shoes of a
 library writer who is writing a feature that takes a file input. How do

 declare their function? Does it take a FILE*, File or mango file class or

 callback like std.format or even something else? I think the D community
 would benefit from some clarity on what D's io story is (which also gets

 clarity on phobos in general but that's a bigger question).

May 26 2005
prev sibling parent reply Carlos Santander <csantander619 gmail.com> writes:
Ben Hinkle escribiˇ:
 Another way of phrasing the issue is to put oneself in the shoes of a 
 library writer who is writing a feature that takes a file input. How do they 
 declare their function? Does it take a FILE*, File or mango file class or a 
 callback like std.format or even something else? I think the D community 
 would benefit from some clarity on what D's io story is (which also gets to 
 clarity on phobos in general but that's a bigger question). 
 
 

I'm part of the camp that thinks that std.c.stdio is C and not D, so when I do things like that I use std.stream. Weird thing is that I prefer writef() over stdout.writef() ... Hehe... -- Carlos Santander Bernal
May 26 2005
next sibling parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Carlos Santander" <csantander619 gmail.com> wrote in message 
news:d75r8b$f4a$1 digitaldaemon.com...
 Ben Hinkle escribiˇ:
 Another way of phrasing the issue is to put oneself in the shoes of a 
 library writer who is writing a feature that takes a file input. How do 
 they declare their function? Does it take a FILE*, File or mango file 
 class or a callback like std.format or even something else? I think the D 
 community would benefit from some clarity on what D's io story is (which 
 also gets to clarity on phobos in general but that's a bigger question).

I'm part of the camp that thinks that std.c.stdio is C and not D, so when I do things like that I use std.stream. Weird thing is that I prefer writef() over stdout.writef() ... Hehe...

same here. Actually I typically use printf since it is in object.d so I don't have to import anything and it handles pointers better than writef (when I'm debugging and I have an object x and I want to print the address of x I can't use writef - very annoying).
May 26 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 26 May 2005 21:50:57 -0400, Ben Hinkle wrote:

[snip]
 ... Actually I typically use printf since it is in object.d so I 
 don't have to import anything and it handles pointers better than writef 
 (when I'm debugging and I have an object x and I want to print the address 
 of x I can't use writef - very annoying).

writefln("Address of object is %08X", &x); -- Derek Melbourne, Australia 27/05/2005 12:07:15 PM
May 26 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message 
news:1equswhmhxo0t$.lq37ul35nfcj$.dlg 40tude.net...
 On Thu, 26 May 2005 21:50:57 -0400, Ben Hinkle wrote:

 [snip]
 ... Actually I typically use printf since it is in object.d so I
 don't have to import anything and it handles pointers better than writef
 (when I'm debugging and I have an object x and I want to print the 
 address
 of x I can't use writef - very annoying).

writefln("Address of object is %08X", &x);

doesn't that print the address of the variable holding the reference to the object? I'm looking for the equivalent to printf("%p\n",x);
May 26 2005
parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 26 May 2005 23:13:25 -0400, Ben Hinkle wrote:

 "Derek Parnell" <derek psych.ward> wrote in message 
 news:1equswhmhxo0t$.lq37ul35nfcj$.dlg 40tude.net...
 On Thu, 26 May 2005 21:50:57 -0400, Ben Hinkle wrote:

 [snip]
 ... Actually I typically use printf since it is in object.d so I
 don't have to import anything and it handles pointers better than writef
 (when I'm debugging and I have an object x and I want to print the 
 address
 of x I can't use writef - very annoying).

writefln("Address of object is %08X", &x);

doesn't that print the address of the variable holding the reference to the object? I'm looking for the equivalent to printf("%p\n",x);

You're correct. I misunderstood your 'request'. By the way, what would you do with the address of the object anyway? This might work for you ... <code> import std.stdio; class Foo { int a;} class Bar { real a;} class Muc { char[200] a;} // Returns the address of an object. size_t ObjAddr( Object x ) { return cast(size_t) *(cast(size_t*)&x); } void main() { Bar qwe = new Bar; Muc rty = new Muc; Foo uio = new Foo; writefln("%X %X %X", &qwe, ObjAddr(qwe), &qwe.a); writefln("%X %X %X", &rty, ObjAddr(rty), &rty.a); writefln("%X %X %X", &uio, ObjAddr(uio), &uio.a); } </code> -- Derek Melbourne, Australia 27/05/2005 2:04:09 PM
May 26 2005
parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Derek Parnell" <derek psych.ward> wrote in message 
news:1v7b3qw0dppoz.iv4epes53a68.dlg 40tude.net...
 On Thu, 26 May 2005 23:13:25 -0400, Ben Hinkle wrote:

 "Derek Parnell" <derek psych.ward> wrote in message
 news:1equswhmhxo0t$.lq37ul35nfcj$.dlg 40tude.net...
 On Thu, 26 May 2005 21:50:57 -0400, Ben Hinkle wrote:

 [snip]
 ... Actually I typically use printf since it is in object.d so I
 don't have to import anything and it handles pointers better than 
 writef
 (when I'm debugging and I have an object x and I want to print the
 address
 of x I can't use writef - very annoying).

writefln("Address of object is %08X", &x);

doesn't that print the address of the variable holding the reference to the object? I'm looking for the equivalent to printf("%p\n",x);

You're correct. I misunderstood your 'request'. By the way, what would you do with the address of the object anyway?

without a debugger there's no other way to see what reference is stored in a variable. I'm curious how people debug code involving objects otherwise since I find myself quite often wondering just which variable refers to which object.
May 27 2005
prev sibling parent reply Chris Sauls <ibisbasenji gmail.com> writes:
Carlos Santander wrote:
 I'm part of the camp that thinks that std.c.stdio is C and not D, so 
 when I do things like that I use std.stream. Weird thing is that I 
 prefer writef() over stdout.writef() ... Hehe...

I admit to often being naughty and adding an "alias stdout.writef writef;" to the tops of my modules that use std.stream... I'm probably just making a confusion trap for anyone else who reads that code, but it saves me ty ping "stdout" a thousand times in debug-console-logging code. -- Chris Sauls
May 26 2005
parent reply "Kris" <fu bar.com> writes:
"Chris Sauls" <ibisbasenji gmail.com> wrote in message
news:d75vht$hkv$2 digitaldaemon.com...
 Carlos Santander wrote:
 I'm part of the camp that thinks that std.c.stdio is C and not D, so
 when I do things like that I use std.stream. Weird thing is that I
 prefer writef() over stdout.writef() ... Hehe...

I admit to often being naughty and adding an "alias stdout.writef writef;" to the tops of my modules that use std.stream... I'm probably just making a confusion trap for anyone else who reads that code, but it saves me ty ping "stdout" a thousand times in debug-console-logging code. -- Chris Sauls

I configure the editor to insert common "phrases" based upon characters typed thus far (like intellisense), using a version of Emacs. I imagine you could do something similar with other editors, such as binding some text to a function-key? Short names, combined with a lack of namespace isolation, often makes code quite a bit harder to maintain over time. But, just recently I've started to realize that the percentage of code with a lifespan of more than a semester has been dropping at an increasing rate. Might the whole "long-term maintenance" thing actually be a sinking ship?
May 26 2005
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Thu, 26 May 2005 19:25:15 -0700, Kris wrote:


[snip]

 Short names, combined with a lack of namespace isolation, often makes code
 quite a bit harder to maintain over time. But, just recently I've started to
 realize that the percentage of code with a lifespan of more than a semester
 has been dropping at an increasing rate. Might the whole "long-term
 maintenance" thing actually be a sinking ship?

No! Wait till you are being paid to write code and then explain your code to somebody else who has to maintain it. One can *never* write code that is too clear or over supported by good practices. -- Derek Melbourne, Australia 27/05/2005 12:44:07 PM
May 26 2005
parent Sean Kelly <sean f4.ca> writes:
In article <1qg5mxr25hl82$.1x1w1jaflnwy5.dlg 40tude.net>, Derek Parnell says...
Wait till you are being paid to write code and then explain your code to
somebody else who has to maintain it. One can *never* write code that is
too clear or over supported by good practices.

Some contractors working at an old job of mine admitted to me that they designed complexity into their code to assure continued business with the client (and long hours for even the simplest change). I had a look at a Monte Carlo app they wrote at one point and it was the most horrifying bit of code I've ever seen. Between things like this and the mistakes of inexperience, I wonder just how much code out there is actually less cost-effective to maintain than to rewrite from scratch. Sean
May 27 2005
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <d760ec$jll$1 digitaldaemon.com>, Kris says...
Short names, combined with a lack of namespace isolation, often makes code
quite a bit harder to maintain over time. But, just recently I've started to
realize that the percentage of code with a lifespan of more than a semester
has been dropping at an increasing rate. Might the whole "long-term
maintenance" thing actually be a sinking ship?

That would be an interesting thing to find out. It's always been the case that programs are used for far longer than the designers had ever planned, but it wasn't until recently that the platforms applications are built on began to change rapidly. Has the browser as a platform given rise to disposable code, or will companies continue to use systems until they are years (or decades) out of date? Sean
May 26 2005
parent reply "Kris" <fu bar.com> writes:
"Sean Kelly" <sean f4.ca> wrote in message
news:d76833$qrc$1 digitaldaemon.com...
 In article <d760ec$jll$1 digitaldaemon.com>, Kris says...
Short names, combined with a lack of namespace isolation, often makes


quite a bit harder to maintain over time. But, just recently I've started


realize that the percentage of code with a lifespan of more than a


has been dropping at an increasing rate. Might the whole "long-term
maintenance" thing actually be a sinking ship?

That would be an interesting thing to find out. It's always been the case

 programs are used for far longer than the designers had ever planned, but

 wasn't until recently that the platforms applications are built on began

 change rapidly.  Has the browser as a platform given rise to disposable

 will companies continue to use systems until they are years (or decades)

 date?

Yes; interesting indeed. For example, I know of one /giant/ electronics manufacturer (I imagine almost everyone owns something made by them) who hire developers on a project by project basis only. There are no in-house developers, therefore all internal knowledge of the code effectively dies when the product ships. My understanding is that it's more cost-effective overall for them to recreate than to maintain; but then the product itself has a limited lifespan anyway. Disposable code for a disposable society <g> Being the old-fart that I am, that concept almost blew my mind through my nostrils.
May 26 2005
parent zwang <nehzgnaw gmail.com> writes:
Kris wrote:
 "Sean Kelly" <sean f4.ca> wrote in message
 news:d76833$qrc$1 digitaldaemon.com...
 
In article <d760ec$jll$1 digitaldaemon.com>, Kris says...

Short names, combined with a lack of namespace isolation, often makes


code
quite a bit harder to maintain over time. But, just recently I've started


to
realize that the percentage of code with a lifespan of more than a


semester
has been dropping at an increasing rate. Might the whole "long-term
maintenance" thing actually be a sinking ship?

That would be an interesting thing to find out. It's always been the case

that
programs are used for far longer than the designers had ever planned, but

it
wasn't until recently that the platforms applications are built on began

to
change rapidly.  Has the browser as a platform given rise to disposable

code, or
will companies continue to use systems until they are years (or decades)

out of
date?

Yes; interesting indeed. For example, I know of one /giant/ electronics manufacturer (I imagine almost everyone owns something made by them) who hire developers on a project by project basis only. There are no in-house developers, therefore all internal knowledge of the code effectively dies when the product ships. My understanding is that it's more cost-effective overall for them to recreate than to maintain; but then the product itself has a limited lifespan anyway. Disposable code for a disposable society <g> Being the old-fart that I am, that concept almost blew my mind through my nostrils.

Sounds like Philips.
May 26 2005
prev sibling parent John Demme <me teqdruid.com> writes:
On Thu, 2005-05-26 at 19:25 -0700, Kris wrote:
 "Chris Sauls" <ibisbasenji gmail.com> wrote in message
 news:d75vht$hkv$2 digitaldaemon.com...
 Carlos Santander wrote:
 I'm part of the camp that thinks that std.c.stdio is C and not D, so
 when I do things like that I use std.stream. Weird thing is that I
 prefer writef() over stdout.writef() ... Hehe...

I admit to often being naughty and adding an "alias stdout.writef writef;" to the tops of my modules that use std.stream... I'm probably just making a confusion trap for anyone else who reads that code, but it saves me ty ping "stdout" a thousand times in debug-console-logging code. -- Chris Sauls

I configure the editor to insert common "phrases" based upon characters typed thus far (like intellisense), using a version of Emacs. I imagine you could do something similar with other editors, such as binding some text to a function-key? Short names, combined with a lack of namespace isolation, often makes code quite a bit harder to maintain over time. But, just recently I've started to realize that the percentage of code with a lifespan of more than a semester has been dropping at an increasing rate. Might the whole "long-term maintenance" thing actually be a sinking ship?

Perhaps, but the day you start believing that and drop your good coding habits, is the day your code will start lasting 10+ years! <g> John Demme
May 26 2005