November 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't

> I can see tilde being confused with the array concatenation operator.

Indeed. That is one of the objections to it

> Parens 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 thread

> Commas are confusing too because of the comma operator that C,C++, and D
all
> share.

Agreed



November 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


November 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
>>>
>>>http://www.digitalmars.com/drn-bin/wwwnews?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).
> 
> 

November 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.

November 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
(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.

Fair enough. My ineptly using printf as an example does not negate the point, however.



November 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
> 
> (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.
> 
> 
> 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);

November 06, 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
(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.

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


November 07, 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.


November 07, 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 ()
be
> a parameter list rather than a parenthesized expression.
>
>


November 07, 2003
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