digitalmars.D.learn - xvalue and std::move in D
- Edwin van Leeuwen (21/21) Mar 06 2014 I am trying to learn D and (partly) replace my C++ projects with
- Mike Parker (3/13) Mar 06 2014 See std.algorithm.move
- Edwin van Leeuwen (3/4) Mar 06 2014 Thank you, can't believe I missed that. How do I specify that the
- bearophile (4/6) Mar 06 2014 Thankfully D lacks the && operator.
- Remo (2/8) Mar 06 2014 But is also locks r-value references, and this is a problem.
- Nicolas Sicard (4/10) Mar 06 2014 What are you trying to do? D is not C++11. Pure functional
- Edwin van Leeuwen (8/19) Mar 06 2014 I guess what I am trying to do is allow code that looks like this:
- Mike Parker (21/28) Mar 06 2014 import std.stdio;
- Mike Parker (10/16) Mar 06 2014 D doesn't have anything like that. The compiler will generally move for
- Edwin van Leeuwen (2/21) Mar 06 2014 Thank you for those links/pointers. I'll have a look at those.
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (29/39) Mar 06 2014 http://blog.knatten.org/2012/11/02/efficient-pure-functional-programming...
I am trying to learn D and (partly) replace my C++ projects with D. Lately in C++ I have become a fan of the type of functional programming discussed here: http://blog.knatten.org/2012/11/02/efficient-pure-functional-programming-in-c-using-move-semantics/ and was wondering if something similar is possible in D. Basically the idea is to define functions as follows: std::vector<double> add_to_vector( double x, std::vector<double> &&v ) { v.push_back(x); return v; } and call it as follows: std::vector<double> v; v = add_to_vector( 1.2, std::move( v ) ); I know I could do the same by passing a reference value, but this makes it explicit that I am changing v, while being as efficient as passing a reference (since it just reuses the memory allocated to v instead of making a copy). Is this possible in D? I had a look through many tutorials and some of the docs, but could not find out how to do it. Any suggestions would be appreciated.
Mar 06 2014
On 3/6/2014 8:21 PM, Edwin van Leeuwen wrote:and call it as follows: std::vector<double> v; v = add_to_vector( 1.2, std::move( v ) ); I know I could do the same by passing a reference value, but this makes it explicit that I am changing v, while being as efficient as passing a reference (since it just reuses the memory allocated to v instead of making a copy). Is this possible in D? I had a look through many tutorials and some of the docs, but could not find out how to do it. Any suggestions would be appreciated.See std.algorithm.move http://dlang.org/phobos/std_algorithm.html#move
Mar 06 2014
On Thursday, 6 March 2014 at 11:28:21 UTC, Mike Parker wrote:See std.algorithm.moveThank you, can't believe I missed that. How do I specify that the function expects a temporary/xvalue (&&) parameter though?
Mar 06 2014
Edwin van Leeuwen:Thank you, can't believe I missed that. How do I specify that the function expects a temporary/xvalue (&&) parameter though?Thankfully D lacks the && operator. Bye, bearophile
Mar 06 2014
On Thursday, 6 March 2014 at 12:01:25 UTC, bearophile wrote:Edwin van Leeuwen:But is also locks r-value references, and this is a problem.Thank you, can't believe I missed that. How do I specify that the function expects a temporary/xvalue (&&) parameter though?Thankfully D lacks the && operator. Bye, bearophile
Mar 06 2014
On Thursday, 6 March 2014 at 11:49:51 UTC, Edwin van Leeuwen wrote:On Thursday, 6 March 2014 at 11:28:21 UTC, Mike Parker wrote:What are you trying to do? D is not C++11. Pure functional programming in D follows a different path.See std.algorithm.moveThank you, can't believe I missed that. How do I specify that the function expects a temporary/xvalue (&&) parameter though?
Mar 06 2014
On Thursday, 6 March 2014 at 12:08:35 UTC, Nicolas Sicard wrote:On Thursday, 6 March 2014 at 11:49:51 UTC, Edwin van Leeuwen wrote:I guess what I am trying to do is allow code that looks like this: v = add_to_vector( x, v ); while enforcing that v is never copied. I know there are other ways to do this, i.e. void add_to_vector( x, ref v ); but for me the earlier pattern is more explicit about what is happening, while still being as efficient.On Thursday, 6 March 2014 at 11:28:21 UTC, Mike Parker wrote:What are you trying to do? D is not C++11. Pure functional programming in D follows a different path.See std.algorithm.moveThank you, can't believe I missed that. How do I specify that the function expects a temporary/xvalue (&&) parameter though?
Mar 06 2014
On 3/6/2014 9:38 PM, Edwin van Leeuwen wrote:I guess what I am trying to do is allow code that looks like this: v = add_to_vector( x, v ); while enforcing that v is never copied. I know there are other ways to do this, i.e. void add_to_vector( x, ref v ); but for me the earlier pattern is more explicit about what is happening, while still being as efficient.import std.stdio; struct Foo { int x, y; } Foo add( Foo f, int val ) { writefln( "By val verision" ); return Foo( f.x + val, f.y + val ); } Foo add( ref Foo f, int val ) { writefln( "Ref version" ); return Foo( f.x + val, f.y + val ); } void main() { Foo f1 = Foo( 1, 2 ); Foo f2 = add( f1, 1 ); // by ref version import std.algorithm : move; Foo f3 = add( f2.move, 4 ); // by val version, no copy // First is by ref, second is by val with no copy Foo f4 = f3.add( 2 ).add( 5 ); }
Mar 06 2014
On 3/6/2014 8:49 PM, Edwin van Leeuwen wrote:On Thursday, 6 March 2014 at 11:28:21 UTC, Mike Parker wrote:D doesn't have anything like that. The compiler will generally move for you when possible. Passing an RValue to a function will be done as a move. When returning structs from a function, they're moved. For LValues, it's up to the caller to make the move with std.algorithm.move. There's been a good deal of discussion here in the NG about this. Hit google with 'dlang move semantics' and you'll get some hits. There's also Ali's presentation (video[1] and slides[2]) from last year's DConf. [1] http://www.youtube.com/watch?v=mPr2UspS0fE [2] http://dconf.org/2013/talks/cehreli.pdfSee std.algorithm.moveThank you, can't believe I missed that. How do I specify that the function expects a temporary/xvalue (&&) parameter though?
Mar 06 2014
On Thursday, 6 March 2014 at 12:10:40 UTC, Mike Parker wrote:On 3/6/2014 8:49 PM, Edwin van Leeuwen wrote:Thank you for those links/pointers. I'll have a look at those.On Thursday, 6 March 2014 at 11:28:21 UTC, Mike Parker wrote:D doesn't have anything like that. The compiler will generally move for you when possible. Passing an RValue to a function will be done as a move. When returning structs from a function, they're moved. For LValues, it's up to the caller to make the move with std.algorithm.move. There's been a good deal of discussion here in the NG about this. Hit google with 'dlang move semantics' and you'll get some hits. There's also Ali's presentation (video[1] and slides[2]) from last year's DConf. [1] http://www.youtube.com/watch?v=mPr2UspS0fE [2] http://dconf.org/2013/talks/cehreli.pdfSee std.algorithm.moveThank you, can't believe I missed that. How do I specify that the function expects a temporary/xvalue (&&) parameter though?
Mar 06 2014
On 03/06/2014 03:21 AM, Edwin van Leeuwen wrote:Lately in C++ I have become a fan of the type of functional programming discussed here:http://blog.knatten.org/2012/11/02/efficient-pure-functional-programming-in-c-u ing-move-semantics/ I haven't read that yet but I have always returned a vector from a function that produced it instead of adding to a reference parameter.and was wondering if something similar is possible in D.Most of the time it is automatic and a non-issue for arrays.Basically the idea is to define functions as follows: std::vector<double> add_to_vector( double x, std::vector<double> &&v ) { v.push_back(x); return v; }Actually, when the name of the function is add_to_vector() anyway, there is an obvious side-effect. So, I would not return the result in C++. However, when the name is like make_vector() then I always return the result. The alternatives have many hard questions to answer: void make_vector(vector<double> & v) { // Should I clear v first? // Should I simply start appending to v? // etc. } All of the efficiency of doing that goes out the window when one considers exception safety. Anyway... Too much off topic... :)Is this possible in D?T[] append(T)(T[] arr, T value) { arr ~= value; return arr; } Done. :) Slices consist of two members that are cheap to copy: The number of elements and the pointer to the first element. It is already as efficient as move in C++. You should also read the following article: http://dlang.org/d-array-article.html Ali
Mar 06 2014