www.digitalmars.com         C & C++   DMDScript  

D - phobos.streams beauty? completeness?

reply Helmut Leitner <leitner hls.via.at> writes:
You'll find:

	// read a single value of desired type,
	// throw ReadError on error
	void read(out byte x) { readExact(&x, x.size); }
	void read(out ubyte x) { readExact(&x, x.size); }
	void read(out short x) { readExact(&x, x.size); }
	void read(out ushort x) { readExact(&x, x.size); }
	void read(out int x) { readExact(&x, x.size); }
	void read(out uint x) { readExact(&x, x.size); }
	void read(out long x) { readExact(&x, x.size); }
	void read(out ulong x) { readExact(&x, x.size); }
	void read(out float x) { readExact(&x, x.size); }
	void read(out double x) { readExact(&x, x.size); }
	void read(out real x) { readExact(&x, x.size); }
	void read(out ireal x) { readExact(&x, x.size); }
	void read(out creal x) { readExact(&x, x.size); }
	void read(out char x) { readExact(&x, x.size); }
	void read(out wchar x) { readExact(&x, x.size); }
	
which is 

  - neiter complete (ifloat, idouble, cfloat, cdouble)
  - nor beautiful (deja vu to Java's Arrays module, IIRC)

Isn't there a way around this? So that any primitive that defines
(or knows about) a transformation to something like
   
   struct mem {
       void *p;
       int size;
   }

could match with a

   void read(out mem) { readExact(mem.p,mem.size); }

?





-- 
Helmut Leitner    leitner hls.via.at
Graz, Austria   www.hls-software.com
Apr 10 2003
parent reply Ilya Minkov <midiclub tiscali.de> writes:
How about a template?
In C++ you would do it this way. In D it would require an explicit 
instantiation.

In C you would use a macro.

Why don't all those "read"s return anything? I feel that this is wrong 
and they should use a return value instead of an out value. You need a 
variable to consume a out value, but to consume a return you only need 
some expression to stick it into, so that the code would be more terse.

BTW, is there any way to suppress out parameters instead of giving them 
throw-away variables? how about a new keyword "discard"?

So that you could say something like:
sillyFunction(1, 2, b, discard);

this could also be accomplished with:
sillyFunction(1, 2, b, void);

Another use would be do discard unused return values, which cannot be 
done with void due to parsing ambiguity:
discard doSomething(thisway); //return value not consumed.

cast(void) is simply more lengthy and less verbose than discard.

There would be an error or a warning if one tries to use a function 
somewhere without using its return value, unless one discards it explicitly.

-i.

Helmut Leitner wrote:
 You'll find:
 
 	// read a single value of desired type,
 	// throw ReadError on error
 	void read(out byte x) { readExact(&x, x.size); }
 	void read(out ubyte x) { readExact(&x, x.size); }
 	void read(out short x) { readExact(&x, x.size); }
 	void read(out ushort x) { readExact(&x, x.size); }
 	void read(out int x) { readExact(&x, x.size); }
 	void read(out uint x) { readExact(&x, x.size); }
 	void read(out long x) { readExact(&x, x.size); }
 	void read(out ulong x) { readExact(&x, x.size); }
 	void read(out float x) { readExact(&x, x.size); }
 	void read(out double x) { readExact(&x, x.size); }
 	void read(out real x) { readExact(&x, x.size); }
 	void read(out ireal x) { readExact(&x, x.size); }
 	void read(out creal x) { readExact(&x, x.size); }
 	void read(out char x) { readExact(&x, x.size); }
 	void read(out wchar x) { readExact(&x, x.size); }
 	
 which is 
 
   - neiter complete (ifloat, idouble, cfloat, cdouble)
   - nor beautiful (deja vu to Java's Arrays module, IIRC)
 
 Isn't there a way around this? So that any primitive that defines
 (or knows about) a transformation to something like
    
    struct mem {
        void *p;
        int size;
    }
 
 could match with a
 
    void read(out mem) { readExact(mem.p,mem.size); }
 
 ?
 
 

Apr 10 2003
parent "Matthew Wilson" <dmd synesis.com.au> writes:
 BTW, is there any way to suppress out parameters instead of giving them
 throw-away variables? how about a new keyword "discard"?

If callers are discarding out parameters, then the functions have not been designed well. The overloads are there precisely because they are overloads. How would a template function work out which to call, if the options were readInt(), readDouble(), etc. It is probably necessary, but I agree with the painful aspects of having to have a variable. Maybe the solution is to provide both? (All it costs is a few more bytes of code, no runtime hit) "Ilya Minkov" <midiclub tiscali.de> wrote in message news:b73gn8$29oe$1 digitaldaemon.com...
 How about a template?
 In C++ you would do it this way. In D it would require an explicit
 instantiation.

 In C you would use a macro.

 Why don't all those "read"s return anything? I feel that this is wrong
 and they should use a return value instead of an out value. You need a
 variable to consume a out value, but to consume a return you only need
 some expression to stick it into, so that the code would be more terse.

 BTW, is there any way to suppress out parameters instead of giving them
 throw-away variables? how about a new keyword "discard"?

 So that you could say something like:
 sillyFunction(1, 2, b, discard);

 this could also be accomplished with:
 sillyFunction(1, 2, b, void);

 Another use would be do discard unused return values, which cannot be
 done with void due to parsing ambiguity:
 discard doSomething(thisway); //return value not consumed.

 cast(void) is simply more lengthy and less verbose than discard.

 There would be an error or a warning if one tries to use a function
 somewhere without using its return value, unless one discards it

 -i.

 Helmut Leitner wrote:
 You'll find:

 // read a single value of desired type,
 // throw ReadError on error
 void read(out byte x) { readExact(&x, x.size); }
 void read(out ubyte x) { readExact(&x, x.size); }
 void read(out short x) { readExact(&x, x.size); }
 void read(out ushort x) { readExact(&x, x.size); }
 void read(out int x) { readExact(&x, x.size); }
 void read(out uint x) { readExact(&x, x.size); }
 void read(out long x) { readExact(&x, x.size); }
 void read(out ulong x) { readExact(&x, x.size); }
 void read(out float x) { readExact(&x, x.size); }
 void read(out double x) { readExact(&x, x.size); }
 void read(out real x) { readExact(&x, x.size); }
 void read(out ireal x) { readExact(&x, x.size); }
 void read(out creal x) { readExact(&x, x.size); }
 void read(out char x) { readExact(&x, x.size); }
 void read(out wchar x) { readExact(&x, x.size); }

 which is

   - neiter complete (ifloat, idouble, cfloat, cdouble)
   - nor beautiful (deja vu to Java's Arrays module, IIRC)

 Isn't there a way around this? So that any primitive that defines
 (or knows about) a transformation to something like

    struct mem {
        void *p;
        int size;
    }

 could match with a

    void read(out mem) { readExact(mem.p,mem.size); }

 ?


Apr 10 2003