www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - void returns

reply Benedikt Meurer <benedikt.meurer unix-ag.uni-siegen.de> writes:
Hello,

Would it be possible to add support for void returns, as in

void f1 () { ... }
void f2 () { ...; return f1 (); }

to D? This would be invaluably helpful in template programming. Else one has 
to either make heavy use of mixins or write a lot of specialisations.

(Looking at the code, it seems, that only dmd/statement.c has to be modified 
to archive this goal).

regards,
Benedikt

--
NetBSD Operating system:                       http://www.NetBSD.org/
pkgsrc "Work in progress":                  http://pkgsrc-wip.sf.net/
XFce desktop environment:                        http://www.xfce.org/
German Unix-AG Association:                   http://www.unix-ag.org/
os-network:                                 http://www.os-network.de/

OpenPGP Key: http://www.home.unix-ag.org/bmeurer/#gpg
May 22 2004
next sibling parent reply J C Calvarese <jcc7 cox.net> writes:
Benedikt Meurer wrote:
 Hello,
 
 Would it be possible to add support for void returns, as in
 
 void f1 () { ... }
 void f2 () { ...; return f1 (); }
 
 to D? This would be invaluably helpful in template programming. Else one 
 has to either make heavy use of mixins or write a lot of specialisations.
 
 (Looking at the code, it seems, that only dmd/statement.c has to be 
 modified to archive this goal).
 
 regards,
 Benedikt

In D, void means the function doesn't return a value. But that doesn't prevent you from calling another function. I'm not sure I understand what your goal is. You can already do this: void f1() { printf("Running f1...\n"); } void f2() { bit itsAGoodIdea = true; printf("Running f2...\n"); if(itsAGoodIdea) { f1(); return; } printf("Don't go there.\n"); } void main() { f2(); printf("The end.\n"); } /* Output: Running f2... Running f1... The end. */
 
 -- 
 NetBSD Operating system:                       http://www.NetBSD.org/
 pkgsrc "Work in progress":                  http://pkgsrc-wip.sf.net/
 XFce desktop environment:                        http://www.xfce.org/
 German Unix-AG Association:                   http://www.unix-ag.org/
 os-network:                                 http://www.os-network.de/
 
 OpenPGP Key: http://www.home.unix-ag.org/bmeurer/#gpg

-- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/
May 22 2004
parent reply Andy Friesen <andy ikagames.com> writes:
J C Calvarese wrote:
 In D, void means the function doesn't return a value. But that doesn't 
 prevent you from calling another function. I'm not sure I understand 
 what your goal is. 

Right. He's referring to syntactically allowing 'void' to be returned. void f1() { } void f2() { return f1(); } f1 has no return value, and neither does f2, so it... sort of, makes sense. The big reason to allow it is because the return type may be parameterized: template t(T) { T f1() { ... } T f2() { return f1(); } } If void can be returned, T can be void, in this example. -- andy
May 22 2004
parent J C Calvarese <jcc7 cox.net> writes:
Andy Friesen wrote:
 J C Calvarese wrote:
 
 In D, void means the function doesn't return a value. But that doesn't 
 prevent you from calling another function. I'm not sure I understand 
 what your goal is. 

Right. He's referring to syntactically allowing 'void' to be returned. void f1() { } void f2() { return f1(); } f1 has no return value, and neither does f2, so it... sort of, makes sense. The big reason to allow it is because the return type may be parameterized: template t(T) { T f1() { ... } T f2() { return f1(); } } If void can be returned, T can be void, in this example. -- andy

Oops. Somehow I missed his reference to templates (perhaps my eyes started to glaze after after I saw his example). Sounds like a good idea since it'd help templatization. -- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/
May 22 2004
prev sibling next sibling parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
Ah, something I've always wanted in C++...

I echo the request.

"Benedikt Meurer" <benedikt.meurer unix-ag.uni-siegen.de> wrote in message
news:c8o52s$1j0l$1 digitaldaemon.com...
 Hello,

 Would it be possible to add support for void returns, as in

 void f1 () { ... }
 void f2 () { ...; return f1 (); }

 to D? This would be invaluably helpful in template programming. Else one has
 to either make heavy use of mixins or write a lot of specialisations.

 (Looking at the code, it seems, that only dmd/statement.c has to be modified
 to archive this goal).

 regards,
 Benedikt

 --
 NetBSD Operating system:                       http://www.NetBSD.org/
 pkgsrc "Work in progress":                  http://pkgsrc-wip.sf.net/
 XFce desktop environment:                        http://www.xfce.org/
 German Unix-AG Association:                   http://www.unix-ag.org/
 os-network:                                 http://www.os-network.de/

 OpenPGP Key: http://www.home.unix-ag.org/bmeurer/#gpg

May 22 2004
parent reply "davepermen" <davepermen hotmail.com> writes:
works in c++...

should be working in D, too, indeed.

"Matthew" <matthew.hat stlsoft.dot.org> schrieb im Newsbeitrag
news:c8okjt$28o9$1 digitaldaemon.com...
 Ah, something I've always wanted in C++...

 I echo the request.

 "Benedikt Meurer" <benedikt.meurer unix-ag.uni-siegen.de> wrote in message
 news:c8o52s$1j0l$1 digitaldaemon.com...
 Hello,

 Would it be possible to add support for void returns, as in

 void f1 () { ... }
 void f2 () { ...; return f1 (); }

 to D? This would be invaluably helpful in template programming. Else one


 to either make heavy use of mixins or write a lot of specialisations.

 (Looking at the code, it seems, that only dmd/statement.c has to be


 to archive this goal).

 regards,
 Benedikt

 --
 NetBSD Operating system:                       http://www.NetBSD.org/
 pkgsrc "Work in progress":                  http://pkgsrc-wip.sf.net/
 XFce desktop environment:                        http://www.xfce.org/
 German Unix-AG Association:                   http://www.unix-ag.org/
 os-network:                                 http://www.os-network.de/

 OpenPGP Key: http://www.home.unix-ag.org/bmeurer/#gpg


May 22 2004
parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
Yes, but it's a relatively late addition, and several recent or still in use
compilers don't support it, which makes its use a portability problem.

Here's another one to consider. In C++ I've had occasion to require a
sizeof(void), and had to resort to traits in order to get it. Does anyone see a
downside with sizeof(void) being legal in D?

"davepermen" <davepermen hotmail.com> wrote in message
news:c8ol00$29c3$1 digitaldaemon.com...
 works in c++...

 should be working in D, too, indeed.

 "Matthew" <matthew.hat stlsoft.dot.org> schrieb im Newsbeitrag
 news:c8okjt$28o9$1 digitaldaemon.com...
 Ah, something I've always wanted in C++...

 I echo the request.

 "Benedikt Meurer" <benedikt.meurer unix-ag.uni-siegen.de> wrote in message
 news:c8o52s$1j0l$1 digitaldaemon.com...
 Hello,

 Would it be possible to add support for void returns, as in

 void f1 () { ... }
 void f2 () { ...; return f1 (); }

 to D? This would be invaluably helpful in template programming. Else one


 to either make heavy use of mixins or write a lot of specialisations.

 (Looking at the code, it seems, that only dmd/statement.c has to be


 to archive this goal).

 regards,
 Benedikt

 --
 NetBSD Operating system:                       http://www.NetBSD.org/
 pkgsrc "Work in progress":                  http://pkgsrc-wip.sf.net/
 XFce desktop environment:                        http://www.xfce.org/
 German Unix-AG Association:                   http://www.unix-ag.org/
 os-network:                                 http://www.os-network.de/

 OpenPGP Key: http://www.home.unix-ag.org/bmeurer/#gpg



May 22 2004
next sibling parent reply "Kris" <someidiot earthlink.dot.dot.dot.net> writes:
I suppose sizeof(void) would need to reflect the size of void[] elements,
which are 1 byte each ...

"Matthew" <matthew.hat stlsoft.dot.org>
 Here's another one to consider. In C++ I've had occasion to require a
 sizeof(void), and had to resort to traits in order to get it. Does anyone

 downside with sizeof(void) being legal in D?

May 22 2004
parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
Sorry, I forgot to say. I would want sizeof(void) to be 0, so it could function
in constraints
validating type sizes.

"Kris" <someidiot earthlink.dot.dot.dot.net> wrote in message
news:c8oo5n$2dpi$1 digitaldaemon.com...
 I suppose sizeof(void) would need to reflect the size of void[] elements,
 which are 1 byte each ...

 "Matthew" <matthew.hat stlsoft.dot.org>
 Here's another one to consider. In C++ I've had occasion to require a
 sizeof(void), and had to resort to traits in order to get it. Does anyone

 downside with sizeof(void) being legal in D?


May 22 2004
parent reply "Walter" <newshound digitalmars.com> writes:
"Matthew" <matthew.hat stlsoft.dot.org> wrote in message
news:c8p0mt$2pl2$1 digitaldaemon.com...
 Sorry, I forgot to say. I would want sizeof(void) to be 0, so it could

 in constraints
 validating type sizes.

There's no way you can make void.sizeof be 0 in D.
May 22 2004
parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
"Walter" <newshound digitalmars.com> wrote in message
news:c8p9tn$5js$1 digitaldaemon.com...
 "Matthew" <matthew.hat stlsoft.dot.org> wrote in message
 news:c8p0mt$2pl2$1 digitaldaemon.com...
 Sorry, I forgot to say. I would want sizeof(void) to be 0, so it could

 in constraints
 validating type sizes.

There's no way you can make void.sizeof be 0 in D.

Do you mean "there's no way that would be a good thing to do" or "there's no way to technically achieve that"? I can't believe the latter, so am intrigued as to your reasoning for the former.
May 22 2004
parent reply "Walter" <newshound digitalmars.com> writes:
"Matthew" <matthew.hat stlsoft.dot.org> wrote in message
news:c8pbkm$7tr$1 digitaldaemon.com...
 "Walter" <newshound digitalmars.com> wrote in message
 news:c8p9tn$5js$1 digitaldaemon.com...
 "Matthew" <matthew.hat stlsoft.dot.org> wrote in message
 news:c8p0mt$2pl2$1 digitaldaemon.com...
 Sorry, I forgot to say. I would want sizeof(void) to be 0, so it could

 in constraints
 validating type sizes.

There's no way you can make void.sizeof be 0 in D.

Do you mean "there's no way that would be a good thing to do" or "there's

 to technically achieve that"?

 I can't believe the latter, so am intrigued as to your reasoning for the

The reason is because you can do pointer arithmetic on void* and indexing of void[]. An axiom of pointer arithmetic is to advance a void* pointer, you add void.sizeof. Breaking this would make an ugly and confusing wart in the language.
May 22 2004
parent "Matthew" <matthew.hat stlsoft.dot.org> writes:
Yes, I can certainly see that point.



"Walter" <newshound digitalmars.com> wrote in message
news:c8pgrt$f23$2 digitaldaemon.com...
 "Matthew" <matthew.hat stlsoft.dot.org> wrote in message
 news:c8pbkm$7tr$1 digitaldaemon.com...
 "Walter" <newshound digitalmars.com> wrote in message
 news:c8p9tn$5js$1 digitaldaemon.com...
 "Matthew" <matthew.hat stlsoft.dot.org> wrote in message
 news:c8p0mt$2pl2$1 digitaldaemon.com...
 Sorry, I forgot to say. I would want sizeof(void) to be 0, so it could

 in constraints
 validating type sizes.

There's no way you can make void.sizeof be 0 in D.

Do you mean "there's no way that would be a good thing to do" or "there's

 to technically achieve that"?

 I can't believe the latter, so am intrigued as to your reasoning for the

The reason is because you can do pointer arithmetic on void* and indexing of void[]. An axiom of pointer arithmetic is to advance a void* pointer, you add void.sizeof. Breaking this would make an ugly and confusing wart in the language.

May 23 2004
prev sibling next sibling parent Hwa Hwa <Hwa_member pathlink.com> writes:
Here's another one to consider. In C++ I've had occasion to require a
sizeof(void), and had to resort to traits in order to get it. Does anyone see a
downside with sizeof(void) being legal in D?

Yes, you would gloat too much.
May 22 2004
prev sibling parent reply Kevin Bealer <Kevin_member pathlink.com> writes:
In article <c8omac$2bc9$1 digitaldaemon.com>, Matthew says...
.
Here's another one to consider. In C++ I've had occasion to require a
sizeof(void), and had to resort to traits in order to get it. Does anyone see a
downside with sizeof(void) being legal in D?

There would discussion, then arguments, then terrible war between the proponents of "void.size==" 0, 1, and 4. So essentially, no. Kevin
May 26 2004
parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
"Kevin Bealer" <Kevin_member pathlink.com> wrote in message
news:c93rtk$1bic$1 digitaldaemon.com...
 In article <c8omac$2bc9$1 digitaldaemon.com>, Matthew says...
 .
Here's another one to consider. In C++ I've had occasion to require a
sizeof(void), and had to resort to traits in order to get it. Does anyone see


downside with sizeof(void) being legal in D?

There would discussion, then arguments, then terrible war between the

 of "void.size==" 0, 1, and 4.  So essentially, no.

Yup, if there could not be 99.98% consensus, then I agree the idea must die. I'll just have to have a size_traits in DTL like I've got in STLSoft. ;)
May 26 2004
parent reply Kevin Bealer <Kevin_member pathlink.com> writes:
In article <c940h3$1i62$1 digitaldaemon.com>, Matthew says...
"Kevin Bealer" <Kevin_member pathlink.com> wrote in message
news:c93rtk$1bic$1 digitaldaemon.com...
 In article <c8omac$2bc9$1 digitaldaemon.com>, Matthew says...
 .
Here's another one to consider. In C++ I've had occasion to require a
sizeof(void), and had to resort to traits in order to get it. Does anyone see


downside with sizeof(void) being legal in D?

There would discussion, then arguments, then terrible war between the

 of "void.size==" 0, 1, and 4.  So essentially, no.

Yup, if there could not be 99.98% consensus, then I agree the idea must die. I'll just have to have a size_traits in DTL like I've got in STLSoft. ;)

Actually, I meant, that usenet's natural state is endless war, so there's no downside. Maybe the classes which want void.size really should be broken. If you can't get around needing the size then you probably have a bug right? I mean, unless it is just a printf(). I think if there was void.sizeof there would be people arguing that it should be illegal, in the same spirit as bit == bool. Kevin
May 27 2004
parent Arcane Jill <Arcane_member pathlink.com> writes:
Maybe the classes which want void.size really should be broken.  If you can't
get around needing the size then you probably have a bug right?  I mean, unless
it is just a printf().  I think if there was void.sizeof there would be people
arguing that it should be illegal, in the same spirit as bit == bool.

Kevin

Actually, that is a very good point. If void.sizeof were simply *not defined* then you'd HAVE to cast it to something else before trying to do pointer arithmetic with it. I still like the idea of having some kind of type with zero size though. So that:
       zero_size_thing x;          // legal
       zero_size_thing* p, q, r;   // legal
       zero_size_thing[1000000000] a;
                             // is also legal, and takes no memory
       x.sizeof              // equals zero
       a.sizeof              // equals zero
       p = a;                // legal
       q = &a[100];          // legal
       q = &a[1000000001];   // NOT legal - array bounds exception
       r = &x;               // legal
       (p == q)              // returns true
       (p == r)              // returns false
       (a[0] == x)           // returns true, since all zero sized objects are
equal
       return x;             // identical in meaning to return;

I'm not hung up on this one. I don't care one way or the other whether sizeof void is 0, 1, or undefined. I don't care if we split void into its two separate meanings (zero_size_thing and unknown) or not. But in my own little way I like to speculate about such ideas, and if they turn out to be useful, fair play. If not, it's no big deal. I've made other suggestions which matter more to me, but this thread I just regard as fun. Incidently, I accidently parsed "void returns" in the same way as "Batman Returns". I thought: does it? Jill
May 27 2004
prev sibling next sibling parent reply James McComb <alan jamesmccomb.id.au> writes:
Benedikt Meurer wrote:
 Hello,
 
 Would it be possible to add support for void returns, as in
 
 void f1 () { ... }
 void f2 () { ...; return f1 (); }

According to Bertrand Meyer, creator of Eiffel, there are two kinds of routines: Commands (i.e. functions that return void), and Queries (i.e. functions that return non-void). According to Meyer, Commands should be used to change state, and Queries should be used only to query that state. What is the point of this distinction? For a variety of reasons, the most important being exception-safety, Queries should not have side-effects (roughly, they should not change state). This is why pop() doesn't return a value in the STL stack. pop() is the Command, and top() is the Query. If functions that return void and functions that return non-void should be used for fundamentally different purposes, when would it be a good idea to have function template parameterized to sometimes return void and sometimes return non-void? James McComb
May 22 2004
next sibling parent reply Juan C <Juan_member pathlink.com> writes:
<snip>
According to Meyer, Commands should be used to change state, and Queries 
should be used only to query that state.

Well then I submit that a knife is to cut food, and a fork is to pick up food (with a spoon being a specialized type of fork?). So one should not use a fork to cut pancakes.
May 22 2004
parent "davepermen" <davepermen hotmail.com> writes:
or a knife to kill people/animals. should not be allowed.

"Juan C" <Juan_member pathlink.com> schrieb im Newsbeitrag
news:c8osai$2jj6$1 digitaldaemon.com...
 <snip>
According to Meyer, Commands should be used to change state, and Queries
should be used only to query that state.

Well then I submit that a knife is to cut food, and a fork is to pick up

 (with a spoon being a specialized type of fork?). So one should not use a

 to cut pancakes.

May 22 2004
prev sibling next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"James McComb" <alan jamesmccomb.id.au> wrote in message
news:c8ophn$2flh$1 digitaldaemon.com...
 If functions that return void and functions that return non-void should
 be used for fundamentally different purposes, when would it be a good
 idea to have function template parameterized to sometimes return void
 and sometimes return non-void?

My thoughts exactly. I know this feature was added to C++, but are there legitimate uses for it, or is it a misfeature, or a workaround for another bug in C++?
May 22 2004
next sibling parent reply Benedikt Meurer <benedikt.meurer unix-ag.uni-siegen.de> writes:
Walter wrote:
 "James McComb" <alan jamesmccomb.id.au> wrote in message
 news:c8ophn$2flh$1 digitaldaemon.com...
 
If functions that return void and functions that return non-void should
be used for fundamentally different purposes, when would it be a good
idea to have function template parameterized to sometimes return void
and sometimes return non-void?

My thoughts exactly. I know this feature was added to C++, but are there legitimate uses for it, or is it a misfeature, or a workaround for another bug in C++?

No, it is an important point in the C++ language, cause without it, you'd end up writing a lot of template specialisations for void. Imagine the following very simple example: class Handler(ReturnType, Parameter) { public: alias ReturnType function(Parameter) Function; this (Function func) { func_ = func; } ReturnType opCall (Parameter1 parameter) { return func_ (parameter); } private: Function func_; }; (Of course, you'll probably also want to have a Handler template for functions with 2, 3, 4, ..., x parameters). This won't work if ReturnType is void. The only way to get this to work in D (I should note, that I'm using the latest gdc) is to create a void specialisation for every such template class. This leds to lots of code duplication which is IMHO a bad thing. One should also keep in mind, that the above is a very simple example. Therefore I consider this a vital feature for template programming. The adoption should be easy, just add a paragraph to the spec: "If a function that is declared to return void, discovers a return statement with an expression, this expression has to evaluate to void." or something like that. best regards, Benedikt -- NetBSD Operating system: http://www.NetBSD.org/ pkgsrc "Work in progress": http://pkgsrc-wip.sf.net/ XFce desktop environment: http://www.xfce.org/ German Unix-AG Association: http://www.unix-ag.org/ os-network: http://www.os-network.de/ OpenPGP Key: http://www.home.unix-ag.org/bmeurer/#gpg
May 23 2004
parent reply "Walter" <newshound digitalmars.com> writes:
"Benedikt Meurer" <benedikt.meurer unix-ag.uni-siegen.de> wrote in message
news:c8pjgl$k6c$1 digitaldaemon.com...
 Walter wrote:
 "James McComb" <alan jamesmccomb.id.au> wrote in message
 news:c8ophn$2flh$1 digitaldaemon.com...

If functions that return void and functions that return non-void should
be used for fundamentally different purposes, when would it be a good
idea to have function template parameterized to sometimes return void
and sometimes return non-void?

My thoughts exactly. I know this feature was added to C++, but are there legitimate uses for it, or is it a misfeature, or a workaround for


 bug in C++?

No, it is an important point in the C++ language, cause without it, you'd

 up writing a lot of template specialisations for void. Imagine the

 very simple example:

I see its need for that example, but I don't see that the example does anything useful <g>. The trouble is, I'm not an expert at using templates, so I'd have to take your word for it.
May 23 2004
parent Arcane Jill <Arcane_member pathlink.com> writes:
In article <c8qoat$27jv$1 digitaldaemon.com>, Walter says...
I see its need for that example, but I don't see that the example does

so I'd have to take your word for it.

I've used templates a lot in C++. I haven't used them in D (yet) because I'm working on a specific project, which just happens not to need them. But I can tell you that being allowed to return void is something that you definitely need in a lot of generic programming. You need it so much, that, if you DON'T put it into the language, then people *will* make their own workarounds for it. For example - I might change something like:
       void printNiceMessage()
       {
           printf("hello\n");
       }

to:
       bit printNiceMessage()
       {
           printf("hello\n");
           return true;
       }

just so that I can use it in templates. But this clutters the interface, and confuses people - sometimes they end up testing the return value, thinking false means "something went wrong", when in fact, it can never return false at all. It would be better to allow void as a return type. Arcane Jill
May 24 2004
prev sibling parent Sean Kelly <sean f4.ca> writes:
Walter wrote:
 
 My thoughts exactly. I know this feature was added to C++, but are there
 legitimate uses for it, or is it a misfeature, or a workaround for another
 bug in C++?

This comes up a lot when using the algorithms from the C++ standard library. They all want to pass functions or function objects around to do stuff, and the return type is a part of the template parameterization: template<typedef Ty> struct accumulate : public std::unary_function<void,Ty> { void operator()( Ty const& val ) { total += val; } Ty total; }; It's pretty common to not care about a return type for these functions, but because of the template design a dummy one often has to be provided just to get the code to compile (I commonly change the void to a bool). So there are legitimate uses for it as a workaround for design aspects of the C++ standard library :) I personally don't have much of an issue with "return void;" from a semantic standpoint. It seems pretty clear, if a bit odd. Sean
May 23 2004
prev sibling parent reply Norbert Nemec <Norbert.Nemec gmx.de> writes:
D allows lots of stuff that Bertrand Meyer does not like. If you want to
follow his coding principles, you are free to do so, but obviously D was
not designed to force people using a certain style, but to allow them to
express themselves in the way they want to.

I like Bertrand Meyer's ideas, but I think that they are a bit idealistic
and lead to extremely wordy programs in real life. Just consider a stack
class that offeres a "pop" routine. According to Bertrand Meyer, "pop"
would be illegal and you should split it up into "get_top" and
"remove_top"...



James McComb wrote:

 Benedikt Meurer wrote:
 Hello,
 
 Would it be possible to add support for void returns, as in
 
 void f1 () { ... }
 void f2 () { ...; return f1 (); }

According to Bertrand Meyer, creator of Eiffel, there are two kinds of routines: Commands (i.e. functions that return void), and Queries (i.e. functions that return non-void). According to Meyer, Commands should be used to change state, and Queries should be used only to query that state. What is the point of this distinction? For a variety of reasons, the most important being exception-safety, Queries should not have side-effects (roughly, they should not change state). This is why pop() doesn't return a value in the STL stack. pop() is the Command, and top() is the Query. If functions that return void and functions that return non-void should be used for fundamentally different purposes, when would it be a good idea to have function template parameterized to sometimes return void and sometimes return non-void? James McComb

May 23 2004
next sibling parent reply "Bent Rasmussen" <exo bent-rasmussen.info> writes:
 D allows lots of stuff that Bertrand Meyer does not like. If you want to
 follow his coding principles, you are free to do so, but obviously D was
 not designed to force people using a certain style, but to allow them to
 express themselves in the way they want to.

I'd call it an idiom than you can use, but Eiffel does not force you into using it, its just good practice and so has nothing to do with Eiffel forcing you into anything. However Eiffel does seem to be designed to be very coherent and the libraries are not an exception. But make your own exceptions. Except for libraries where you'd probably not want two versions, one for side-effecting queries and one for side-effecting queries for terseness. ;) A D-like compromise would be to build the side-effecting query on top of the separated command and query.
 I like Bertrand Meyer's ideas, but I think that they are a bit idealistic
 and lead to extremely wordy programs in real life. Just consider a stack
 class that offeres a "pop" routine. According to Bertrand Meyer, "pop"
 would be illegal and you should split it up into "get_top" and
 "remove_top"...

One more call, one less bug? ;)
May 23 2004
parent Norbert Nemec <Norbert.Nemec gmx.de> writes:
Bent Rasmussen wrote:

 I like Bertrand Meyer's ideas, but I think that they are a bit idealistic
 and lead to extremely wordy programs in real life. Just consider a stack
 class that offeres a "pop" routine. According to Bertrand Meyer, "pop"
 would be illegal and you should split it up into "get_top" and
 "remove_top"...

One more call, one less bug? ;)

I don't believe, splitting "pop" into two calls would prevent any bugs. It would be just as likely that you forget one "remove_top" somewhere in the code. Every experienced C/C++/D programmer knows that side-effects of functions have to be taken carefully. Looking back at a long time of programming, I don't think that bugs caused by unexpected side-effects ever were a major problem. Actually, looking at exapmles like the ++/-- operators, side-effects are planted so deep inside the philosophy of C/C++/D that you might have a hard time if you want to follow Bertram Meyer's concepts.
May 23 2004
prev sibling parent reply James McComb <alan jamesmccomb.id.au> writes:
Norbert Nemec wrote:

 I like Bertrand Meyer's ideas, but I think that they are a bit idealistic
 and lead to extremely wordy programs in real life.

I agree with you. In case you think I worship Betrand Meyer, here's the same idea expressed by C++ guru Herb Sutter: <quote> Incidentally, have you ever grumbled at the way the standard library containers' pop functions (e.g., list::pop_back, stack::pop, etc.) don't return the popped value? Well, here's one reason to do this: It avoids weakening exception safety. </quote> James McComb
May 23 2004
parent reply Norbert Nemec <Norbert.Nemec gmx.de> writes:
James McComb wrote:

 Norbert Nemec wrote:
 
 I like Bertrand Meyer's ideas, but I think that they are a bit idealistic
 and lead to extremely wordy programs in real life.

I agree with you. In case you think I worship Betrand Meyer, here's the same idea expressed by C++ guru Herb Sutter: <quote> Incidentally, have you ever grumbled at the way the standard library containers' pop functions (e.g., list::pop_back, stack::pop, etc.) don't return the popped value? Well, here's one reason to do this: It avoids weakening exception safety. </quote>

Sorry, I have no idea what he means with "weakening exception safety". I realize now, that STL's "pop" really doesn't return a value. Guess, I have to reconsider my former statements. Anyhow, I really would like to understand the rationale behind it.
May 24 2004
parent "Matthew" <matthew.hat stlsoft.dot.org> writes:
If you pop and return the pop'd value in one notional operation, it is possible
for the element to be removed from the container, but for an exception to throw
in the copy constructor of the returned value - if of class type - which would
result in the element being lost, both from the container and from client code.
This is an artefact of C++'s return-by-value semantics, and is not an issue in
D.
(Unless one can do such things with structs, which is counter to my current
understanding.)

"Norbert Nemec" <Norbert.Nemec gmx.de> wrote in message
news:c8s7dn$18u0$2 digitaldaemon.com...
 James McComb wrote:

 Norbert Nemec wrote:

 I like Bertrand Meyer's ideas, but I think that they are a bit idealistic
 and lead to extremely wordy programs in real life.

I agree with you. In case you think I worship Betrand Meyer, here's the same idea expressed by C++ guru Herb Sutter: <quote> Incidentally, have you ever grumbled at the way the standard library containers' pop functions (e.g., list::pop_back, stack::pop, etc.) don't return the popped value? Well, here's one reason to do this: It avoids weakening exception safety. </quote>

Sorry, I have no idea what he means with "weakening exception safety". I realize now, that STL's "pop" really doesn't return a value. Guess, I have to reconsider my former statements. Anyhow, I really would like to understand the rationale behind it.

May 24 2004
prev sibling next sibling parent "Ivan Senji" <ivan.senji public.srce.hr> writes:
"Benedikt Meurer" <benedikt.meurer unix-ag.uni-siegen.de> wrote in message
news:c8o52s$1j0l$1 digitaldaemon.com...
 Hello,

 Would it be possible to add support for void returns, as in

 void f1 () { ... }
 void f2 () { ...; return f1 (); }

I have to say I am surprised that this isn't possible in D. In my opinion one of the most important things in any language is that it is consistent. So if it is possible to do: int f1 () { ... } int f2 () { ...; return f1 (); } then this should be allowed also void f1 () { ... } void f2 () { ...; return f1 (); } Function f2 is declared to return void(nothing) and the return type of f1 is also void, so it just makes prefect sence to redirect f1s void to f2s void.
 to D? This would be invaluably helpful in template programming. Else one

 to either make heavy use of mixins or write a lot of specialisations.

 (Looking at the code, it seems, that only dmd/statement.c has to be

 to archive this goal).

 regards,
 Benedikt

 --
 NetBSD Operating system:                       http://www.NetBSD.org/
 pkgsrc "Work in progress":                  http://pkgsrc-wip.sf.net/
 XFce desktop environment:                        http://www.xfce.org/
 German Unix-AG Association:                   http://www.unix-ag.org/
 os-network:                                 http://www.os-network.de/

 OpenPGP Key: http://www.home.unix-ag.org/bmeurer/#gpg

May 24 2004
prev sibling parent reply Kevin Bealer <Kevin_member pathlink.com> writes:
In article <c8o52s$1j0l$1 digitaldaemon.com>, Benedikt Meurer says...
Hello,

Would it be possible to add support for void returns, as in

void f1 () { ... }
void f2 () { ...; return f1 (); }

to D? This would be invaluably helpful in template programming. Else one has 
to either make heavy use of mixins or write a lot of specialisations.

(Looking at the code, it seems, that only dmd/statement.c has to be modified 
to archive this goal).

This idea could be taken further. Instead of just for return types, imagine something like this: void[int] set_of_int; Now, I have a set. The object is a map (assoc. array) but a map with no key is a set. I would need some way to determine if an element is present of course. Another example: template(Bar) { struct Baz { char[] name; Foo value; } } Now, Bar!(void).Baz yields: struct Baz { char[] name; }; Baz x; x.value = 5; // Do nothing statement. 5; // An equivalent statement. A statement like "x.value = 4" would simply disappear. I'm not saying this is a good idea; I'll let others speculate. Essentially all statements using the "void" object would just disappear. This allows the creation of optional fields. (But would it be useful? not sure.) Kevin
May 25 2004
parent reply Norbert Nemec <Norbert.Nemec gmx.de> writes:
Kevin Bealer wrote:

 In article <c8o52s$1j0l$1 digitaldaemon.com>, Benedikt Meurer says...
Hello,

Would it be possible to add support for void returns, as in

void f1 () { ... }
void f2 () { ...; return f1 (); }

to D? This would be invaluably helpful in template programming. Else one
has to either make heavy use of mixins or write a lot of specialisations.

(Looking at the code, it seems, that only dmd/statement.c has to be
modified to archive this goal).

This idea could be taken further. Instead of just for return types, imagine something like this: void[int] set_of_int; Now, I have a set. The object is a map (assoc. array) but a map with no key is a set. I would need some way to determine if an element is present of course.

You probably want to say "A map with no *data*"
May 25 2004
parent reply Arcane Jill <Arcane_member pathlink.com> writes:
Since the bool type suggestion went down so well, it's worth pointing out that
the keyword "void" is also similarly overloaded to mean two completely different
things - and this is also true in C, C++ and Java.

"void" on its own means "nothing". A function which returns void, is a function
which does not return a value at all.

On the other hand, "void *" does NOT mean "pointer to nothing". It means
"pointer to ANYTHING". And there is a big, big difference in meaning between
"nothing" and "anything".

Imagine if, instead of the single type void, we had two types: "void" and
"unknown". Throughout the universe of D, all instances of "void *" would be
changed to "unknown *". unknown.sizeof would be defined to be equal to 1, but
"void.sizeof" would be defined to be equal to 0. Functions would be allowed to
return void, but it would be illegal to return unknown (but perfectly ok to
return a POINTER to unknown). A "variable" could be declared as being of type
void (but not unknown). Such a void variable would occupy zero bytes of storage,
but it would still be possible to take its address. An array like
void[100000000] would be possible, and would still occupy zero bytes. (And yes,
this would be useful - at least, in generic template programming).

"unknown", on the other hand would be less flexible. Only "unknown *" would be
allowed. Such a pointer may never be dereferenced, without first being cast into
something else.

Of course, I don't expect anyone either to take this seriously, or to implement
this. But I just bring this to people's attention - (void *) does not mean
"pointer to void", it means "pointer to something but we don't know what it is".
And this can sometimes cause confusion.

Arcane Jill
May 26 2004
next sibling parent Juan C <Juan_member pathlink.com> writes:
I'm for it.

In article <c91ipc$10lq$1 digitaldaemon.com>, Arcane Jill says...
Since the bool type suggestion went down so well, it's worth pointing out that
the keyword "void" is also similarly overloaded to mean two completely different
things - and this is also true in C, C++ and Java.

"void" on its own means "nothing". A function which returns void, is a function
which does not return a value at all.

On the other hand, "void *" does NOT mean "pointer to nothing". It means
"pointer to ANYTHING". And there is a big, big difference in meaning between
"nothing" and "anything".

Imagine if, instead of the single type void, we had two types: "void" and
"unknown". Throughout the universe of D, all instances of "void *" would be
changed to "unknown *". unknown.sizeof would be defined to be equal to 1, but
"void.sizeof" would be defined to be equal to 0. Functions would be allowed to
return void, but it would be illegal to return unknown (but perfectly ok to
return a POINTER to unknown). A "variable" could be declared as being of type
void (but not unknown). Such a void variable would occupy zero bytes of storage,
but it would still be possible to take its address. An array like
void[100000000] would be possible, and would still occupy zero bytes. (And yes,
this would be useful - at least, in generic template programming).

"unknown", on the other hand would be less flexible. Only "unknown *" would be
allowed. Such a pointer may never be dereferenced, without first being cast into
something else.

Of course, I don't expect anyone either to take this seriously, or to implement
this. But I just bring this to people's attention - (void *) does not mean
"pointer to void", it means "pointer to something but we don't know what it is".
And this can sometimes cause confusion.

Arcane Jill

May 26 2004
prev sibling next sibling parent Regan Heath <regan netwin.co.nz> writes:
Intersting idea..

Q: why type "unknown *" when we could just type "unknown"?

basically the type "unknown" could be defined as a pointer to anything, so 
assigning anything to an unknown automatically takes it's address.


On Wed, 26 May 2004 07:59:40 +0000 (UTC), Arcane Jill 
<Arcane_member pathlink.com> wrote:
 Since the bool type suggestion went down so well, it's worth pointing 
 out that
 the keyword "void" is also similarly overloaded to mean two completely 
 different
 things - and this is also true in C, C++ and Java.

 "void" on its own means "nothing". A function which returns void, is a 
 function
 which does not return a value at all.

 On the other hand, "void *" does NOT mean "pointer to nothing". It means
 "pointer to ANYTHING". And there is a big, big difference in meaning 
 between
 "nothing" and "anything".

 Imagine if, instead of the single type void, we had two types: "void" and
 "unknown". Throughout the universe of D, all instances of "void *" would 
 be
 changed to "unknown *". unknown.sizeof would be defined to be equal to 
 1, but
 "void.sizeof" would be defined to be equal to 0. Functions would be 
 allowed to
 return void, but it would be illegal to return unknown (but perfectly ok 
 to
 return a POINTER to unknown). A "variable" could be declared as being of 
 type
 void (but not unknown). Such a void variable would occupy zero bytes of 
 storage,
 but it would still be possible to take its address. An array like
 void[100000000] would be possible, and would still occupy zero bytes. 
 (And yes,
 this would be useful - at least, in generic template programming).

 "unknown", on the other hand would be less flexible. Only "unknown *" 
 would be
 allowed. Such a pointer may never be dereferenced, without first being 
 cast into
 something else.

 Of course, I don't expect anyone either to take this seriously, or to 
 implement
 this. But I just bring this to people's attention - (void *) does not 
 mean
 "pointer to void", it means "pointer to something but we don't know what 
 it is".
 And this can sometimes cause confusion.

 Arcane Jill

-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
May 26 2004
prev sibling next sibling parent Derek Parnell <derek psych.ward> writes:
On Wed, 26 May 2004 07:59:40 +0000 (UTC), Arcane Jill wrote:

 Since the bool type suggestion went down so well, it's worth pointing out that
 the keyword "void" is also similarly overloaded to mean two completely
different
 things - and this is also true in C, C++ and Java.
 
 "void" on its own means "nothing". A function which returns void, is a function
 which does not return a value at all.
 
 On the other hand, "void *" does NOT mean "pointer to nothing". It means
 "pointer to ANYTHING". And there is a big, big difference in meaning between
 "nothing" and "anything".
 
 Imagine if, instead of the single type void, we had two types: "void" and
 "unknown". Throughout the universe of D, all instances of "void *" would be
 changed to "unknown *". unknown.sizeof would be defined to be equal to 1, but
 "void.sizeof" would be defined to be equal to 0. Functions would be allowed to
 return void, but it would be illegal to return unknown (but perfectly ok to
 return a POINTER to unknown). A "variable" could be declared as being of type
 void (but not unknown). Such a void variable would occupy zero bytes of
storage,
 but it would still be possible to take its address. An array like
 void[100000000] would be possible, and would still occupy zero bytes. (And yes,
 this would be useful - at least, in generic template programming).
 
 "unknown", on the other hand would be less flexible. Only "unknown *" would be
 allowed. Such a pointer may never be dereferenced, without first being cast
into
 something else.
 
 Of course, I don't expect anyone either to take this seriously, or to implement
 this. But I just bring this to people's attention - (void *) does not mean
 "pointer to void", it means "pointer to something but we don't know what it
is".
 And this can sometimes cause confusion.
 
 Arcane Jill

Hmmmmm...don't know....sounds a bit too logical... Oh well, let's throw caution to the wind. I think this is a Good Idea (tm). Let's see now... unknown *X; int A; int B; X = &A; // Now X points to A B = cast(int)*X; // Assign B to whatever X points to ('A' in this case) -- Derek 27/May/04 10:00:26 AM
May 26 2004
prev sibling parent Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
In article <c91ipc$10lq$1 digitaldaemon.com>, Arcane Jill wrote:
 On the other hand, "void *" does NOT mean "pointer to nothing". It means
 "pointer to ANYTHING". And there is a big, big difference in meaning between
 "nothing" and "anything".
 
 Imagine if, instead of the single type void, we had two types: "void" and
 "unknown". Throughout the universe of D, all instances of "void *" would be
 changed to "unknown *". unknown.sizeof would be defined to be equal to 1, but
 "void.sizeof" would be defined to be equal to 0. Functions would be allowed to
 return void, but it would be illegal to return unknown (but perfectly ok to
 return a POINTER to unknown). A "variable" could be declared as being of type

Why not use just byte* instead of unknown*? Because in the end every pointer *is* a pointer to a byte, and that's about as little semantics as you can give to a pointer to anything. I know - safety issues I guess, to prevent accidental use of those pointers? (I like the idea of void as something of size 0) -Antti -- I will not be using Plan 9 in the creation of weapons of mass destruction to be used by nations other than the US.
May 27 2004