Thread overview
Possible solution for D's I/O system
Mar 02, 2004
Andrew Edwards
Mar 02, 2004
Charles Hixson
Mar 03, 2004
Stewart Gordon
March 02, 2004
Gentlemen, please provide some comments on the following.

bit echo(sequence)
{
foreach(morph; sequence)
{
switch(morph.type) // Typename
{
case "int"   : // process int
case "char[]": // process char[]
[...]
case "UDT"   : // how on earth would one process this?
default:
throw UndefinedTypeError;
}
}
}

echo() is one of four functions in an I/O system designed to
replace the current I/O system of D. It is responsible for
outputting information to stdout (monitor). The remaining
functions are:

bit scan(...);  // reads input from stdin (keyboard)
bit read(...);  // reads input from files and other streams
bit write(...); // outputs info to files and other streams

It's return type is bit (aka bool), and indicates failure or
success. It accepts a variable number of arguments via the
sequence (...) perameter. When called without an argument
it should output '\n'.

sequence is an array of arguments much like the infamous char[][] args; however, it accepts any and all types.

Much like a void*, morph is a pointer that points to objects
of any type. It should be self-dereferencing and may be confined
for use only in conjunction with sequence. Additionally, it
should inherit all characteristics of the object to which it
points.  (Can this be done?)

UDTs must have a built-in output{} and input{} facility that provide information on how to process I/O for said type. Without such a facility, the above I/O functions will all throw an UndefinedTypeError.

Forgive me if my neophyte brain has left my thought process somewhat convoluted.

Any comments on the feasability of this suggestion, to include how to improve upon or depicting possible flaws in it would be appreciated.

Thanks,
Andrew


March 02, 2004
Andrew Edwards wrote:
> Gentlemen, please provide some comments on the following.
> 
> bit echo(sequence)
> {
> foreach(morph; sequence)
> {
> switch(morph.type) // Typename
> {
> case "int"   : // process int
> case "char[]": // process char[]
> [...]
> case "UDT"   : // how on earth would one process this?
> default:
> throw UndefinedTypeError;
> }
> }
> }
> 
> echo() is one of four functions in an I/O system designed to
> replace the current I/O system of D. It is responsible for
> outputting information to stdout (monitor). The remaining
> functions are:
> 
> bit scan(...);  // reads input from stdin (keyboard)
> bit read(...);  // reads input from files and other streams
> bit write(...); // outputs info to files and other streams
> 
> It's return type is bit (aka bool), and indicates failure or
> success. It accepts a variable number of arguments via the
> sequence (...) perameter. When called without an argument
> it should output '\n'.
> 
> sequence is an array of arguments much like the infamous
> char[][] args; however, it accepts any and all types.
> 
> Much like a void*, morph is a pointer that points to objects
> of any type. It should be self-dereferencing and may be confined
> for use only in conjunction with sequence. Additionally, it
> should inherit all characteristics of the object to which it
> points.  (Can this be done?)
> 
> UDTs must have a built-in output{} and input{} facility that
> provide information on how to process I/O for said type. Without
> such a facility, the above I/O functions will all throw an
> UndefinedTypeError.
> 
> Forgive me if my neophyte brain has left my thought process
> somewhat convoluted.
> 
> Any comments on the feasability of this suggestion, to include
> how to improve upon or depicting possible flaws in it would be
> appreciated.
> 
> Thanks,
> Andrew
> 
> 
1) generally my feeling is that Object should have a built-in method for output to a sequential file, with stdout being the default.
2) formatting of the output is very important, but this is best specified via a string.  Partially because every class will probably implement a different default output format.
3) it would be best if there were a mechanism for specifying multiple default output formats, e.g., columnar, justified, tab delimited, XML, etc.  I'm not sure the best way to handle this.
4) int_s, etc., need to be able to fit into the normal output chain.
5) Is defining a new class really the best way to handle a new output format?  It seems like there should be a better one, but just what isn't clear.

Class variables make things a lot more complicated than what printf was designed to handle.  This doesn't mean that we've designed any better way.  But I really doubt that any global function will be able to do much better than a method of Object would.

Perhaps there need to be classes like XMLString and HTMLString that have methods designed to allow one to append appropriately formatted output?

March 03, 2004
Andrew Edwards wrote:

> Gentlemen, please provide some comments on the following.
> 
> bit echo(sequence)
> {
> foreach(morph; sequence)
> {
> switch(morph.type) // Typename
> {
> case "int"   : // process int
> case "char[]": // process char[]
> [...]
> case "UDT"   : // how on earth would one process this?
> default:
> throw UndefinedTypeError;
> }
> }
> }

I'm not sure I'd agree with this.  It relies on an ad-hoc, still not exactly typesafe I guess, system of variable argument lists, which in turn relies on the invention of a variant type.

> echo() is one of four functions in an I/O system designed to
> replace the current I/O system of D. It is responsible for
> outputting information to stdout (monitor). The remaining
> functions are:
> 
> bit scan(...);  // reads input from stdin (keyboard)
> bit read(...);  // reads input from files and other streams
> bit write(...); // outputs info to files and other streams
> 
> It's return type is bit (aka bool), and indicates failure or
> success.

We should use exceptions for failure.  That's what they're there for.

<snip>
> UDTs must have a built-in output{} and input{} facility that
> provide information on how to process I/O for said type. Without
> such a facility, the above I/O functions will all throw an
> UndefinedTypeError.
<snip>

Either that or just use toString for output.  Isn't that what toString's there for?

The only really fitting means I can see for formatted output is to define a function that takes the data and returns a formatted string. All we need is some built-in functions for common numeric formats, and we'll have this pretty much done.

Maybe we should invent a new operator for std.stream.Stream, similar to << in C++.  It would write a string exactly, use a default decimal format for numeric types and toString for UDTs.  Of course it would chain as in C++, keeping to the "simple operations should be simple" rule, for situations where defining a format function is overkill or you want to write several formatted records together.

Maybe ~~ or something.  It would be similar to ~ and ~=, which it slightly resembles in function.  But is it likely that anyone's yet used qwert~~yuiop to mean qwert concatenated with the one's complement of yuiop?

Then the only things left to consider are:
- the input counterpart
- supporting Unicode

On second thoughts, maybe ~< for output and ~> for input.  (I suppose the only advantage over << and >> is that there are no pre-existing semantics to bend, and hence no potential for ugly/confusing mixing of two meanings of the same binop.)  As long as < and > don't exist as prefix operators, and ~ doesn't exist as a postfix operator, there's no possible ambiguity.

Stewart.

-- 
My e-mail is valid but not my primary mailbox, aside from its being the unfortunate victim of intensive mail-bombing at the moment.  Please keep replies on the 'group where everyone may benefit.