D - formatted output trial balloon
- "Walter" <walter digitalmars.com> Nov 05 2003
- "Walter" <walter digitalmars.com> Nov 05 2003
- Kazuhiro Inaba <Kazuhiro_member pathlink.com> Nov 06 2003
- "Walter" <walter digitalmars.com> Nov 06 2003
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Nov 06 2003
- "Walter" <walter digitalmars.com> Nov 06 2003
- "Jan-Eric Duden" <jeduden whisset.com> Nov 07 2003
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Nov 07 2003
- "Walter" <walter digitalmars.com> Nov 08 2003
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Nov 10 2003
- "Charles Sanders" <sanders-consulting comcast.net> Nov 05 2003
- "Ben Hinkle" <bhinkle4 juno.com> Nov 05 2003
- J Anderson <REMOVEanderson badmama.com.au> Nov 05 2003
- "Sean L. Palmer" <palmer.sean verizon.net> Nov 05 2003
- "Charles Sanders" <sanders-consulting comcast.net> Nov 05 2003
- Andy Friesen <andy ikagames.com> Nov 05 2003
- "Charles Sanders" <sanders-consulting comcast.net> Nov 06 2003
- Andy Friesen <andy ikagames.com> Nov 06 2003
- J Anderson <REMOVEanderson badmama.com.au> Nov 05 2003
- Roberto Mariottini <Roberto_member pathlink.com> Nov 05 2003
- "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> Nov 06 2003
- "Sean L. Palmer" <palmer.sean verizon.net> Nov 09 2003
- "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> Nov 09 2003
- Dario <Dario_member pathlink.com> Nov 06 2003
- Dario <Dario_member pathlink.com> Nov 06 2003
- "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> Nov 06 2003
- Dario <Dario_member pathlink.com> Nov 06 2003
- Jonathan Andrew <Jonathan_member pathlink.com> Nov 05 2003
- "Walter" <walter digitalmars.com> Nov 05 2003
- Helmut Leitner <helmut.leitner wikiservice.at> Nov 05 2003
- "Sean L. Palmer" <palmer.sean verizon.net> Nov 06 2003
- "Walter" <walter digitalmars.com> Nov 08 2003
- "Walter" <walter digitalmars.com> Nov 08 2003
- "Sean L. Palmer" <palmer.sean verizon.net> Nov 09 2003
- "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> Nov 05 2003
- "Walter" <walter digitalmars.com> Nov 08 2003
- Andy Friesen <andy ikagames.com> Nov 05 2003
- J Anderson <REMOVEanderson badmama.com.au> Nov 05 2003
- "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> Nov 05 2003
- Andy Friesen <andy ikagames.com> Nov 06 2003
- Hauke Duden <H.NS.Duden gmx.net> Nov 06 2003
- "Sean L. Palmer" <palmer.sean verizon.net> Nov 06 2003
- "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> Nov 06 2003
- "Sean L. Palmer" <palmer.sean verizon.net> Nov 09 2003
- "Sean L. Palmer" <palmer.sean verizon.net> Nov 06 2003
- "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> Nov 06 2003
- Ilya Minkov <midiclub tiscali.de> Nov 07 2003
- "Jeandrι du Toit" <morphiax hotmail.com> Nov 08 2003
- Roberto Mariottini <Roberto_member pathlink.com> Nov 05 2003
- Hauke Duden <H.NS.Duden gmx.net> Nov 06 2003
- Roberto Mariottini <Roberto_member pathlink.com> Nov 06 2003
- "Jan-Eric Duden" <jeduden whisset.com> Nov 06 2003
- Ilya Minkov <midiclub tiscali.de> Nov 06 2003
- "Walter" <walter digitalmars.com> Feb 20 2004
- Vathix <vathix dprogramming.com> Feb 21 2004
- "Ben Hinkle" <bhinkle4 juno.com> Feb 21 2004
- Roberto Mariottini <Roberto_member pathlink.com> Nov 07 2003
- "Ben Hinkle" <bhinkle4 juno.com> Nov 06 2003
- "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> Nov 06 2003
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Nov 06 2003
- "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> Nov 06 2003
- Russ Lewis <spamhole-2001-07-16 deming-os.org> Nov 06 2003
- Ilya Minkov <midiclub tiscali.de> Nov 07 2003
- Hauke Duden <H.NS.Duden gmx.net> Nov 07 2003
- "Ben Hinkle" <bhinkle4 juno.com> Nov 06 2003
- "Sean L. Palmer" <palmer.sean verizon.net> Nov 09 2003
- Patrick Down <Patrick_member pathlink.com> Nov 06 2003
- "Sean L. Palmer" <palmer.sean verizon.net> Nov 09 2003
- "Carlos Santander B." <carlos8294 msn.com> Nov 06 2003
- Matthias Becker <Matthias_member pathlink.com> Nov 16 2003
- Jan Knepper <jan smartsoft.us> Nov 16 2003
Since with () overloading class objects can now look like functions, I've
been toying with the idea of using this for formatted I/O. Here's a trial
mockup of what it might look like:
-----------------------------------------------
import std.string;
import std.c.stdio;
import std.c.stdlib;
class Stdout
{
Stdout opCall(int i)
{
printf("%d", i);
return this;
}
Stdout opCall(char[] format, ...)
{
va_list ap;
ap = cast(va_list)&format;
ap += format.size;
vprintf(format, ap);
return this;
}
Stdout nl()
{
printf("\n");
return this;
}
}
void main()
{ Stdout stdout = new Stdout();
stdout("hello")(" world")(47).nl()("bar")("%06i\n", 62);
}
-------------------------------------------
(Note that it retains the power of printf!) The issue here is how the syntax
stdout("foo")("bar") looks. In C++ it would look like stdout<<"foo"<<"bar"
which I don't find appealing.
Nov 05 2003
Andy Friesen also had very close to this idea earlier. -Walter D/17402
Nov 05 2003
Andy Friesen also had very close to this idea earlier. -Walter D/17402
Or, C++ has type-safe 'format' library http://boost.org/libs/format/doc/format.html which cout << format("%|04| *%|=7|*\n") % 100 % "foo"; prints "0100 * foo *" and linefeed. operator % is used here. (maybe % of "%d" or "%s"... is the origin) But i prefer Andy's operator~ approach. Since ~ already has the meaning "concatination", i think it's quite natural.
Nov 06 2003
"Kazuhiro Inaba" <Kazuhiro_member pathlink.com> wrote in message news:bodpsg$n5e$1 digitaldaemon.com...Andy Friesen also had very close to this idea earlier. -Walter D/17402
Or, C++ has type-safe 'format' library http://boost.org/libs/format/doc/format.html which cout << format("%|04| *%|=7|*\n") % 100 % "foo"; prints "0100 * foo *" and linefeed. operator % is used here. (maybe % of "%d" or "%s"... is the origin) But i prefer Andy's operator~ approach. Since ~ already has the meaning "concatination", i think it's quite
Thanks for the boost link. The ~ certainly does look better. One of my problems with the format() function, though, is it creates and returns a string, which then gets output. This results in double-buffering, something I want to avoid (for efficiency reasons).
Nov 06 2003
What about this syntax:
stdout ~ "asdf" ~ ("%d", foo);
Then, the class would have multiple overloaded overloadings of the ~
operator.
Walter wrote:
"Kazuhiro Inaba" <Kazuhiro_member pathlink.com> wrote in message
news:bodpsg$n5e$1 digitaldaemon.com...
Andy Friesen also had very close to this idea earlier. -Walter
D/17402
Or, C++ has type-safe 'format' library
http://boost.org/libs/format/doc/format.html
which
cout << format("%|04| *%|=7|*\n") % 100 % "foo";
prints "0100 * foo *" and linefeed.
operator % is used here. (maybe % of "%d" or "%s"... is the origin)
But i prefer Andy's operator~ approach.
Since ~ already has the meaning "concatination", i think it's quite
natural.
Thanks for the boost link. The ~ certainly does look better. One of my
problems with the format() function, though, is it creates and returns a
string, which then gets output. This results in double-buffering, something
I want to avoid (for efficiency reasons).
Nov 06 2003
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:boecta$1kbb$1 digitaldaemon.com...What about this syntax: stdout ~ "asdf" ~ ("%d", foo); Then, the class would have multiple overloaded overloadings of the ~ operator.
Unfortunately, the way overloading works, I don't see how I could make () be a parameter list rather than a parenthesized expression.
Nov 06 2003
tuples would help here :) -- Jan-Eric Duden "Walter" <walter digitalmars.com> wrote in message news:boep4t$26nb$1 digitaldaemon.com..."Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:boecta$1kbb$1 digitaldaemon.com...What about this syntax: stdout ~ "asdf" ~ ("%d", foo); Then, the class would have multiple overloaded overloadings of the ~ operator.
Unfortunately, the way overloading works, I don't see how I could make ()
a parameter list rather than a parenthesized expression.
Nov 07 2003
Can you expand on this? Is this an issue particular to your compiler implementation, or something else? Walter wrote:"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:boecta$1kbb$1 digitaldaemon.com...What about this syntax: stdout ~ "asdf" ~ ("%d", foo); Then, the class would have multiple overloaded overloadings of the ~ operator.
Unfortunately, the way overloading works, I don't see how I could make () be a parameter list rather than a parenthesized expression.
Nov 07 2003
In general, a~b is overloaded by looking at the types of a and the types of b. The type of a here is Stdout. The type of b, however, is the type of foo. That isn't going to use the overload of (). "Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:bogq3g$21fv$1 digitaldaemon.com...Can you expand on this? Is this an issue particular to your compiler implementation, or something else? Walter wrote:"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:boecta$1kbb$1 digitaldaemon.com...What about this syntax: stdout ~ "asdf" ~ ("%d", foo); Then, the class would have multiple overloaded overloadings of the ~ operator.
Unfortunately, the way overloading works, I don't see how I could make
a parameter list rather than a parenthesized expression.
Nov 08 2003
I'm sorry, maybe I wasn't clear in what I was suggesting. I was
suggesting that the following expression:
stdout ~ ("%d", foo);
would call the following member function:
class Stdout {
Stdout cat(char[], int);
}
whereas simple uses (without parens) would get mapped to single-argument
versions of cat(). So this line:
stdout ~ "asdf" ~ ("%d", foo);
would be exactly equivalent to
stdout.cat("asdf").cat("%d", foo);
Russ
Walter wrote:
In general, a~b is overloaded by looking at the types of a and the types of
b. The type of a here is Stdout. The type of b, however, is the type of foo.
That isn't going to use the overload of ().
What about this syntax:
stdout ~ "asdf" ~ ("%d", foo);
Nov 10 2003
I like it! Im not a fan of the .nl() though it looks inconsistent, not sure how else to handle it though. C "Walter" <walter digitalmars.com> wrote in message news:boc9me$1g2b$1 digitaldaemon.com...Since with () overloading class objects can now look like functions, I've been toying with the idea of using this for formatted I/O. Here's a trial mockup of what it might look like: ----------------------------------------------- import std.string; import std.c.stdio; import std.c.stdlib; class Stdout { Stdout opCall(int i) { printf("%d", i); return this; } Stdout opCall(char[] format, ...) { va_list ap; ap = cast(va_list)&format; ap += format.size; vprintf(format, ap); return this; } Stdout nl() { printf("\n"); return this; } } void main() { Stdout stdout = new Stdout(); stdout("hello")(" world")(47).nl()("bar")("%06i\n", 62); } ------------------------------------------- (Note that it retains the power of printf!) The issue here is how the
stdout("foo")("bar") looks. In C++ it would look like stdout<<"foo"<<"bar" which I don't find appealing.
Nov 05 2003
Note .nl() is the same as ("\n") if that's any better.
-Ben
"Charles Sanders" <sanders-consulting comcast.net> wrote in message
news:bocf1q$1o62$1 digitaldaemon.com...
I like it! Im not a fan of the .nl() though it looks inconsistent, not
how else to handle it though.
C
"Walter" <walter digitalmars.com> wrote in message
news:boc9me$1g2b$1 digitaldaemon.com...
Since with () overloading class objects can now look like functions,
been toying with the idea of using this for formatted I/O. Here's a
mockup of what it might look like:
-----------------------------------------------
import std.string;
import std.c.stdio;
import std.c.stdlib;
class Stdout
{
Stdout opCall(int i)
{
printf("%d", i);
return this;
}
Stdout opCall(char[] format, ...)
{
va_list ap;
ap = cast(va_list)&format;
ap += format.size;
vprintf(format, ap);
return this;
}
Stdout nl()
{
printf("\n");
return this;
}
}
void main()
{ Stdout stdout = new Stdout();
stdout("hello")(" world")(47).nl()("bar")("%06i\n", 62);
}
-------------------------------------------
(Note that it retains the power of printf!) The issue here is how the
stdout("foo")("bar") looks. In C++ it would look like
which I don't find appealing.
Nov 05 2003
Charles Sanders wrote:I like it! Im not a fan of the .nl() though it looks inconsistent, not sure how else to handle it though. C
stdout("hello")(" world")(47)(endl)("bar")("%06i\n", 62);
Nov 05 2003
"J Anderson" <REMOVEanderson badmama.com.au> wrote in message news:bocj2a$1tns$2 digitaldaemon.com...Charles Sanders wrote:I like it! Im not a fan of the .nl() though it looks inconsistent, not
how else to handle it though.
Instead of nl you could have a constant, ie endl
Yah.stdout("hello")(" world")(47)(endl)("bar")("%06i\n", 62);
Why on earth would you go to all the trouble to replace printf, and end up supporting the same bad technique anyway in all its untype-safe glory? That last bit should be some kind of integer formatting function or object. Sean
Nov 05 2003
But what would endl be defined as, an arbitrary number ? How would it know i didnt actually want to output that specific number ? C "J Anderson" <REMOVEanderson badmama.com.au> wrote in message news:bocj2a$1tns$2 digitaldaemon.com...Charles Sanders wrote:I like it! Im not a fan of the .nl() though it looks inconsistent, not
how else to handle it though. C
stdout("hello")(" world")(47)(endl)("bar")("%06i\n", 62);
Nov 05 2003
Charles Sanders wrote:But what would endl be defined as, an arbitrary number ? How would it know i didnt actually want to output that specific number ? C
A typedeffed value. Or some sort of unique mutator object. -- andy
Nov 05 2003
Whats a mutator object ? C "Andy Friesen" <andy ikagames.com> wrote in message news:bocnr5$25gn$2 digitaldaemon.com...Charles Sanders wrote:But what would endl be defined as, an arbitrary number ? How would it
i didnt actually want to output that specific number ? C
A typedeffed value. Or some sort of unique mutator object. -- andy
Nov 06 2003
Charles Sanders wrote:Whats a mutator object ? C
err.... I think C++ calls them maniuplators. Interface StreamManipulator { void manipulate(Stream s); } class Stream { ... Stream opCall(StreamManipulator manipulator) { manipulator.manipulate(this); return this; } } Basically, it's a polymorphic way to allow an object to manipulate how the stream does things. Manpulators can be used to change how the stream formats certain types of values. So, you could do something like stdout("X is equal to ")(floatFormat(8,3))(x); Where floatFormat returns a manipulator that tells stdout how to format x. (assuming x is a float) of course, stdout could simply have an overload for opCall that accepts three arguments instead of one. opCall(float f, int space, int precision) Mutators are probably still a good idea, though, as creating them doesn't require changes to the source of the stream class. -- andy
Nov 06 2003
Charles Sanders wrote:But what would endl be defined as, an arbitrary number ? How would it know i didnt actually want to output that specific number ? C "J Anderson" <REMOVEanderson badmama.com.au> wrote in message news:bocj2a$1tns$2 digitaldaemon.com...Charles Sanders wrote:I like it! Im not a fan of the .nl() though it looks inconsistent, not
how else to handle it though. C
stdout("hello")(" world")(47)(endl)("bar")("%06i\n", 62);
or function (endl()). -Anderson
Nov 05 2003
In article <bocoep$26eh$2 digitaldaemon.com>, J Anderson says...Charles Sanders wrote:But what would endl be defined as, an arbitrary number ? How would it know i didnt actually want to output that specific number ? [...]
I'd be defined as a constant char or constant char[] or constant char*, or function (endl()).
I suggest to create a special class Stdout.NLClass, define endl as a const Stdout.NLClass object, and define an opCall with a Stdout.NLClass parameter that does the job. Ciao
Nov 05 2003
I'm sorry, but I think the introduction of global variables purely for syntactic sugaring is a slippery slope that none of us will like hitting the bottom of. In general, if you need global variables, your design is flawed. "Roberto Mariottini" <Roberto_member pathlink.com> wrote in message news:bocv12$2g8q$1 digitaldaemon.com...In article <bocoep$26eh$2 digitaldaemon.com>, J Anderson says...Charles Sanders wrote:But what would endl be defined as, an arbitrary number ? How would it
i didnt actually want to output that specific number ? [...]
I'd be defined as a constant char or constant char[] or constant char*, or function (endl()).
I suggest to create a special class Stdout.NLClass, define endl as a const Stdout.NLClass object, and define an opCall with a Stdout.NLClass
does the job. Ciao
Nov 06 2003
I'm not buying into your dogma. Anyway it's not a global variable, it's a global constant. Similar to PI or whatever. Are you saying those are always bad too? Sean "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> wrote in message news:bod14n$2ka4$1 digitaldaemon.com...I'm sorry, but I think the introduction of global variables purely for syntactic sugaring is a slippery slope that none of us will like hitting
bottom of. In general, if you need global variables, your design is flawed.
Nov 09 2003
I'm not buying into your dogma.
Probably wise, as I think I had my Devil's Advocate head on in this discussion
Nov 09 2003
Charles Sanders:But what would endl be defined as, an arbitrary number ? How would it know i didnt actually want to output that specific number ?
This should work: typedef uint SpecialChar; enum: SpecialChar { endl = 0, tab = 1, ... } So endl won't be confused with uints. But we can also use this: version(linux) const char endl = '\n'; version(Win32) const char[] endl = "\r\n"; But I don't like Stdout(...)(...)(...). I'd like Stdout.print(...)(...)(...) instead, though I understand that it's harder to implement. There should be: file.print(...)(...)(...); // write formatted data file.scan(...)(...)(...); // read formatted data file.write(...)(...)(...); // write raw data file.read(...)(...)(...); // read raw data I'll try to write something that works... Dario
Nov 06 2003
He he. That's as much counter-semantic operator overloading as I like to see. Bravo! "Dario" <Dario_member pathlink.com> wrote in message news:bodm0g$he4$1 digitaldaemon.com...Something like this will work:
Nov 06 2003
Oops, an empty message...
I swear I wrote something in it! :-O
Something like this should work:
_
_ const char[] endl = "\r\n";
_
_ struct Write
_ { private Stream stream;
_ Write opCall(char x) {
_ stream.rawWrite(&x, x.size);
_ return *this;
_ }
_ Write opCall(char[] x) {
_ stream.rawWrite(x, x.length);
_ return *this;
_ }
_ }
_
_ class Stream
_ { union
_ { private Stream self;
_ Write write;
_ }
_ this() { self = this; }
_ abstract void rawWrite(void*, uint);
_ }
_
_ class File: Stream
_ { HANDLE fd;
_ this(HANDLE fd) { this.fd = fd; }
_ void rawWrite(void* bf, uint sz)
_ { uint wr;
_ WriteFile(fd, bf, sz, &wr, null);
_ }
_ }
_
_ void main()
_ { File stdout = new File(GetStdHandle(-11));
_ stdout.write("Hello")('!')(endl);
_ }
I realize that this code looks tricky and cumbersome.
And it isn't perfect too: a reference to the stream
is kept though it shouldn't be necessary.
Notice how the const char[] endl fits well.
I guess it can be useful to write portable code too.
Dario
Nov 06 2003
In article <bocf1q$1o62$1 digitaldaemon.com>, Charles Sanders says...I like it! Im not a fan of the .nl() though it looks inconsistent, not sure how else to handle it though. C
I agree. ("\n") seems a little cleaner to me. Also, would it make sense to declare Stdout static in stdio so you don't need to instantiate it each time? -Jon"Walter" <walter digitalmars.com> wrote in message news:boc9me$1g2b$1 digitaldaemon.com...Since with () overloading class objects can now look like functions, I've been toying with the idea of using this for formatted I/O. Here's a trial mockup of what it might look like: ----------------------------------------------- import std.string; import std.c.stdio; import std.c.stdlib; class Stdout { Stdout opCall(int i) { printf("%d", i); return this; } Stdout opCall(char[] format, ...) { va_list ap; ap = cast(va_list)&format; ap += format.size; vprintf(format, ap); return this; } Stdout nl() { printf("\n"); return this; } } void main() { Stdout stdout = new Stdout(); stdout("hello")(" world")(47).nl()("bar")("%06i\n", 62); } ------------------------------------------- (Note that it retains the power of printf!) The issue here is how the
stdout("foo")("bar") looks. In C++ it would look like stdout<<"foo"<<"bar" which I don't find appealing.
Nov 05 2003
"Jonathan Andrew" <Jonathan_member pathlink.com> wrote in message news:bocl5e$21g8$1 digitaldaemon.com...Also, would it make sense to declare Stdout static in stdio so you don't need to instantiate it each time?
Yes, of course. There'd be an abstract class forming the base of it, then there'd be Stdout deriving from it and sending its output to the console. stdout would be some global static. There'd also be another derivation from the base class which would enable buffered output to a file, and output to a string, etc. I can make all that work, so the question is do people like the ()() approach, or does it just stink? Andy suggests using ~ instead, that certainly has an appeal, but I'm a bit concerned though about sinking into the C++ << quagmire <G>.
Nov 05 2003
Walter wrote:I can make all that work, so the question is do people like the ()() approach, or does it just stink? Andy suggests using ~ instead, that certainly has an appeal, but I'm a bit concerned though about sinking into the C++ << quagmire <G>.
I dislike both, especially the ~. If you use the ()() syntax, then it must be a general language feature, that can be used for any function, e. g. MoveTo(x1,y1); DrawTo(x2,y1)(x2,y2)(x1,y2)(x1,y1); If it is that way, it may be ok. It won't hurt, if it isn't used with io in the end. If it is only usable with opCall, then it is an ugly hack. On the other hand it doesn't solve the inefficiency problem of "C++ <<", effecitivly producing a flood of func(this,fmt[,type]) calls. And it is not searchable. And what is the advantage over: stream.print(...)(...)(...); ? Even if you do this, these are still open problems - to pass a variable number of arguments safely - to get a generic interface to pass - any arry => ArrayInfoStruct - any primitive (now "Type", should be "Prim[itive]") => PrimInfoStruct - any object, array or primitive => TypeInfoStruct It would be no good to fix the io problem without taking these into account. -- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.com
Nov 05 2003
Any function that returns itself should work like that, but how the heck
would you specify the signature of a function that returns itself?!?
(int,int)(*)(int,int)(*)(int,int)(*)(int,int)(*)(int,int)(*)(int,int)
DrawTo(int x,int y) { Line(opx,opy,x,y); opx = x; opy = y; return DrawTo; }
It doesn't even seem that typedef will help here.
Sean
"Helmut Leitner" <helmut.leitner wikiservice.at> wrote in message
news:3FA9F16C.9DF16013 wikiservice.at...
Walter wrote:
I can make all that work, so the question is do people like the ()()
approach, or does it just stink? Andy suggests using ~ instead, that
certainly has an appeal, but I'm a bit concerned though about sinking
the C++ << quagmire <G>.
I dislike both, especially the ~.
If you use the ()() syntax, then it must be a general language feature,
that can be used for any function, e. g.
MoveTo(x1,y1);
DrawTo(x2,y1)(x2,y2)(x1,y2)(x1,y1);
If it is that way, it may be ok. It won't hurt, if it isn't used with io
If it is only usable with opCall, then it is an ugly hack.
On the other hand it doesn't solve the inefficiency problem of "C++ <<",
effecitivly producing a flood of
func(this,fmt[,type])
calls.
And it is not searchable.
And what is the advantage over:
stream.print(...)(...)(...);
?
Even if you do this, these are still open problems
- to pass a variable number of arguments safely
- to get a generic interface to pass
- any arry =>
- any primitive (now "Type", should be "Prim[itive]") =>
- any object, array or primitive =>
It would be no good to fix the io problem without taking these into
account.
--
Helmut Leitner leitner hls.via.at
Graz, Austria www.hls-software.com
Nov 06 2003
"Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:boe65h$19t4$1 digitaldaemon.com...Any function that returns itself should work like that, but how the heck would you specify the signature of a function that returns itself?!?
You can't. But you *can* make it work with a so-called function object, which is an object with the () operator overloaded. This works now in D.
Nov 08 2003
"Helmut Leitner" <helmut.leitner wikiservice.at> wrote in message news:3FA9F16C.9DF16013 wikiservice.at...Walter wrote:I can make all that work, so the question is do people like the ()() approach, or does it just stink? Andy suggests using ~ instead, that certainly has an appeal, but I'm a bit concerned though about sinking
the C++ << quagmire <G>.
Ok.If you use the ()() syntax, then it must be a general language feature, that can be used for any function, e. g. MoveTo(x1,y1); DrawTo(x2,y1)(x2,y2)(x1,y2)(x1,y1); If it is that way, it may be ok. It won't hurt, if it isn't used with io
If it is only usable with opCall, then it is an ugly hack.
It won't work at all with functions, but it will work with function objects (i.e. opCall).On the other hand it doesn't solve the inefficiency problem of "C++ <<", effecitivly producing a flood of func(this,fmt[,type]) calls.
I'm not sure why C++'s way fares so poorly. What it won't need to do is have a specialized parser for printf's format string, which takes time.And it is not searchable.
It is by searching for 'stdout'.And what is the advantage over: stream.print(...)(...)(...); ?
()() won't work with plain old functions.Even if you do this, these are still open problems - to pass a variable number of arguments safely
Use (var1)(var2)(var3) etc.- to get a generic interface to pass - any arry =>
- any primitive (now "Type", should be "Prim[itive]") =>
- any object, array or primitive =>
It would be no good to fix the io problem without taking these into account.
Yes, that needs work.
Nov 08 2003
"Walter" <walter digitalmars.com> wrote in message news:bojg4f$2qpr$1 digitaldaemon.com...On the other hand it doesn't solve the inefficiency problem of "C++ <<", effecitivly producing a flood of func(this,fmt[,type]) calls.
I'm not sure why C++'s way fares so poorly. What it won't need to do is
a specialized parser for printf's format string, which takes time.
We went over a way to reduce that inefficiency at one point. We actually did measure considerable overhead in the printf string parsing, in our game at one point, the font drawing function was routing everything thru sprintf. The signature of the draw function was: void Font::Draw(Vc3, Color, char const*, ...); When we changed Font().Draw(Vc3(40,50), Color::red, "My big long string"); to: Font().Draw(Vc3(40,50), Color::red, "%s", "My big long string"); we got a huge savings. Sean
Nov 09 2003
"Walter" <walter digitalmars.com> wrote in message news:bocp61$27of$1 digitaldaemon.com..."Jonathan Andrew" <Jonathan_member pathlink.com> wrote in message news:bocl5e$21g8$1 digitaldaemon.com...Also, would it make sense to declare Stdout static in stdio so you don't need to instantiate it each time?
Yes, of course. There'd be an abstract class forming the base of it, then there'd be Stdout deriving from it and sending its output to the console. stdout would be some global static. There'd also be another derivation
the base class which would enable buffered output to a file, and output to
string, etc. I can make all that work, so the question is do people like the ()() approach, or does it just stink? Andy suggests using ~ instead, that certainly has an appeal, but I'm a bit concerned though about sinking into the C++ << quagmire <G>.
It's ugly, but at least it's not (mis)using operators. I take it that the reason you want to use it is because it will do an atomic write with a result of all the individual expressions?
Nov 05 2003
"Matthew Wilson" <matthew-hat -stlsoft-dot.-org> wrote in message news:bocre8$2avm$1 digitaldaemon.com...I take it that the reason you want to use it is because it will do an
write with a result of all the individual expressions?
I like it because it can work without double buffering of the intermediate results. It can be as efficient as printf().
Nov 08 2003
Walter wrote:Since with () overloading class objects can now look like functions, I've been toying with the idea of using this for formatted I/O. Here's a trial mockup of what it might look like: [...]
(Note that it retains the power of printf!) The issue here is how the syntax stdout("foo")("bar") looks. In C++ it would look like stdout<<"foo"<<"bar" which I don't find appealing.
I think () is a bit too busy. '~' may be better, since it's a lot less hoggish in terms of eyeball-space. Plus, D already uses it to indicate concatenation. stdout ~ "Hello " ~ "world" ~ 47 ~ endl ~ "bar" ~ format("%06i\n", 62); -- andy
Nov 05 2003
Andy Friesen wrote:[snip]
I think () is a bit too busy. '~' may be better, since it's a lot less hoggish in terms of eyeball-space. Plus, D already uses it to indicate concatenation. stdout ~ "Hello " ~ "world" ~ 47 ~ endl ~ "bar" ~ format("%06i\n", 62); -- andy
you've got bidirectional streams how would that be handled?
Nov 05 2003
More operating overloading gunk. Hate it hate it hate it. Once again the evil zombie iostreams are sent to plague us, just wearing another head Gilbert Grump "Andy Friesen" <andy ikagames.com> wrote in message news:bocnlc$25gn$1 digitaldaemon.com...Walter wrote:Since with () overloading class objects can now look like functions,
been toying with the idea of using this for formatted I/O. Here's a
mockup of what it might look like: [...]
(Note that it retains the power of printf!) The issue here is how the
stdout("foo")("bar") looks. In C++ it would look like
which I don't find appealing.
I think () is a bit too busy. '~' may be better, since it's a lot less hoggish in terms of eyeball-space. Plus, D already uses it to indicate concatenation. stdout ~ "Hello " ~ "world" ~ 47 ~ endl ~ "bar" ~ format("%06i\n", 62); -- andy
Nov 05 2003
Matthew Wilson wrote:More operating overloading gunk. Hate it hate it hate it. Once again the evil zombie iostreams are sent to plague us, just wearing another head Gilbert Grump
Yup. But the reason I use printf instead of std::stringstream isn't any asthetic aversion to using << to indicate redirection. It's not because I think it's cryptic either. I've never known stream twiddling to ever reach that sort of complexity, and I've never needed to do bit shifting in the middle of stream in/output. I simply don't like how verbose things get when you start to do more complicated formatting. It's a pain to type and look at. I don't think that operator() is any better in that regard, though I suppose it is less arbitrary in nature. (caveat: opCall can accept any number of arguments; formatting could be much simpler than with any binary operator) Maybe D just needs some (completely insane) way to overload the comma operator and translate what looks like a single varargs method call into a series of monadic calls. Maybe not. -- andy
Nov 06 2003
Andy Friesen wrote:Maybe D just needs some (completely insane) way to overload the comma operator and translate what looks like a single varargs method call into a series of monadic calls. Maybe not.
Maybe D only needs a way to pass a variable number of arguments in a type-safe way. That would solve all problems of printf, since printf could always find out what was actually passed to it. Since D objects are always passed by reference only this problem is actually a little easier to solve than in C++. Howsabout the following: void print(char[] formatstring, vararglist args ); vararglist would be a special internal type that the compiler recognizes. Instead of just pushing all arguments onto the stack the compiler internally creates an array of structs of the following form (the implementation should probably be hidden from the programmer): struct vararg { int type; //type-info pointer?? TYPE arg; }; type could be a special value indicating whether it is a simple type (int, double, etc.) or an object reference. The class of the object would not have to be included, since objects in D already have runtime type information. The only problem I see with this are structs and pointers to structs. Does the compiler automatically generate some kind of typeinfo structure for each struct? If it does then vararg could simply include a pointer to that typeinfo and the called function could find out what kind of struct was passed. Another alternative, of course, would be to not allow structs to be passed to such a function. Anyway, provided that the struct problem is solved somehow then on the called side everything could be typesafe. A vararglist object could behave like some kind of iterator or cursor: void print(char[] formatstring, vararglist args) { while(args.next()) { if(args.isInt()) { int val=args.getInt(); //throws exception if //not an int or compatible type } else if(args.isObject()) { Object obj=args.getObject(); //throws an //exception if not an object } ... } } Hauke
Nov 06 2003
Why not implement it like this?:
void print(... args)
{
foreach(v in args)
v.print(stdout);
}
Every type then would be required to provide a print function to a stream.
There could be several such functions (auto-generated if not explicitly
provided, of course) that read and write to/from text or binary streams.
The auto-generated functions would perhaps just call the base class function
then print the new members.
Sean
"Hauke Duden" <H.NS.Duden gmx.net> wrote in message
news:bodopv$lfe$1 digitaldaemon.com...
Andy Friesen wrote:
Maybe D just needs some (completely insane) way to overload the comma
operator and translate what looks like a single varargs method call into
a series of monadic calls. Maybe not.
Maybe D only needs a way to pass a variable number of arguments in a
type-safe way. That would solve all problems of printf, since printf
could always find out what was actually passed to it.
Since D objects are always passed by reference only this problem is
actually a little easier to solve than in C++.
Howsabout the following:
void print(char[] formatstring, vararglist args );
vararglist would be a special internal type that the compiler
recognizes. Instead of just pushing all arguments onto the stack the
compiler internally creates an array of structs of the following form
(the implementation should probably be hidden from the programmer):
struct vararg
{
int type; //type-info pointer??
TYPE arg;
};
type could be a special value indicating whether it is a simple type
(int, double, etc.) or an object reference. The class of the object
would not have to be included, since objects in D already have runtime
type information.
The only problem I see with this are structs and pointers to structs.
Does the compiler automatically generate some kind of typeinfo structure
for each struct? If it does then vararg could simply include a pointer
to that typeinfo and the called function could find out what kind of
struct was passed.
Another alternative, of course, would be to not allow structs to be
passed to such a function.
Anyway, provided that the struct problem is solved somehow then on the
called side everything could be typesafe. A vararglist object could
behave like some kind of iterator or cursor:
void print(char[] formatstring, vararglist args)
{
while(args.next())
{
if(args.isInt())
{
int val=args.getInt(); //throws exception if
//not an int or compatible type
}
else if(args.isObject())
{
Object obj=args.getObject(); //throws an
//exception if not an object
}
...
}
}
Hauke
Nov 06 2003
You lose atomicity of write. "Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:boe43g$16ri$1 digitaldaemon.com...Why not implement it like this?: void print(... args) { foreach(v in args) v.print(stdout); } Every type then would be required to provide a print function to a stream. There could be several such functions (auto-generated if not explicitly provided, of course) that read and write to/from text or binary streams. The auto-generated functions would perhaps just call the base class
then print the new members. Sean "Hauke Duden" <H.NS.Duden gmx.net> wrote in message news:bodopv$lfe$1 digitaldaemon.com...Andy Friesen wrote:Maybe D just needs some (completely insane) way to overload the comma operator and translate what looks like a single varargs method call
a series of monadic calls. Maybe not.
Maybe D only needs a way to pass a variable number of arguments in a type-safe way. That would solve all problems of printf, since printf could always find out what was actually passed to it. Since D objects are always passed by reference only this problem is actually a little easier to solve than in C++. Howsabout the following: void print(char[] formatstring, vararglist args ); vararglist would be a special internal type that the compiler recognizes. Instead of just pushing all arguments onto the stack the compiler internally creates an array of structs of the following form (the implementation should probably be hidden from the programmer): struct vararg { int type; //type-info pointer?? TYPE arg; }; type could be a special value indicating whether it is a simple type (int, double, etc.) or an object reference. The class of the object would not have to be included, since objects in D already have runtime type information. The only problem I see with this are structs and pointers to structs. Does the compiler automatically generate some kind of typeinfo structure for each struct? If it does then vararg could simply include a pointer to that typeinfo and the called function could find out what kind of struct was passed. Another alternative, of course, would be to not allow structs to be passed to such a function. Anyway, provided that the struct problem is solved somehow then on the called side everything could be typesafe. A vararglist object could behave like some kind of iterator or cursor: void print(char[] formatstring, vararglist args) { while(args.next()) { if(args.isInt()) { int val=args.getInt(); //throws exception if //not an int or compatible type } else if(args.isObject()) { Object obj=args.getObject(); //throws an //exception if not an object } ... } } Hauke
Nov 06 2003
That is not a problem. It's "writing" directly into the stream's buffer. The actual write happens upon buffer flushes. Sean "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> wrote in message news:boec1l$1j08$2 digitaldaemon.com...You lose atomicity of write. "Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:boe43g$16ri$1 digitaldaemon.com...Why not implement it like this?: void print(... args) { foreach(v in args) v.print(stdout); } Every type then would be required to provide a print function to a
There could be several such functions (auto-generated if not explicitly provided, of course) that read and write to/from text or binary streams. The auto-generated functions would perhaps just call the base class
then print the new members. Sean
Nov 09 2003
What is so evil about it?
What is more evil:
Pascal: WriteLn("foo", ' ', bar);
C: printf("%s%c%i\n","foo",' ',bar);
C++: cout << "foo" << ' ' << bar << endl;
BASIC: print "foo", " ", %bar, chr(13)
D proposal #1: stdout("foo")(' ')(bar)(endl);
D proposal #2: stdout ~ "foo" ~ ' ' ~ bar ~ endl;
Why would you think commas are so much better than tildes or parens?
I can see tilde being confused with the array concatenation operator.
Parens are not confusing at all, once you get used to the chained call
style.
Commas are confusing too because of the comma operator that C,C++, and D all
share.
Sean
"Matthew Wilson" <matthew-hat -stlsoft-dot.-org> wrote in message
news:bocr93$2am6$2 digitaldaemon.com...
More operating overloading gunk. Hate it hate it hate it. Once again the
evil zombie iostreams are sent to plague us, just wearing another head
Gilbert Grump
Nov 06 2003
What is more evil: Pascal: WriteLn("foo", ' ', bar); C: printf("%s%c%i\n","foo",' ',bar); C++: cout << "foo" << ' ' << bar << endl; ** This one BASIC: print "foo", " ", %bar, chr(13)
D proposal #1: stdout("foo")(' ')(bar)(endl); D proposal #2: stdout ~ "foo" ~ ' ' ~ bar ~ endl; ** This one Why would you think commas are so much better than tildes or parens?
I don'tI can see tilde being confused with the array concatenation operator.
Indeed. That is one of the objections to itParens are not confusing at all, once you get used to the chained call style.
Indeed. That is preferable, as I think I've indicated already in this threadCommas are confusing too because of the comma operator that C,C++, and D
share.
Agreed
Nov 06 2003
Matthew Wilson wrote:I can see tilde being confused with the array concatenation operator.
Indeed. That is one of the objections to it
Why "confused"? It's actually the maning of it! Look. If you have an output, you are actually concatenating stuff to it. Especially if it is a file. Or even if it is a console the paradigm works well enough. It doesn't make so much sense with inputs though. I think we need something like operator : or :: on them, which could also be used for list separation? Sather uses a notation like this #OUT + "this " + 123 + " that"; It actually creates an anonymous object of class OUT and calls an add method of it. Considering that adding is Sather's way of concatenating stuff, it's basically the same idea. The operator itself simply does the output, and then passes the OUT further. -eye
Nov 07 2003
What about C#'s
MessageBox.Show("NumTwo is {1} and NumOne {0} and both are {0}{1}", NumOne,
NumTwo);
"Sean L. Palmer" <palmer.sean verizon.net> wrote in message
news:boe3nb$16a7$1 digitaldaemon.com...
What is so evil about it?
What is more evil:
Pascal: WriteLn("foo", ' ', bar);
C: printf("%s%c%i\n","foo",' ',bar);
C++: cout << "foo" << ' ' << bar << endl;
BASIC: print "foo", " ", %bar, chr(13)
Nov 08 2003
In article <boc9me$1g2b$1 digitaldaemon.com>, Walter says... [...]void main() { Stdout stdout = new Stdout(); stdout("hello")(" world")(47).nl()("bar")("%06i\n", 62); }
if I understand, this would be equivalent to: stdout.opCall("hello").opCall(" world").opCall(47).nl().opCall("bar").opCall("%06i\n", 62); Right?(Note that it retains the power of printf!)
so this: stdout("I am 50% stupid?"); generates a segmentation fault?The issue here is how the syntax stdout("foo")("bar") looks. In C++ it would look like stdout<<"foo"<<"bar" which I don't find appealing.
I like <<, I like (), I like ~ (althouhg I haven't ~ on my keyboard). Ciao
Nov 05 2003
Roberto Mariottini wrote:althouhg I haven't ~ on my keyboard).
That's important! VERY important. If ~ is not on all keyboards, then IMHO it shouldn't be a built-in operator at all. What kind of keyboard is this? Hauke
Nov 06 2003
In article <bod2or$2mnk$1 digitaldaemon.com>, Hauke Duden says...Roberto Mariottini wrote:althouhg I haven't ~ on my keyboard).
That's important! VERY important. If ~ is not on all keyboards, then IMHO it shouldn't be a built-in operator at all. What kind of keyboard is this?
Italian keyboard. For sure every one of the 56 millions of italians has to use the Alt-126 combination to enter a single ~. We also have no {}, but the undocumented AltGr-Shift-[ and AltGr-Shift-] cobinations fortunately work in any italian keyboard Windows driver, although I see many of my collegues using Alt-123 and Alt-125. Old italian hackers use USA keyboards, but not all employers agree to buy one for every developer. Ciao
Nov 06 2003
OMG. I didn't think it is possible that { and } can be omitted on a keyboard
layout....
--
Jan-Eric Duden
"Roberto Mariottini" <Roberto_member pathlink.com> wrote in message
news:bod3l8$2o2j$1 digitaldaemon.com...
In article <bod2or$2mnk$1 digitaldaemon.com>, Hauke Duden says...
Roberto Mariottini wrote:
althouhg I haven't ~ on my keyboard).
That's important! VERY important. If ~ is not on all keyboards, then
IMHO it shouldn't be a built-in operator at all.
What kind of keyboard is this?
Italian keyboard.
For sure every one of the 56 millions of italians has to use the Alt-126
combination to enter a single ~.
We also have no {}, but the undocumented AltGr-Shift-[ and AltGr-Shift-]
cobinations fortunately work in any italian keyboard Windows driver,
see many of my collegues using Alt-123 and Alt-125.
Old italian hackers use USA keyboards, but not all employers agree to buy
for every developer.
Ciao
Nov 06 2003
I've looked at it and i find the italian keyboard very wierd. It is underpopulated in some spots and overpopulated in the others. Bad design. It also doesn't have a backquote, which is even present on hebrew, russian, and all other fancy keyboars i've ever seen - and which is requiered by some programming languages as well, most notably lisp. And UNIX simply doesn't work without ~. You can use a keyboard layout editor. Under Windows i use KLM Medium: http://www.klm.freeservers.com/ However, it costs more than a US keyboard. Another sane solution would be a program which would be a resident and listen to a magic key combination, and then pastes the symbol into the program. Or even a widows shortcut with a hotkey to call a small program which would only paste a symbol into an active program... -eye Roberto Mariottini wrote:Italian keyboard. For sure every one of the 56 millions of italians has to use the Alt-126 combination to enter a single ~. We also have no {}, but the undocumented AltGr-Shift-[ and AltGr-Shift-] cobinations fortunately work in any italian keyboard Windows driver, although I see many of my collegues using Alt-123 and Alt-125. Old italian hackers use USA keyboards, but not all employers agree to buy one for every developer. Ciao
Nov 06 2003
"Roberto Mariottini" <Roberto_member pathlink.com> wrote in message news:bod3l8$2o2j$1 digitaldaemon.com...Old italian hackers use USA keyboards, but not all employers agree to buy
for every developer.
I hate to be annoying <g>, but a USA keyboard can be had for $9.99 around here. Mine cost $19.99, but that's only because I just cannot stand the oversized Enter key that substitutes for the \ key. Every time I hit \, I get Enter instead and the command gets prematurely executed, sometimes with disastrous results: rm -r foo\bar becomes: rm -r foo Argggh! Why can't these layouts be standardized? C++ tried to get around the keyboard problem by introducing digraphs. When that failed, trigraphs were introduced. That's failed too, and now there's \uxxxx, etc. (By failed I mean that I see a lot of code from all over the world, and never once have I seen any code outside of a test suite that used digraphs, trigraphs, or \u or \U.) The C/C++ experiments with this show that there isn't a known decent solution. What I do to input funky characters is cut & paste them from a palette of them.
Feb 20 2004
I hate to be annoying <g>, but a USA keyboard can be had for $9.99 around here. Mine cost $19.99, but that's only because I just cannot stand the oversized Enter key that substitutes for the \ key. Every time I hit \, I get Enter instead and the command gets prematurely executed, sometimes with disastrous results:
I have that large Enter. What used to bug me is backspace being smaller and me constantly bumping the insert key; that is, until I pulled the key out :D -- Christopher E. Miller www.dprogramming.com irc.dprogramming.com #D
Feb 21 2004
| What I do to input funky characters is cut & paste them from a | palette of them. I know what you mean - the old Mac's MPW environment used greek deltas (option-D) in scripts for line-continuation. There were a few times when I found myself editing a script on a wacky keyboard and could only wrap lines by cutting and pasting these darn deltas from somewhere else. MPW loved that option key. -Ben
Feb 21 2004
Hi,
the following example shows why you can't have only one
Stdout opCall(char[] format, ...)
to handle all strings output, but you must have one opCall with only one string
as parameter.
Works with:
Digital Mars Compiler Version 8.29n
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
It doesn't work well with Borland compiler, gcc generates a segfault.
------------------------test.c----------------------------
#include <stdio.h>
char *s = "%%% stupid, not stupid %%%";
int f(char *m)
{
return m[15] = 0;
}
int main()
{
char *p = s+ 2;
f(p);
printf("I am 100% sane at all.\n");
return 0;
}
------------------------test.c----------------------------
Ciao
Nov 07 2003
This got me thinking about message chaining in Object C and SmallTalk (or
message cascading...)
Maybe a whole new syntax could help and possibly replace printf and ~.
Something like
stdout.printf["hello", " world", 47, "\nbar", ("%06i\n", 62)];
string.cat["a", "bc", 47, "def"];
would turn into
stdout.printf("hello").printf("
world").printf(47).printf("\nbar").printf("%06i\n", 62);
string.cat("a").cat("bc").cat(47).cat("def");
I haven't thought about if this syntax conflicts with anything else or is
implementable ;-)
-Ben
"Walter" <walter digitalmars.com> wrote in message
news:boc9me$1g2b$1 digitaldaemon.com...
Since with () overloading class objects can now look like functions, I've
been toying with the idea of using this for formatted I/O. Here's a trial
mockup of what it might look like:
-----------------------------------------------
import std.string;
import std.c.stdio;
import std.c.stdlib;
class Stdout
{
Stdout opCall(int i)
{
printf("%d", i);
return this;
}
Stdout opCall(char[] format, ...)
{
va_list ap;
ap = cast(va_list)&format;
ap += format.size;
vprintf(format, ap);
return this;
}
Stdout nl()
{
printf("\n");
return this;
}
}
void main()
{ Stdout stdout = new Stdout();
stdout("hello")(" world")(47).nl()("bar")("%06i\n", 62);
}
-------------------------------------------
(Note that it retains the power of printf!) The issue here is how the
stdout("foo")("bar") looks. In C++ it would look like stdout<<"foo"<<"bar"
which I don't find appealing.
Nov 06 2003
This got me thinking about message chaining in Object C and SmallTalk (or message cascading...) Maybe a whole new syntax could help and possibly replace printf and ~. Something like stdout.printf["hello", " world", 47, "\nbar", ("%06i\n", 62)]; string.cat["a", "bc", 47, "def"]; would turn into stdout.printf("hello").printf(" world").printf(47).printf("\nbar").printf("%06i\n", 62); string.cat("a").cat("bc").cat(47).cat("def"); I haven't thought about if this syntax conflicts with anything else or is implementable ;-) -Ben
I think the point of the concatenated (not concatenating, mind you) syntax is that the write operation would be atomic, which would certainly need to be the case to system streams such as the log stream, and to process-wide streams in a multi-threaded process. If your example translates to a function that does that, by concatenating all input in a buffer, and then sending that to the requisite output stream in a single operation, then I would think it worth pursuing.
Nov 06 2003
Matthew Wilson wrote:This got me thinking about message chaining in Object C and SmallTalk (or message cascading...) Maybe a whole new syntax could help and possibly replace printf and ~. Something like stdout.printf["hello", " world", 47, "\nbar", ("%06i\n", 62)]; string.cat["a", "bc", 47, "def"]; would turn into stdout.printf("hello").printf(" world").printf(47).printf("\nbar").printf("%06i\n", 62); string.cat("a").cat("bc").cat(47).cat("def"); I haven't thought about if this syntax conflicts with anything else or is implementable ;-) -Ben
I think the point of the concatenated (not concatenating, mind you) syntax is that the write operation would be atomic, which would certainly need to be the case to system streams such as the log stream, and to process-wide streams in a multi-threaded process.
printf() is not atomic, I believe. write() generally is, I think. But printf() buffers output until either the buffer fills up or you call fflush(). So why are you arguing about the atomicity of print mechanisms? If atomicity is critical, form your own buffer and then use write() directly.
Nov 06 2003
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:boedmk$1l44$1 digitaldaemon.com...Matthew Wilson wrote:This got me thinking about message chaining in Object C and SmallTalk
message cascading...) Maybe a whole new syntax could help and possibly replace printf and ~. Something like stdout.printf["hello", " world", 47, "\nbar", ("%06i\n", 62)]; string.cat["a", "bc", 47, "def"]; would turn into stdout.printf("hello").printf(" world").printf(47).printf("\nbar").printf("%06i\n", 62); string.cat("a").cat("bc").cat(47).cat("def"); I haven't thought about if this syntax conflicts with anything else or
implementable ;-) -Ben
I think the point of the concatenated (not concatenating, mind you)
is that the write operation would be atomic, which would certainly need
be the case to system streams such as the log stream, and to
streams in a multi-threaded process.
printf() is not atomic, I believe. write() generally is, I think. But printf() buffers output until either the buffer fills up or you call fflush(). So why are you arguing about the atomicity of print mechanisms? If atomicity is critical, form your own buffer and then use write() directly.
Fair enough. My ineptly using printf as an example does not negate the point, however.
Nov 06 2003
Matthew Wilson wrote:"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:boedmk$1l44$1 digitaldaemon.com...Matthew Wilson wrote:This got me thinking about message chaining in Object C and SmallTalk
(ormessage cascading...) Maybe a whole new syntax could help and possibly replace printf and ~. Something like stdout.printf["hello", " world", 47, "\nbar", ("%06i\n", 62)]; string.cat["a", "bc", 47, "def"]; would turn into stdout.printf("hello").printf(" world").printf(47).printf("\nbar").printf("%06i\n", 62); string.cat("a").cat("bc").cat(47).cat("def"); I haven't thought about if this syntax conflicts with anything else or
isimplementable ;-) -Ben
I think the point of the concatenated (not concatenating, mind you)
syntaxis that the write operation would be atomic, which would certainly need
tobe the case to system streams such as the log stream, and to
process-widestreams in a multi-threaded process.
printf() is not atomic, I believe. write() generally is, I think. But printf() buffers output until either the buffer fills up or you call fflush(). So why are you arguing about the atomicity of print mechanisms? If atomicity is critical, form your own buffer and then use write() directly.
Fair enough. My ineptly using printf as an example does not negate the point, however.
I hear you, but I don't think that atomic writes are a big requirement for a general-purpose formatted I/O routine. Once the routine is in place, you can use the syntax (whatever it happens to be) to build a buffer in memory, something like: Stream str = new BufStream; str <insert the formatting syntax here>; write(file_pointer, str);
Nov 06 2003
Russ Lewis wrote:I hear you, but I don't think that atomic writes are a big requirement for a general-purpose formatted I/O routine. Once the routine is in place, you can use the syntax (whatever it happens to be) to build a buffer in memory, something like: Stream str = new BufStream; str <insert the formatting syntax here>; write(file_pointer, str);
IIRC that's what Walter wanted to avoid forcing on the user, for efficiency reasons. He wants whatever system D has to be at least as efficient as printf. Not a basic requierement for the IO system IMHO - that's what the same write is for. A basic requierement is typesafety, extensibility, and ease of use even for beginners. C++ iostreams serve these requierements wonderfully well. -eye
Nov 07 2003
Ilya Minkov wrote:I hear you, but I don't think that atomic writes are a big requirement for a general-purpose formatted I/O routine. Once the routine is in place, you can use the syntax (whatever it happens to be) to build a buffer in memory, something like: Stream str = new BufStream; str <insert the formatting syntax here>; write(file_pointer, str);
IIRC that's what Walter wanted to avoid forcing on the user, for efficiency reasons. He wants whatever system D has to be at least as efficient as printf. Not a basic requierement for the IO system IMHO - that's what the same write is for. A basic requierement is typesafety, extensibility, and ease of use even for beginners. C++ iostreams serve these requierements wonderfully well.
I just had an idea to create an atomic version of the proposed print with the same syntax. Couldn't the first atomicPrint call return an auto object (like the BufStream mentioned above) that itself works in the same way as the proposed StdIO object? It would accumulate the following print calls and output the resulting string when its destructor is called. Essentially this would be the same as using a temporary Stream object, except that the user would not have to create it explicitly. Not sure whether auto-objects can be returned from a function, though. My intuition tells me probably not, but I'll would have to try it out... Hauke
Nov 07 2003
"Matthew Wilson" <matthew-hat -stlsoft-dot.-org> wrote in message news:boec1m$1j08$3 digitaldaemon.com...This got me thinking about message chaining in Object C and SmallTalk
message cascading...) Maybe a whole new syntax could help and possibly replace printf and ~. Something like stdout.printf["hello", " world", 47, "\nbar", ("%06i\n", 62)]; string.cat["a", "bc", 47, "def"]; would turn into stdout.printf("hello").printf(" world").printf(47).printf("\nbar").printf("%06i\n", 62); string.cat("a").cat("bc").cat(47).cat("def"); I haven't thought about if this syntax conflicts with anything else or
implementable ;-) -Ben
I think the point of the concatenated (not concatenating, mind you) syntax is that the write operation would be atomic, which would certainly need to be the case to system streams such as the log stream, and to process-wide streams in a multi-threaded process. If your example translates to a function that does that, by concatenating all input in a buffer, and then sending that to the requisite output
in a single operation, then I would think it worth pursuing.
I hadn't thought about that. Reading my post again (aside from the fact that I can't spell "Objective" before my first cup of coffee) I also see I was assuming strings were class objects and not plain arrays. I'll ponder some more about the atomic stuff and about cascading non-member functions. -Ben
Nov 06 2003
There are equally as many cases where you *don't* want the output to be atomic. It is slower to write into this temporary buffer, before sending the final buffer to the stream, than to write directly into the stream's buffer. Besides, you don't usually know how big of a buffer you're going to need before you start writing. Streams are always buffered, right? If so there's a nice Flush() command somewhere. Unbuffered streams are horribly inefficient. Sean "Matthew Wilson" <matthew-hat -stlsoft-dot.-org> wrote in message news:boec1m$1j08$3 digitaldaemon.com...This got me thinking about message chaining in Object C and SmallTalk
message cascading...) Maybe a whole new syntax could help and possibly replace printf and ~. Something like stdout.printf["hello", " world", 47, "\nbar", ("%06i\n", 62)]; string.cat["a", "bc", 47, "def"]; would turn into stdout.printf("hello").printf(" world").printf(47).printf("\nbar").printf("%06i\n", 62); string.cat("a").cat("bc").cat(47).cat("def"); I haven't thought about if this syntax conflicts with anything else or
implementable ;-) -Ben
I think the point of the concatenated (not concatenating, mind you) syntax is that the write operation would be atomic, which would certainly need to be the case to system streams such as the log stream, and to process-wide streams in a multi-threaded process. If your example translates to a function that does that, by concatenating all input in a buffer, and then sending that to the requisite output
in a single operation, then I would think it worth pursuing.
Nov 09 2003
Why not make IO a more formal operation.
Introduce a new keyword "write"
Syntax: write object, param [,param]*;
Example:
float a = 12.4;
write stdOut,"Hello ",12,.format(4,2,a)," amount";
Any "." preceeded name is considers a function of
the object.
The object has opWrite functions.
class StdOut
{
opWrite(char[]) { }
opWrite(int) { }
opWrite(float) { }
format(int digits,int postDigits, float value);
}
Read is handled in a similar way.
Example:
read stdIn, a, b, c;
class StdIn
{
opRead(out char[]) { }
opRead(out int) {}
//etc...
}
Nov 06 2003
Because typesafe varargs is useful for lots of things besides I/O. Sean "Patrick Down" <Patrick_member pathlink.com> wrote in message news:boe5fs$18se$1 digitaldaemon.com...Why not make IO a more formal operation. Introduce a new keyword "write" Syntax: write object, param [,param]*;
Nov 09 2003
"Walter" <walter digitalmars.com> wrote in message
news:boc9me$1g2b$1 digitaldaemon.com...
| ...
| stdout("hello")(" world")(47).nl()("bar")("%06i\n", 62);
| ...
Personally, I don't like so many (). ~ feels a bit better. However, I agree
that true typesafe varargs would be the ideal solution for this.
Carlos Santander
---
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.536 / Virus Database: 331 - Release Date: 2003-11-03
Nov 06 2003
This all doesn't help me, to output objects of my own classes, does it?
Nov 16 2003
Walter wrote:(Note that it retains the power of printf!) The issue here is how the syntax stdout("foo")("bar") looks. In C++ it would look like stdout<<"foo"<<"bar" which I don't find appealing.
stdout << "foo" << "bar"; Does indeed not loop very appealing. I personally would have liked better: stdout << "foo", "bar", i, "\n", "second line", nl; Jan
Nov 16 2003









"Jan-Eric Duden" <jeduden whisset.com> 