Re: Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 5 October 2018 at 19:31:56 UTC, Jon Degenhardt wrote:

On Friday, 5 October 2018 at 16:34:32 UTC, Paul Backus wrote:
You can thread multiple arguments through to `each` using 
`std.range.zip`:


tenRandomNumbers
.zip(repeat(output))
.each!(unpack!((n, output) => 
output.appendln(n.to!string)));


Full code: https://run.dlang.io/is/Qe7uHt


Very interesting, thanks. It's a clever way to avoid the 
delegate capture issue.


(Aside: A nested function that accesses 'output' from lexical 
context has the same issue as delegates wrt to capturing the 
variable.)


Note that this solution may do a lot of output and hence running 
of the destructor.


Use: `.zip(repeat())` to avoid that.




Re: DMD release build being faster than debug!

2018-10-05 Thread Per Nordlöw via Digitalmars-d-learn

On Friday, 5 October 2018 at 16:57:03 UTC, Seb wrote:
Yeah BUILD more or less only defines in which folder the 
binaries will be stored as the default BUILD was RELEASE 
historically and the real release build can take a while and 
shouldn't be used by default (bad newcomer experience).
We tried to change the default BUILD to debug but it was a mess 
with the CIs :/


Got it. Thanks, Seb.


Re: Alligned gc allocation of struct

2018-10-05 Thread Sjoerd Nijboer via Digitalmars-d-learn

On Friday, 5 October 2018 at 14:55:04 UTC, Dennis wrote:

On Friday, 5 October 2018 at 10:03:35 UTC, Kagamin wrote:

GC allocations are 16 bytes aligned.


Is that an implementation detail or well-defined behavior?


The GC_Allocator doesn't support alignedAllocate from the 
IAllocate interface, which is kinda unfortunate.

So I'm a little worried that this might change in the future.


Re: Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-05 Thread Jon Degenhardt via Digitalmars-d-learn

On Friday, 5 October 2018 at 16:34:32 UTC, Paul Backus wrote:
On Friday, 5 October 2018 at 06:56:49 UTC, Nicholas Wilson 
wrote:
On Friday, 5 October 2018 at 06:44:08 UTC, Nicholas Wilson 
wrote:
Alas is does not because each does not accept additional 
argument other than the range. Shouldn't be hard to fix 
though.


https://issues.dlang.org/show_bug.cgi?id=19287


You can thread multiple arguments through to `each` using 
`std.range.zip`:


tenRandomNumbers
.zip(repeat(output))
.each!(unpack!((n, output) => 
output.appendln(n.to!string)));


Full code: https://run.dlang.io/is/Qe7uHt


Very interesting, thanks. It's a clever way to avoid the delegate 
capture issue.


(Aside: A nested function that accesses 'output' from lexical 
context has the same issue as delegates wrt to capturing the 
variable.)


Re: DMD release build being faster than debug!

2018-10-05 Thread Seb via Digitalmars-d-learn

On Friday, 5 October 2018 at 14:11:22 UTC, Per Nordlöw wrote:

I just noticed that building DMD~master via

make -f posix.mak BUILD=debug

currently takes 3.2 secs while building it via

make -f posix.mak BUILD=release

takes only 3.0 secs on my Ubuntu 18.04 64-bit machine!

Are there more DMD switches other than `BUILD=release` I need 
to activate to produce the fastest possible compiler binary? 
Apart for compiling it with LDC, that is.


Yeah BUILD more or less only defines in which folder the binaries 
will be stored as the default BUILD was RELEASE historically and 
the real release build can take a while and shouldn't be used by 
default (bad newcomer experience).
We tried to change the default BUILD to debug but it was a mess 
with the CIs :/


Re: Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-05 Thread Paul Backus via Digitalmars-d-learn

On Friday, 5 October 2018 at 06:56:49 UTC, Nicholas Wilson wrote:
On Friday, 5 October 2018 at 06:44:08 UTC, Nicholas Wilson 
wrote:
Alas is does not because each does not accept additional 
argument other than the range. Shouldn't be hard to fix though.


https://issues.dlang.org/show_bug.cgi?id=19287


You can thread multiple arguments through to `each` using 
`std.range.zip`:


tenRandomNumbers
.zip(repeat(output))
.each!(unpack!((n, output) => 
output.appendln(n.to!string)));


Full code: https://run.dlang.io/is/Qe7uHt


Re: Alligned gc allocation of struct

2018-10-05 Thread Dennis via Digitalmars-d-learn

On Friday, 5 October 2018 at 10:03:35 UTC, Kagamin wrote:

GC allocations are 16 bytes aligned.


Is that an implementation detail or well-defined behavior?


Re: DMD release build being faster than debug!

2018-10-05 Thread Per Nordlöw via Digitalmars-d-learn

On Friday, 5 October 2018 at 14:11:22 UTC, Per Nordlöw wrote:
Are there more DMD switches other than `BUILD=release` I need 
to activate to produce the fastest possible compiler binary? 
Apart for compiling it with LDC, that is.


Ahh, that wasn't so hard to find once I looked inside the correct 
posix.mak. I guess I should do


make -f posix.mak BUILD=release ENABLE_RELEASE=1



DMD release build being faster than debug!

2018-10-05 Thread Per Nordlöw via Digitalmars-d-learn

I just noticed that building DMD~master via

make -f posix.mak BUILD=debug

currently takes 3.2 secs while building it via

make -f posix.mak BUILD=release

takes only 3.0 secs on my Ubuntu 18.04 64-bit machine!

Are there more DMD switches other than `BUILD=release` I need to 
activate to produce the fastest possible compiler binary? Apart 
for compiling it with LDC, that is.


Re: Template/mixin ideas?

2018-10-05 Thread Stanislav Blinov via Digitalmars-d-learn

On Thursday, 4 October 2018 at 01:12:04 UTC, Chris Katko wrote:


What's the alternative to using strings... for strings?


Since the purpose is terminal output, you could just make a 
custom formatter, something like this:


https://run.dlang.io/is/F51UCZ



Re: Alligned gc allocation of struct

2018-10-05 Thread Sjoerd Nijboer via Digitalmars-d-learn

On Friday, 5 October 2018 at 10:03:35 UTC, Kagamin wrote:

GC allocations are 16 bytes aligned.


That's perfect. Thank you!


Re: Alligned gc allocation of struct

2018-10-05 Thread Kagamin via Digitalmars-d-learn

GC allocations are 16 bytes aligned.


Re: Template/mixin ideas?

2018-10-05 Thread Anonymouse via Digitalmars-d-learn

On Wednesday, 3 October 2018 at 11:01:53 UTC, Chris Katko wrote:
I've got this simple task but I'm trying to perfect it as best 
I can to learn something in the process.


I have Linux terminal ASCII codes for coloring terminal output.

string red(string) { /* ... */ }

"Hello world".red => "\033[31mHello World\033[0m"

which translates to "[red]Hello World[reset to normal text]".

I have to do some slight trickery so I can chain them. But it 
all works fine. __The function is the same__ no matter what 
kind of color, bold, etc attribute I want. The only difference 
is the tag/prefix string.


So I have a table (or enum):
enum colors{
 reset = "\033[0m",
 red = "\033[31m",
 bold = "\033[1m" //...
 }

Absolute perfection would be some way to add a single line to 
that enum (or table) and magically get a new function. I add 
"blue" with its prefix code to the enum and immediately I can 
do:


"hello world".blue

Add yellow = "\033..." and I can do:

"hello world".bold.yellow


https://run.dlang.io/gist/run-dlang/e0d0bcebe6c4edcc3cd0c2858183357d?compiler=dmd

https://issues.dlang.org/show_bug.cgi?id=19286 prevents us from 
using static foreaches to declare the aliases.


Alligned gc allocation of struct

2018-10-05 Thread Sjoerd Nijboer via Digitalmars-d-learn
I've got a `struct Foo{ubyte16 field1, field2 fieldn;}` for 
which I would like a heap allocation `Foo* foo = new Foo();` But 
the fields itsself must be 16 bytes aligned for SIMD instructions.

Is there a neat way to do this in D?
As far as I can tell the GC_allocator doesn't do aligned 
allocations by default.


Re: Template/mixin ideas?

2018-10-05 Thread Sebastiaan Koppe via Digitalmars-d-learn

On Thursday, 4 October 2018 at 01:12:04 UTC, Chris Katko wrote:
The mixin part wouldn't be slowed by strings, right? So the 
"slowness" is the invokation part which changes strings and 
forces GC allocations, I guess?

Yep, that is right.


What's the alternative to using strings... for strings?
During the concatenation phase you'll use an Appender. Afterwards 
you retrieve the resulting string from the appender. It is very 
similar to a StringBuilder in other languages.


See std.array.appender


Re: Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 5 October 2018 at 06:44:08 UTC, Nicholas Wilson wrote:
Alas is does not because each does not accept additional 
argument other than the range. Shouldn't be hard to fix though.


https://issues.dlang.org/show_bug.cgi?id=19287


Re: Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-05 Thread Jon Degenhardt via Digitalmars-d-learn

On Friday, 5 October 2018 at 06:44:08 UTC, Nicholas Wilson wrote:
On Friday, 5 October 2018 at 06:22:57 UTC, Nicholas Wilson 
wrote:
tenRandomNumbers.each!((n,o) => 
o.appendln(n.to!string))(output);


or

tenRandomNumbers.each!((n, ref o) => 
o.appendln(n.to!string))(output);


should hopefully do the trick (run.dlang.io seems to be down 
atm).




Alas is does not because each does not accept additional 
argument other than the range. Shouldn't be hard to fix though.


Yeah, that's what I was seeing also. Thanks for taking a look. Is 
there perhaps a way to limit the scope of the delegate to the 
local function? Something that would tell the compiler the 
delegate has a lifetime shorter than the struct.


One specific it points out is that this a place where the 
BufferedOutputRange I wrote cannot be used interchangeably with 
other output ranges. It's minor, but the intent was to be able to 
pass this anyplace an output range could be used.


Re: Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 5 October 2018 at 06:22:57 UTC, Nicholas Wilson wrote:
tenRandomNumbers.each!((n,o) => 
o.appendln(n.to!string))(output);


or

tenRandomNumbers.each!((n, ref o) => 
o.appendln(n.to!string))(output);


should hopefully do the trick (run.dlang.io seems to be down 
atm).




Alas is does not because each does not accept additional argument 
other than the range. Shouldn't be hard to fix though.


Re: Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 5 October 2018 at 03:27:17 UTC, Jon Degenhardt wrote:
I got the compilation error in the subject line when trying to 
create a range via std.range.generate. Turns out this was 
caused by trying to create a closure for 'generate' where the 
closure was accessing a struct containing a destructor.


The fix was easy enough: write out the loop by hand rather than 
using 'generate' with a closure. What I'm wondering/asking is 
if there alternate way to do this that would enable the 
'generate' approach. This is more curiosity/learning at this 
point.


Below is a stripped down version of what I was doing. I have a 
struct for output buffering. The destructor writes any data 
left in the buffer to the output stream. This gets passed to 
routines performing output. It was this context that I created 
a generator that wrote to it.


example.d-
struct BufferedStdout
{
import std.array : appender;

private auto _outputBuffer = appender!(char[]);

~this()
{
import std.stdio : write;
write(_outputBuffer.data);
_outputBuffer.clear;
}

void appendln(T)(T stuff)
{
import std.range : put;
put(_outputBuffer, stuff);
put(_outputBuffer, "\n");
}
}

void foo(BufferedStdout output)
{
import std.algorithm : each;
import std.conv : to;
import std.range: generate, takeExactly;
import std.random: Random, uniform, unpredictableSeed;

auto randomGenerator = Random(unpredictableSeed);
auto randomNumbers = generate!(() => uniform(0, 1000, 
randomGenerator));

auto tenRandomNumbers = randomNumbers.takeExactly(10);
tenRandomNumbers.each!(n => output.appendln(n.to!string));
}

void main(string[] args)
{
foo(BufferedStdout());
}
End of  example.d-

Compiling the above results in:

   $ dmd example.d
   example.d(22): Error: variable `example.foo.output` has 
scoped destruction, cannot build closure


As mentioned, using a loop rather than 'generate' works fine, 
but help with alternatives that would use generate would be 
appreciated.


The actual buffered output struct has more behind it than shown 
above, but not too much. For anyone interested it's here:  
https://github.com/eBay/tsv-utils/blob/master/common/src/tsvutil.d#L358


tenRandomNumbers.each!((n,o) => o.appendln(n.to!string))(output);

or

tenRandomNumbers.each!((n, ref o) => 
o.appendln(n.to!string))(output);


should hopefully do the trick (run.dlang.io seems to be down atm).


The problem is that `output` is captured by the delegate and this 
somehow causes problems (idk what or why). If the (perviously 
captured) variables are instead passed as parameters then there 
is no need to create a closure for the variable, so no problem.
This is also the way to ensure that lambdas are @nogc if you ever 
need that.