Re: pop & popFront combined

2016-05-11 Thread Nordlöw via Digitalmars-d-learn

On Saturday, 1 November 2014 at 13:22:34 UTC, Nordlöw wrote:

https://github.com/nordlow/justd/blob/master/range_ex.d#L14


Moved here:

https://github.com/nordlow/phobos-next/blob/master/src/range_ex.d#L66


Re: pop popFront combined

2014-11-02 Thread via Digitalmars-d-learn

On Saturday, 1 November 2014 at 14:19:56 UTC, Nordlöw wrote:

On Saturday, 1 November 2014 at 13:54:31 UTC, Nordlöw wrote:
On Saturday, 1 November 2014 at 13:38:22 UTC, Marc Schütz 
wrote:

If you want to avoid the temporary variable, you could write:

  scope(success) r.popFront;
  return r.moveFront;


Does this solution cost performance?


I guess we have to look at the assembler output to be sure. Is 
there a convenient way to do this in LDC?


ldc2 -O3 -output-s -c test.d

Generates test.s.


Re: pop popFront combined

2014-11-02 Thread via Digitalmars-d-learn

On Saturday, 1 November 2014 at 13:54:31 UTC, Nordlöw wrote:

On Saturday, 1 November 2014 at 13:38:22 UTC, Marc Schütz wrote:

If you want to avoid the temporary variable, you could write:

   scope(success) r.popFront;
   return r.moveFront;


Does this solution cost performance?


I think DMD doesn't generate good code for it; IIRC it lowers 
scope(success) to a strange construct with an invisible variable 
and a try/catch. Don't know the reasons for this, maybe it has 
changed by now. Theoretically it would just need to move the 
contents of the scope(success) after the evaluation of the 
returned expression, which is cheap.


Re: pop popFront combined

2014-11-02 Thread Nordlöw

On Sunday, 2 November 2014 at 11:46:19 UTC, Marc Schütz wrote:
I think DMD doesn't generate good code for it; IIRC it lowers 
scope(success) to a strange construct with an invisible 
variable and a try/catch. Don't know the reasons for this, 
maybe it has changed by now. Theoretically it would just need 
to move the contents of the scope(success) after the evaluation 
of the returned expression, which is cheap.


Are there cases in LDC where

auto e = r.moveFront;
r.popFront;
return e;

generates code less efficient than

scope(success) r.popFront;
return r.moveFront;

because of the extra assignment?


Re: pop popFront combined

2014-11-02 Thread via Digitalmars-d-learn

On Sunday, 2 November 2014 at 12:29:14 UTC, Nordlöw wrote:

On Sunday, 2 November 2014 at 11:46:19 UTC, Marc Schütz wrote:
I think DMD doesn't generate good code for it; IIRC it lowers 
scope(success) to a strange construct with an invisible 
variable and a try/catch. Don't know the reasons for this, 
maybe it has changed by now. Theoretically it would just need 
to move the contents of the scope(success) after the 
evaluation of the returned expression, which is cheap.


Are there cases in LDC where

auto e = r.moveFront;
r.popFront;
return e;

generates code less efficient than

scope(success) r.popFront;
return r.moveFront;

because of the extra assignment?


I'm not sure. If the element type has a postblit, there might be 
some obscure corner case where the language specification 
requires a copy if you declare a named variable. In general I 
would expect no (language level) copy to take place. The result 
of `moveFront` can just be moved into the yet uninitialized `e`, 
which later can be moved up to the caller. These are simple 
bitblits, not copies.


Re: pop popFront combined

2014-11-01 Thread Nordlöw

On Saturday, 20 September 2014 at 19:23:46 UTC, Jakob Ovrum wrote:

If you want move semantics, use `moveFront`.


But x.moveFront doesn't modify x.

What I want is to transform my uses of std.range from

if (!x.empty)
{
x.front.doStuff;
x.popFront;
}

into

if (!x.empty)
if (auto front = x.stealFront)
{
front.doStuff;
}

This is more functional/atomic, that is it reduces the risk of 
accidentally forgetting to call popFront at the end.


Destroy!


Re: pop popFront combined

2014-11-01 Thread Nordlöw

On Saturday, 1 November 2014 at 11:43:28 UTC, Nordlöw wrote:

if (!x.empty)
if (auto front = x.stealFront)
{
front.doStuff;
}

This is more functional/atomic, that is it reduces the risk of 
accidentally forgetting to call popFront at the end.


Forgot my explicit question:

So why isn't something like x.stealFront already in Phobos?


Re: pop popFront combined

2014-11-01 Thread Nordlöw

On Saturday, 20 September 2014 at 19:40:02 UTC, AsmMan wrote:

Is this function part of phobos library? if so, where?


It's in std.range.


Re: pop popFront combined

2014-11-01 Thread Nordlöw

On Saturday, 1 November 2014 at 11:45:25 UTC, Nordlöw wrote:

So why isn't something like x.stealFront already in Phobos?


First try here:

https://github.com/nordlow/justd/blob/master/range_ex.d#L14

Please comment!


Re: pop popFront combined

2014-11-01 Thread Nordlöw

On Saturday, 1 November 2014 at 13:22:34 UTC, Nordlöw wrote:

https://github.com/nordlow/justd/blob/master/range_ex.d#L14

Please comment!


What's the recommended way of making stealFront and stealBack 
inout here? Can I somehow use auto ref together with inout?


Re: pop popFront combined

2014-11-01 Thread anonymous via Digitalmars-d-learn

On Saturday, 1 November 2014 at 13:22:34 UTC, Nordlöw wrote:

On Saturday, 1 November 2014 at 11:45:25 UTC, Nordlöw wrote:

So why isn't something like x.stealFront already in Phobos?


First try here:

https://github.com/nordlow/justd/blob/master/range_ex.d#L14

Please comment!


That is:


auto ref stealFront(R)(ref R r)
{
import std.range: moveFront, popFront;
auto e = r.moveFront;
r.popFront;
return e;
}


`auto ref` is nonsense here. You can't return a reference to `e`
as
it's a local variable.


Re: pop popFront combined

2014-11-01 Thread anonymous via Digitalmars-d-learn

On Saturday, 1 November 2014 at 13:25:03 UTC, Nordlöw wrote:

On Saturday, 1 November 2014 at 13:22:34 UTC, Nordlöw wrote:

https://github.com/nordlow/justd/blob/master/range_ex.d#L14

Please comment!


What's the recommended way of making stealFront and stealBack 
inout here? Can I somehow use auto ref together with inout?


I don't see what you'd need inout for here. stealFront/stealBack 
are not methods.


Re: pop popFront combined

2014-11-01 Thread via Digitalmars-d-learn

On Saturday, 1 November 2014 at 13:30:16 UTC, anonymous wrote:

On Saturday, 1 November 2014 at 13:22:34 UTC, Nordlöw wrote:

On Saturday, 1 November 2014 at 11:45:25 UTC, Nordlöw wrote:

So why isn't something like x.stealFront already in Phobos?


First try here:

https://github.com/nordlow/justd/blob/master/range_ex.d#L14

Please comment!


That is:


auto ref stealFront(R)(ref R r)
{
import std.range: moveFront, popFront;
auto e = r.moveFront;
r.popFront;
return e;
}


`auto ref` is nonsense here. You can't return a reference to `e`
as
it's a local variable.


It's probably intended to mean `auto` + `ref`, not `auto ref`. 
`ref` alone is already sufficient to get type deduction.


Re: pop popFront combined

2014-11-01 Thread anonymous via Digitalmars-d-learn

On Saturday, 1 November 2014 at 13:36:05 UTC, Marc Schütz wrote:

On Saturday, 1 November 2014 at 13:30:16 UTC, anonymous wrote:

[...]

auto ref stealFront(R)(ref R r)
{
import std.range: moveFront, popFront;
auto e = r.moveFront;
r.popFront;
return e;
}

[...]
It's probably intended to mean `auto` + `ref`, not `auto ref`. 
`ref` alone is already sufficient to get type deduction.


But ref is wrong. The function returns a local. Just auto would
be fine.


Re: pop popFront combined

2014-11-01 Thread via Digitalmars-d-learn

On Saturday, 1 November 2014 at 13:25:03 UTC, Nordlöw wrote:

On Saturday, 1 November 2014 at 13:22:34 UTC, Nordlöw wrote:

https://github.com/nordlow/justd/blob/master/range_ex.d#L14

Please comment!


What's the recommended way of making stealFront and stealBack 
inout here? Can I somehow use auto ref together with inout?


If you want to avoid the temporary variable, you could write:

scope(success) r.popFront;
return r.moveFront;


Re: pop popFront combined

2014-11-01 Thread Nordlöw

On Saturday, 1 November 2014 at 13:38:22 UTC, Marc Schütz wrote:

If you want to avoid the temporary variable, you could write:

scope(success) r.popFront;
return r.moveFront;


Does this solution cost performance?


Re: pop popFront combined

2014-11-01 Thread Nordlöw

On Saturday, 1 November 2014 at 13:30:16 UTC, anonymous wrote:

`auto ref` is nonsense here. You can't return a reference to `e`
as
it's a local variable.


My mistake. Thanks.


Re: pop popFront combined

2014-11-01 Thread Nordlöw

On Saturday, 1 November 2014 at 13:36:05 UTC, anonymous wrote:
I don't see what you'd need inout for here. 
stealFront/stealBack are not methods.


inout can be used on free functions aswell. See for example

https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L674


Re: pop popFront combined

2014-11-01 Thread anonymous via Digitalmars-d-learn

On Saturday, 1 November 2014 at 14:01:42 UTC, Nordlöw wrote:

On Saturday, 1 November 2014 at 13:36:05 UTC, anonymous wrote:
I don't see what you'd need inout for here. 
stealFront/stealBack are not methods.


inout can be used on free functions aswell. See for example

https://github.com/nordlow/justd/blob/master/algorithm_ex.d#L674


Sure, but it doesn't buy you anything in these cases, does it? 
You can just drop inout from overlapInOrder. It's fully 
templated. T can be const/immutable and you get a const/immutable 
result. Works fine.


Re: pop popFront combined

2014-11-01 Thread Jakob Ovrum via Digitalmars-d-learn

On Saturday, 1 November 2014 at 11:43:28 UTC, Nordlöw wrote:
On Saturday, 20 September 2014 at 19:23:46 UTC, Jakob Ovrum 
wrote:

If you want move semantics, use `moveFront`.


But x.moveFront doesn't modify x.


It does modify `x` as it leaves `front` in a destroyed and 
default-initialized state, as required by move semantics.



What I want is to transform my uses of std.range from

if (!x.empty)
{
x.front.doStuff;
x.popFront;
}

into

if (!x.empty)
if (auto front = x.stealFront)
{
front.doStuff;
}

This is more functional/atomic, that is it reduces the risk of 
accidentally forgetting to call popFront at the end.


Destroy!


The other half of my post explained why such a `stealFront` is 
problematic.


Re: pop popFront combined

2014-11-01 Thread Nordlöw

On Saturday, 1 November 2014 at 16:10:17 UTC, Jakob Ovrum wrote:
The other half of my post explained why such a `stealFront` is 
problematic.


Got it. Thanks!


Re: pop popFront combined

2014-11-01 Thread Nordlöw

On Saturday, 20 September 2014 at 19:23:46 UTC, Jakob Ovrum wrote:
Sometimes after popping, the previous `front` is no longer 
valid, such as in the case of a buffer being reused. We should


This seems like a error-prone design to me.

I guess performance is the motivation right?

Maybe a future data-flow analysis á lá Rust could come to the 
rescue here ;)


Re: pop popFront combined

2014-11-01 Thread Nordlöw

On Saturday, 20 September 2014 at 19:23:46 UTC, Jakob Ovrum wrote:
Sometimes after popping, the previous `front` is no longer 
valid, such as in the case of a buffer being reused.


Is there a suitable trait we can use to detect this and in turn 
use to disallow stealFront() and stealBack() in these cases?


 We should
be careful about promoting using a previously read `front` 
after `popFront` until we figure out what we want to do about 
these transient ranges.


Re: pop popFront combined

2014-11-01 Thread Nordlöw

On Saturday, 1 November 2014 at 16:10:17 UTC, Jakob Ovrum wrote:

problematic.


What about turning stealFront and stealBack at

https://github.com/nordlow/justd/blob/master/range_ex.d

into mixins?


Re: pop popFront combined

2014-11-01 Thread Nordlöw

On Saturday, 1 November 2014 at 20:48:45 UTC, Nordlöw wrote:
Is there a suitable trait we can use to detect this and in turn 
use to disallow stealFront() and stealBack() in these cases?


Made it a separate new question at

http://forum.dlang.org/thread/onibkzepudfisxtri...@forum.dlang.org#post-onibkzepudfisxtrigsi:40forum.dlang.org


pop popFront combined

2014-09-20 Thread Nordlöw
Is there a reason why popFront doesn't automatically return what 
front does?


If so I'm still missing a combined variant of pop and popFront in 
std.range.

Why isn't such a common operation in Phobos already?


Re: pop popFront combined

2014-09-20 Thread Jakob Ovrum via Digitalmars-d-learn

On Saturday, 20 September 2014 at 18:59:03 UTC, Nordlöw wrote:
Is there a reason why popFront doesn't automatically return 
what front does?


If so I'm still missing a combined variant of pop and popFront 
in std.range.

Why isn't such a common operation in Phobos already?


Sometimes after popping, the previous `front` is no longer valid, 
such as in the case of a buffer being reused. We should be 
careful about promoting using a previously read `front` after 
`popFront` until we figure out what we want to do about these 
transient ranges.


If you want move semantics, use `moveFront`.


Re: pop popFront combined

2014-09-20 Thread AsmMan via Digitalmars-d-learn

On Saturday, 20 September 2014 at 18:59:03 UTC, Nordlöw wrote:
Is there a reason why popFront doesn't automatically return 
what front does?


If so I'm still missing a combined variant of pop and popFront 
in std.range.

Why isn't such a common operation in Phobos already?


So far I know isn't common use return value from popFront() at 
same time it's called. For example, checkout how is:


int[] a = [1,2,3];
foreach(int n; a) {}

is translated:

for(auto r = a; !r.empty; r.popFront())
{
  int n = r.front;
}

to return same as value in front by popFront() save previously 
value is needed:


int popFrontInt(out int[] arr)
{
   int current = arr[0]; // or arr.front
   arr = arr[1 .. $];
   return current;
}

(this isn't exactly like Phobos implementation and is int[]-only, 
btw)


the cost of the 'current' variable may be a bit expansive (one 
extra register use per function call) and useless, since it isn't 
used and a common use is one like the loop.


I think it's well-designed, IMHO...


On Saturday, 20 September 2014 at 18:59:03 UTC, Nordlöw wrote:
If you want move semantics, use `moveFront`.


Is this function part of phobos library? if so, where?


Re: pop popFront combined

2014-09-20 Thread Nordlöw

On Saturday, 20 September 2014 at 19:23:46 UTC, Jakob Ovrum wrote:
Sometimes after popping, the previous `front` is no longer 
valid, such as in the case of a buffer being reused. We should 
be careful about promoting using a previously read `front` 
after `popFront` until we figure out what we want to do about 
these transient ranges.


If you want move semantics, use `moveFront`.


Excellent! Thanks!


Re: pop popFront combined

2014-09-20 Thread Ali Çehreli via Digitalmars-d-learn

On 09/20/2014 11:59 AM, Nordlöw wrote:

Is there a reason why popFront doesn't automatically return what front
does?

If so I'm still missing a combined variant of pop and popFront in
std.range.
Why isn't such a common operation in Phobos already?


It is also related to exception safety. It took the C++ community to 
realize that a Stack data structure with pop() returning the top object 
cannot be made exception safe. The solution was to separate pop() from 
top().


Here is the original paper demonstrating the impossibility:


http://ptgmedia.pearsoncmg.com/imprint_downloads/informit/aw/meyerscddemo/DEMO/MAGAZINE/CA_FRAME.HTM

Here is Herb Sutter's presentation of the solution:

  http://www.gotw.ca/gotw/008.htm

Ali