D - Variable arguments: opStream
- Vathix (24/24) Apr 17 2004 Operators << and >> are for shifting, overloading opCall("like")("this")...
- Patrick Down (5/8) Apr 17 2004 This is like the proposal I had for opWrite and opRead a while back.
- John Reimer (3/30) Apr 17 2004 I must admit that something along the lines of your opStream example doe...
- h3r3tic (2/2) Apr 17 2004 i like this idea, it reminds me of the Amos language :)
- Manfred Nowak (9/10) Apr 18 2004 [...]
- Vathix (10/26) Apr 18 2004 I have proposed many ideas here for type safe variable arguments; this
- Manfred Nowak (7/9) Apr 18 2004 [...]
- Mike (11/18) Apr 19 2004 I'm a C++ programmer interested in switching to D, however I dislike not...
- Mike (25/25) Apr 19 2004 After thinking a bit about it I came up with an extended solution. No op...
- John Reimer (8/24) Apr 19 2004 << and >> are not out of the question, just likely not preferred by some...
- John Reimer (1/9) Apr 19 2004 Argh! I meant www.dsource.org, of course.
- Ivan Senji (7/31) Apr 19 2004 having
- John Reimer (5/9) Apr 19 2004 Are we talking about a different implementation? I'm just saying that
- John Reimer (2/15) Apr 19 2004 Sorry, where x and y are int or some other numerical type.
- Ivan Senji (9/24) Apr 19 2004 I have also written a class that can be used like that (i will have to c...
- Mike (10/10) Apr 19 2004 Hmm ... I thought it would be out of discussion because in D things like...
- John Reimer (13/27) Apr 19 2004 Hey Mike,
- Ben Hinkle (21/43) Apr 18 2004 Instead of calling these ideas "type safe variable arguments" I think it...
- Vathix (11/48) Apr 18 2004 All right, good point.
- Ben Hinkle (8/16) Apr 19 2004 Ack - I didn't mean to imply your idea was a bad one. I just don't think...
- Manfred Nowak (46/56) Apr 18 2004 [...]
- Scott Egan (7/31) Apr 19 2004 I know I'm going to get shot for this but...
Operators << and >> are for shifting, overloading opCall("like")("this") is ugly to me :P and hard to type. So I have yet another idea for type-safe variable arguments. Here's the idea in code: class Foo { char[] buf; void opStream(char[] x) { buf ~= x; } void opStream(char x) { buf ~= x; } void opStream(Object o) { buf ~= o.toString(); } char[] toString() { return buf; } } int main() { Foo foo; foo$("this calls", " opStream for", " each parameter", '\n'); printf("Foo = '%.*s'\n", foo.toString()); return 0; } I just threw in the symbol $ so it doesn't conflict with opCall and so you can better understand what it's doing. opStream always has void return type and exactly one parameter. For input streams you could use out parameters. -- Christopher E. Miller
Apr 17 2004
Vathix <vathix dprogramming.com> wrote in news:c5rhae$1eek$1 digitaldaemon.com:Operators << and >> are for shifting, overloading opCall("like")("this") is ugly to me :P and hard to type. So I have yet another idea for type-safe variable arguments.This is like the proposal I had for opWrite and opRead a while back. In general I like the idea. http://www.digitalmars.com/drn-bin/wwwnews?D/19072
Apr 17 2004
On Sat, 17 Apr 2004 11:09:04 -0400, Vathix wrote:Operators << and >> are for shifting, overloading opCall("like")("this") is ugly to me :P and hard to type. So I have yet another idea for type-safe variable arguments. Here's the idea in code: class Foo { char[] buf; void opStream(char[] x) { buf ~= x; } void opStream(char x) { buf ~= x; } void opStream(Object o) { buf ~= o.toString(); } char[] toString() { return buf; } } } int main() { Foo foo; foo$("this calls", " opStream for", " each parameter", '\n'); printf("Foo = '%.*s'\n", foo.toString()); return 0; } } I just threw in the symbol $ so it doesn't conflict with opCall and so you can better understand what it's doing. opStream always has void return type and exactly one parameter. For input streams you could use out parameters.I must admit that something along the lines of your opStream example does look desirable.
Apr 17 2004
i like this idea, it reminds me of the Amos language :) u have my vote ;)
Apr 17 2004
Vathix wrote:So I have yet another idea for type-safe variable arguments.[...] This is not "another idea". You just specialized for streams my general proposal: pre- or postprocessing not possible; only one state in the declaration stage, therefore the next state implicitely denoted by void type; opCall renamed to opStream; at the call stage `,' instead of `;'. Would you please explain, why it would be good, to have another syntax extension for every special case that may arise? So long!
Apr 18 2004
Manfred Nowak wrote:Vathix wrote:I have proposed many ideas here for type safe variable arguments; this is another one. I called it opStream because most (all?) cases where you want variable arguments is to stream data into an object. I am proposing a friendlier syntax, because foo("this is")(" using opCall")(" and doesn't")(" look")(" too pretty"), and the C++ method of using << and >> is out of the question. I don't stand by my proposals 100%, I just say what is interesting to me and hope it is inspiring to improve anything. -- Christopher E. MillerSo I have yet another idea for type-safe variable arguments.[...] This is not "another idea". You just specialized for streams my general proposal: pre- or postprocessing not possible; only one state in the declaration stage, therefore the next state implicitely denoted by void type; opCall renamed to opStream; at the call stage `,' instead of `;'. Would you please explain, why it would be good, to have another syntax extension for every special case that may arise? So long!
Apr 18 2004
Vathix wrote: [...]I am proposing a friendlier syntax, because foo("this is")(" using opCall") (" and doesn't")(" look")(" too pretty")[...] Agreed. However: foo("this is"; " using opCall"; " and doesn't"; "look"; " too pretty") is not lookimg that bad. So long!
Apr 18 2004
Hi!I have proposed many ideas here for type safe variable arguments; this is another one. I called it opStream because most (all?) cases where you want variable arguments is to stream data into an object. I am proposing a friendlier syntax, because foo("this is")(" using opCall")(" and doesn't")(" look")(" too pretty"), and the C++ method of using << and >> is out of the question. I don't stand by my proposals 100%, I just say what is interesting to me and hope it is inspiring to improve anything.I'm a C++ programmer interested in switching to D, however I dislike not having cin and cout in D. I understand that the << and >> operators are out of question, but since D eliminated the need for a -> operator couldn't you just use <- and -> for streaming? int i; cin -> i; cout <- "i is " <- i <- endl; That would call cin.opStreamIn and cout.opStreamOut ... bad idea? -Mike
Apr 19 2004
After thinking a bit about it I came up with an extended solution. No opStream, but a new keyword ("streaming" or "multi" or whatever): class bar { /* The "streaming" keyword (or "multi" or whatever) declares a property as "streamable" */ streaming void foo1(int i) { /* ... */ } streaming void foo1(char c) { /* ... */} streaming void foo2(int i) { /* ... */} streaming void foo2(char c) { /* ... */} streaming int foo1() { return /* ... */} streaming char foo1() { return /* ... */} streaming int foo2() { return /* ... */} streaming char foo2() { return /* ... */} /* ... */ } Later on: bar b; int i = 3; char c = 'a' b.foo1 <- i <- c; // calls void bar.foo1(i) and void bar.foo1(c) b.foo2 -> i -> c; // calls int bar.foo2() and char bar.foo2() Maybe you find that plausible in some way or the other, but I think that wouldn't be too bad :-) -Mike
Apr 19 2004
I'm a C++ programmer interested in switching to D, however I dislike not having cin and cout in D. I understand that the << and >> operators are out of question, but since D eliminated the need for a -> operator couldn't you just use <- and -> for streaming? int i; cin -> i; cout <- "i is " <- i <- endl; That would call cin.opStreamIn and cout.opStreamOut ... bad idea? -Mike<< and >> are not out of the question, just likely not preferred by some programmers (probably the reason this discussion doesn't explore them: they're looking for a better way). The DSC.io project provides these C++-style stream operators as well as a different variation. It's the programmers choice as to which to use in an application. This very nicely implemented library is being discussed at www.dscource.org, and I believe is close to beta access so that others can play with it (I'm really, really hoping ;-) ).
Apr 19 2004
<< and >> are not out of the question, just likely not preferred by some programmers (probably the reason this discussion doesn't explore them: they're looking for a better way). The DSC.io project provides these C++-style stream operators as well as a different variation. It's the programmers choice as to which to use in an application. This very nicely implemented library is being discussed at www.dscource.org, and I believe is close to beta access so that others can play with it (I'm really, really hoping ;-) ).Argh! I meant www.dsource.org, of course.
Apr 19 2004
"John Reimer" <jjreimer telus.net> wrote in message news:c6137v$vh9$1 digitaldaemon.com...havingI'm a C++ programmer interested in switching to D, however I dislike notDcin and cout in D. I understand that the << and >> operators are out of question, but sinceforeliminated the need for a -> operator couldn't you just use <- and ->Yes they are (unfortunatelly) out of the questions because the order of chained << or >> isn't defined :(streaming? int i; cin -> i; cout <- "i is " <- i <- endl; That would call cin.opStreamIn and cout.opStreamOut ... bad idea? -Mike<< and >> are not out of the question, just likely not preferred by someprogrammers (probably the reason this discussion doesn't explore them: they're looking for a better way). The DSC.io project provides these C++-style stream operators as well as a different variation. It's the programmers choice as to which to use in an application. This very nicely implemented library is being discussed at www.dscource.org, and I believe is close to beta access so that others can play with it (I'm really, really hoping ;-) ).
Apr 19 2004
Yes they are (unfortunatelly) out of the questions because the order of chained << or >> isn't defined :(Are we talking about a different implementation? I'm just saying that it must be possible to do in D. Kris's DSC.io library does this Stdout << x << "this is a test" << y << Stdout.newline; ... and it works flawlessly. Am I missing something?
Apr 19 2004
John Reimer wrote:Sorry, where x and y are int or some other numerical type.Yes they are (unfortunatelly) out of the questions because the order of chained << or >> isn't defined :(Are we talking about a different implementation? I'm just saying that it must be possible to do in D. Kris's DSC.io library does this Stdout << x << "this is a test" << y << Stdout.newline; ... and it works flawlessly. Am I missing something?
Apr 19 2004
"John Reimer" <jjreimer telus.net> wrote in message news:c616ir$16o5$2 digitaldaemon.com...John Reimer wrote:I have also written a class that can be used like that (i will have to check it out to see how it works for classes) But the problem is that someone on this newsgroup said that the order of execution of chained << is implementation specific and code shouldn't be written that depends on this order. I'm not sure if this is true but it is what i read!Sorry, where x and y are int or some other numerical type.Yes they are (unfortunatelly) out of the questions because the order of chained << or >> isn't defined :(Are we talking about a different implementation? I'm just saying that it must be possible to do in D. Kris's DSC.io library does this Stdout << x << "this is a test" << y << Stdout.newline; ... and it works flawlessly. Am I missing something?
Apr 19 2004
Hmm ... I thought it would be out of discussion because in D things like having the << operator working as streaming AND shifting operator should be avoided. Therefore I thought using <- and -> could be a good idea. Introducing new operators with defined behaviour wouldn't be that bad. Anyway, after being a lurker here for a couple of weeks and being interested in D I just wanted to express my wish for something similar to cin/cout in D - I'll have a look at the classes on dsource. You know, I'd certainly like to get rid of that stupid printf once and for all, really :-) Good night, -Mike
Apr 19 2004
Mike wrote:Hmm ... I thought it would be out of discussion because in D things like having the << operator working as streaming AND shifting operator should be avoided. Therefore I thought using <- and -> could be a good idea. Introducing new operators with defined behaviour wouldn't be that bad. Anyway, after being a lurker here for a couple of weeks and being interested in D I just wanted to express my wish for something similar to cin/cout in D - I'll have a look at the classes on dsource. You know, I'd certainly like to get rid of that stupid printf once and for all, really :-) Good night, -MikeHey Mike, I brought it up because I realize that some programmers seem to have a real bond with the << and >> operators for stream use, especially when they come from C++ (I can't stand this use of shift operators myself). DSC.io allows use of them on both linux and windows. The library also provides an alternative method that I prefer. The other method is basically a form of multiple function calls. You'll have to see it. These methods could likely be improved upon, but it's nice just to know that we have something other than printf and <<, >>. There is not much documentation for the project yet other than in-source comments and sample unittest code which sufficient for the most part. The author, Kris, is getting ready to release the source at www.dsource.org soon.
Apr 19 2004
Vathix wrote:Operators << and >> are for shifting, overloading opCall("like")("this") is ugly to me :P and hard to type. So I have yet another idea for type-safe variable arguments. Here's the idea in code: class Foo { char[] buf; void opStream(char[] x) { buf ~= x; } void opStream(char x) { buf ~= x; } void opStream(Object o) { buf ~= o.toString(); } char[] toString() { return buf; } } int main() { Foo foo; foo$("this calls", " opStream for", " each parameter", '\n'); printf("Foo = '%.*s'\n", foo.toString()); return 0; }Instead of calling these ideas "type safe variable arguments" I think it should be called something like "syntactic sugar for multiple function calls". Manfred's idea of using ";" was similar and it took me forever to realize he wasn't talking about arguments to one function call - he was talking about making multiple function calls. This is quite different from variable arguments using a single function call and I'd expect C/C++ users to see something that looks like a regular function call and expect it to behave like a regular function call. The concept of "varargs" or "variable arguments" has always been applied to a single function call so we should keep it that way. These ideas have been bouncing around at least since Walter's original opCall input/output idea: http://www.digitalmars.com/drn-bin/wwwnews?D/18945 I'm sure you're aware of the history since you mention opCall but not everyone might know what motivates these proposals. -Ben ps - the posting I made a while back http://www.digitalmars.com/drn-bin/wwwnews?D/26932 was what I thought Manfred was talking about with "type-safe variable arguments" since it allows vararg style calls with type checking.
Apr 18 2004
Ben Hinkle wrote:Vathix wrote:All right, good point. So foo("hello"; " world"); would be at least foo("hello"); foo(" world"); I like it.. Sorry about my post. -- Christopher E. MillerOperators << and >> are for shifting, overloading opCall("like")("this") is ugly to me :P and hard to type. So I have yet another idea for type-safe variable arguments. Here's the idea in code: class Foo { char[] buf; void opStream(char[] x) { buf ~= x; } void opStream(char x) { buf ~= x; } void opStream(Object o) { buf ~= o.toString(); } char[] toString() { return buf; } } int main() { Foo foo; foo$("this calls", " opStream for", " each parameter", '\n'); printf("Foo = '%.*s'\n", foo.toString()); return 0; }Instead of calling these ideas "type safe variable arguments" I think it should be called something like "syntactic sugar for multiple function calls". Manfred's idea of using ";" was similar and it took me forever to realize he wasn't talking about arguments to one function call - he was talking about making multiple function calls. This is quite different from variable arguments using a single function call and I'd expect C/C++ users to see something that looks like a regular function call and expect it to behave like a regular function call. The concept of "varargs" or "variable arguments" has always been applied to a single function call so we should keep it that way.
Apr 18 2004
All right, good point. So foo("hello"; " world"); would be at least foo("hello"); foo(" world"); I like it.. Sorry about my post.Ack - I didn't mean to imply your idea was a bad one. I just don't think it should be called "variable arguments". Whether a semi-colon or $ or something else is used is somewhat secondary. Heck, back in Walter's original thread there were probably other suggestions - well, those who read closely can find I suggested the syntax foo[a,b,c] http://www.digitalmars.com/drn-bin/wwwnews?D/19001 So you see I think the general idea is just swell. -Ben
Apr 19 2004
Ben Hinkle wrote: [...]This is quite different from variable arguments using a single function call[...] I do not see the difference you are proposing here. If the details of the declaration of such a, lets call it "variadic object", are hidden it would become indistinguishable from a function. I do not see a need to keep up the feeling of "variadic objects" must be functions. I already gave a _working_ example of a generic "variadic object" of a list that is able to adapt to every codable type. None of the proposals I have seen so far has even proposed to be able to do that. Furthermore: by changing the states of a "variadic object" from structs to classes it seems possible to "derive" "variadic objects" from given ones, thereby expanding the language that is accepted by such a "derived variadic object". How does this fit into the feeling of a function? By hiding the details of a declaration I mean something like: variadic( ( T1, T2)*:R ){ R result; // declarations // preprocess switch{ // only one state needed in this special case case T1 p1: // declarations // do something with p1 and result case T2 p2: // declarations // do something else with p2 and result } // postprocess return R; } At the call side: T1 ap1, ap3; T2 ap2; R res; // prepare the call res= variadic( ap1, ap2, ap3); Now please explain why you still consider this as multiple function calls.These ideas have been bouncing around at least since Walter's original opCall input/output idea: http://www.digitalmars.com/drn-bin/wwwnews?D/18945 I'm sure you're aware of the history since you mention opCall but not everyone might know what motivates these proposals.Thanks! That was some weeks before I started digging into D. I therefore did not notice, that Walter has already laid out the playgrounds of such _packaged_ opCalls and I am somehow reinventing a wheel. Please note, that in the example given above it is very well possible to nest the calls of the "variadic object" provided, that the return types are assigned properly: res= variadic( ap1, variadic( ap2, ap3), ap4);ps - the posting I made a while back http://www.digitalmars.com/drn-bin/wwwnews?D/26932 was what I thought Manfred was talking about with "type-safe variable arguments" since it allows vararg style calls with type checking.Commented on it. So long!
Apr 18 2004
I know I'm going to get shot for this but... Why don't we just byte the bullet and allow the opCat to be used, eg steram.writeLine("Fred was here in: " ~ date ~ ". He has been here " ~ n ~ " times before."); Don't hit me too hard. "Vathix" <vathix dprogramming.com> wrote in message news:c5rhae$1eek$1 digitaldaemon.com...Operators << and >> are for shifting, overloading opCall("like")("this") is ugly to me :P and hard to type. So I have yet another idea for type-safe variable arguments. Here's the idea in code: class Foo { char[] buf; void opStream(char[] x) { buf ~= x; } void opStream(char x) { buf ~= x; } void opStream(Object o) { buf ~= o.toString(); } char[] toString() { return buf; } } int main() { Foo foo; foo$("this calls", " opStream for", " each parameter", '\n'); printf("Foo = '%.*s'\n", foo.toString()); return 0; } I just threw in the symbol $ so it doesn't conflict with opCall and so you can better understand what it's doing. opStream always has void return type and exactly one parameter. For input streams you could use out parameters. -- Christopher E. Miller
Apr 19 2004