www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Let's do front, back, popFront, and popBack!

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Let's!!

Andrei
Jan 29 2009
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
Will popFront and popBack return the element removed?  Usually that is the 
meaning of pop (but not always).

-Steve 
Jan 29 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Steven Schveighoffer wrote:
 Will popFront and popBack return the element removed?  Usually that is the 
 meaning of pop (but not always).

Great question. In STL they can't because C++ couldn't move values reliably at the time (C++0X still can't IMHO but that's another discussion). D would be able to because it has good support for moving. I just don't want inefficiencies; returning e.g. a large struct will still involve some memcpying even if costly resources are not duplicated. So I'm ambivalent about this. Andrei
Jan 29 2009
next sibling parent reply Michel Fortin <michel.fortin michelf.com> writes:
On 2009-01-29 22:02:07 -0500, Andrei Alexandrescu 
<SeeWebsiteForEmail erdani.org> said:

 Steven Schveighoffer wrote:
 Will popFront and popBack return the element removed?  Usually that is 
 the meaning of pop (but not always).

Great question. In STL they can't because C++ couldn't move values reliably at the time (C++0X still can't IMHO but that's another discussion). D would be able to because it has good support for moving. I just don't want inefficiencies; returning e.g. a large struct will still involve some memcpying even if costly resources are not duplicated. So I'm ambivalent about this.

That would seem like another good use for return type overloading: void popFront(); ElementType popFront(); Too bad we can't have that. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Jan 29 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Michel Fortin wrote:
 On 2009-01-29 22:02:07 -0500, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:
 
 Steven Schveighoffer wrote:
 Will popFront and popBack return the element removed?  Usually that 
 is the meaning of pop (but not always).

Great question. In STL they can't because C++ couldn't move values reliably at the time (C++0X still can't IMHO but that's another discussion). D would be able to because it has good support for moving. I just don't want inefficiencies; returning e.g. a large struct will still involve some memcpying even if costly resources are not duplicated. So I'm ambivalent about this.

That would seem like another good use for return type overloading: void popFront(); ElementType popFront(); Too bad we can't have that.

I've been thinking for a while to suggest Walter to allow overloading of void vs. anything else return type. Making one private or undefined would prevent statically that people call functions and ignore error codes. Andrei
Jan 29 2009
next sibling parent dsimcha <dsimcha yahoo.com> writes:
== Quote from Andrei Alexandrescu (SeeWebsiteForEmail erdani.org)'s article
 I've been thinking for a while to suggest Walter to allow overloading of
 void vs. anything else return type. Making one private or undefined
 would prevent statically that people call functions and ignore error codes.
 Andrei

Who still uses error codes? The only time I can think of that mattering is if you're calling C functions, in which case overloading wouldn't work anyhow. Isn't enforcing that the caller not ignore an error condition what exceptions are for?
Jan 29 2009
prev sibling parent reply Don <nospam nospam.com> writes:
Andrei Alexandrescu wrote:
 Michel Fortin wrote:
 On 2009-01-29 22:02:07 -0500, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 Steven Schveighoffer wrote:
 Will popFront and popBack return the element removed?  Usually that 
 is the meaning of pop (but not always).

Great question. In STL they can't because C++ couldn't move values reliably at the time (C++0X still can't IMHO but that's another discussion). D would be able to because it has good support for moving. I just don't want inefficiencies; returning e.g. a large struct will still involve some memcpying even if costly resources are not duplicated. So I'm ambivalent about this.

That would seem like another good use for return type overloading: void popFront(); ElementType popFront(); Too bad we can't have that.

I've been thinking for a while to suggest Walter to allow overloading of void vs. anything else return type. Making one private or undefined would prevent statically that people call functions and ignore error codes.

That's a really interesting idea. You could force ownership, too, couldn't you? (So that you couldn't eg createFile("xxx") and forget to store the file handle).
Jan 30 2009
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Don" wrote
 Andrei Alexandrescu wrote:
 Michel Fortin wrote:
 On 2009-01-29 22:02:07 -0500, Andrei Alexandrescu 
 <SeeWebsiteForEmail erdani.org> said:

 Steven Schveighoffer wrote:
 Will popFront and popBack return the element removed?  Usually that is 
 the meaning of pop (but not always).

Great question. In STL they can't because C++ couldn't move values reliably at the time (C++0X still can't IMHO but that's another discussion). D would be able to because it has good support for moving. I just don't want inefficiencies; returning e.g. a large struct will still involve some memcpying even if costly resources are not duplicated. So I'm ambivalent about this.

That would seem like another good use for return type overloading: void popFront(); ElementType popFront(); Too bad we can't have that.

I've been thinking for a while to suggest Walter to allow overloading of void vs. anything else return type. Making one private or undefined would prevent statically that people call functions and ignore error codes.

That's a really interesting idea. You could force ownership, too, couldn't you? (So that you couldn't eg createFile("xxx") and forget to store the file handle).

Hm... then we have to implement 2 functions where only one is now necessary. Most likely the second function just is a void shell of the other. For instance, chaining references are quite often returned, but you don't always have to "store" or use them. Now we have to double all the functions so you have void versions too? I do like the idea though on allowing a void/nonvoid overload. It would be a very simple to check for by the compiler. Just don't force me to use the return value if it's not important to. -Steve
Jan 30 2009
prev sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:
 I just don't want inefficiencies; returning e.g. a large struct will 
 still involve some memcpying even if costly resources are not duplicated.

If a larger and more complex API can be tolerated, then you can add a method to remove the last/first item without returning it (so the pop methods return it). To append items you can use tilte-equal operator, and to prepend you may use the ".prepend(...)" method. Another silly possibility is, inside the pop methods, identify in some way the code that returns the value, and don't compile it. So the compiler is able to almost automatically create two return-overloaded functions, one that returns and one that doesn't return. To do this the programmer may add some tag, or the compiler may do it automatically, removing the "return" from a second version of the function, and then removing dead code that created the data that is given by the return.
Making one private or undefined would prevent statically that people call
functions and ignore error codes.<

I think this is an important enough thing; GCC too thinks it's important because it allows this function attribute: warn_unused_result The warn_unused_result attribute causes a warning to be emitted if a caller of the function with this attribute does not use its return value. This is useful for functions where not checking the result is either a security problem or always a bug, such as realloc. int fn () __attribute__ ((warn_unused_result)); int foo () { if (fn () < 0) return -1; fn (); return 0; } results in warning on line 5 Bye, bearophile
Jan 30 2009
parent reply bearophile <bearophileHUGS lycos.com> writes:
popFront, and popBack:

An alternative possibility is to have "pop" and "popFront", where "pop" removes
from the back.

In Python you can use pop() to remove from the back and pop(0) to remove from
the front, but I presume this isn't much appreciated in D.

Bye,
bearophile
Jan 30 2009
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
bearophile wrote:
 popFront, and popBack:
 
 An alternative possibility is to have "pop" and "popFront", where "pop"
removes from the back.
 
 In Python you can use pop() to remove from the back and pop(0) to remove from
the front, but I presume this isn't much appreciated in D.
 
 Bye,
 bearophile

There are structures (heap, stack) that only allow pop, which would make matters rather confusing. One nice thing about the STL is a consistent naming convention. They have front, back, push_front, push_back, pop_front, and pop_back when these make sense. When only one pop makes sense, the name of the function is pop, as expected. The nice thing is there's almost no need to explain what each of these does and why they're called that way. Andrei
Jan 30 2009
prev sibling parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Thu, 29 Jan 2009 18:54:14 -0800, Andrei Alexandrescu wrote:
 Let's!!

I like it. I think this even was proposed before but was rejected because of Walter's attitude towards composite primitive names. I also like the symmetry because ranges are a more generic construct than single-linked lists where head et al. come from. Probably I don't like capitalization in built-in primitive names, it smells of C#. I'd prefer popfront and popback.
Jan 30 2009
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Sergey Gromov wrote:
 Thu, 29 Jan 2009 18:54:14 -0800, Andrei Alexandrescu wrote:
 Let's!!

I like it. I think this even was proposed before but was rejected because of Walter's attitude towards composite primitive names. I also like the symmetry because ranges are a more generic construct than single-linked lists where head et al. come from. Probably I don't like capitalization in built-in primitive names, it smells of C#. I'd prefer popfront and popback.

Me too, but it would run counter to the prevailing naming convention in phobosAtLeast. There are many places in phobos where that's not respected though... Andrei
Jan 30 2009
parent Chad J <gamerchad __spam.is.bad__gmail.com> writes:
Andrei Alexandrescu wrote:
 Sergey Gromov wrote:
 Thu, 29 Jan 2009 18:54:14 -0800, Andrei Alexandrescu wrote:
 Let's!!

I like it. I think this even was proposed before but was rejected because of Walter's attitude towards composite primitive names. I also like the symmetry because ranges are a more generic construct than single-linked lists where head et al. come from. Probably I don't like capitalization in built-in primitive names, it smells of C#. I'd prefer popfront and popback.

Me too, but it would run counter to the prevailing naming convention in phobosAtLeast. There are many places in phobos where that's not respected though... Andrei

Phobos not adhering to it's own naming convention always rubbed me the wrong way. As for composite primitive/builtin names... foreach_reverse :/ Mostly though I don't really care. I use Tango and foreach_reverse is forgivable ;)
Jan 30 2009