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

November 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


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


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


November 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

"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
syntax
> stdout("foo")("bar") looks. In C++ it would look like stdout<<"foo"<<"bar"
> which I don't find appealing.
>
>


November 06, 2003
Something like this will work:
November 06, 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

November 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

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