Re: GC and void[N] in struct

2018-08-06 Thread vit via Digitalmars-d-learn

On Monday, 6 August 2018 at 21:23:36 UTC, Paul Backus wrote:

On Monday, 6 August 2018 at 20:22:36 UTC, vit wrote:
On Monday, 6 August 2018 at 19:56:03 UTC, Steven Schveighoffer 
wrote:


BTW, is there a reason you aren't just using Algebraic?

https://dlang.org/phobos/std_variant.html#.Algebraic

-Steve


primarily visit for Algebraic isn't pure, @nogc, @safe, 
nothrow.


I wrote the 'sumtype' package to solve this exact problem:

https://code.dlang.org/packages/sumtype


I'm using simpler (and less powerful) version with different  
visit/visitor syntax:



struct Foo{
string foo;
}
struct Bar1{
string bar;
}
struct Bar2{
string bar;
}

void main()pure nothrow @safe @nogc{
Variant!(true, Foo, Bar1, Bar2) var; ///Nullable == true

static visit(T)(auto ref const(T) x, string def = ""){
import std.experimental.all;

static if(is(T == Foo)){
return x.foo;
}
else static if(false
|| is(T == Bar1)
|| is(T == Bar2)
){
return x.bar;
}
else static if(is(T == typeof(null))){
return def;
}
else static assert(0, "no impl");
}

assert(var.isa!null);
assert(var.visitor!visit("null") == "null");

var = Foo("foo");
assert(var.isa!Foo);
assert(var.visitor!visit == "foo");

var = Bar1("bar1");
assert(var.isa!Bar1);
assert(var.visitor!visit == "bar1");

var = Bar2("bar2");
assert(var.isa!Bar2);
assert(var.visitor!visit == "bar2");

var = null;
assert(var.isa!null);

	auto var2 = Variant!(false, Foo, Bar1, 
Bar2)(Foo("foo"));///Nullable == false


assert(var2.visitor!visit == "foo");
assert(var2.as!Foo.foo == "foo");

///var2 = null; //error, variant is not null


}

full code: https://dpaste.dzfl.pl/d83ecca23694


Re: GC and void[N] in struct

2018-08-06 Thread Paul Backus via Digitalmars-d-learn

On Monday, 6 August 2018 at 20:22:36 UTC, vit wrote:
On Monday, 6 August 2018 at 19:56:03 UTC, Steven Schveighoffer 
wrote:


BTW, is there a reason you aren't just using Algebraic?

https://dlang.org/phobos/std_variant.html#.Algebraic

-Steve


primarily visit for Algebraic isn't pure, @nogc, @safe, nothrow.


I wrote the 'sumtype' package to solve this exact problem:

https://code.dlang.org/packages/sumtype


Re: scope variable values assigned to non-scope this.placeholder

2018-08-06 Thread vit via Digitalmars-d-learn
On Monday, 6 August 2018 at 20:29:29 UTC, Alexandru Ermicioi 
wrote:

Hi Dlang community!

I've been playing with dip1000 and scope storage class and 
stumbled upon a strange error that I can't to understand yet. 
Here is minimized version of code that generates the error:


[...]


Parameter values must be `return scope` and this need to be in 
compiler: https://issues.dlang.org/show_bug.cgi?id=19097


scope variable values assigned to non-scope this.placeholder

2018-08-06 Thread Alexandru Ermicioi via Digitalmars-d-learn

Hi Dlang community!

I've been playing with dip1000 and scope storage class and 
stumbled upon a strange error that I can't to understand yet. 
Here is minimized version of code that generates the error:


The link: https://run.dlang.io/is/rg2Odu
--
import std.stdio;
import std.range;
import std.algorithm;
@safe:
class C {
const int*[] placeholder;

this(scope int*[] values) {
this.placeholder = values;
}
}

void main()
{
auto array = iota(0, 20).map!((int i) => new int(i)).array;

auto c = new C(array);

writeln(c.placeholder.map!(p => *p));
}
--

I'm not sure what I'm doing wrong, but from what I understand it 
should check 'this' lifetime to lifetime of scoped 'values' and 
error only in case when passed value has shorter lifetime than 
the container itself.


I'll be thankful if someone could explain what is wrong with this 
example.


Regards,
Alexandru.


Re: GC and void[N] in struct

2018-08-06 Thread vit via Digitalmars-d-learn
On Monday, 6 August 2018 at 19:56:03 UTC, Steven Schveighoffer 
wrote:


BTW, is there a reason you aren't just using Algebraic?

https://dlang.org/phobos/std_variant.html#.Algebraic

-Steve


primarily visit for Algebraic isn't pure, @nogc, @safe, nothrow.


Re: GC and void[N] in struct

2018-08-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/6/18 3:43 PM, Steven Schveighoffer wrote:

On 8/6/18 2:59 PM, vit wrote:

On Monday, 6 August 2018 at 18:28:11 UTC, Steven Schveighoffer wrote:

On 8/6/18 2:22 PM, vit wrote:

Hello,
I have this struct:

struct S{
 uint kind;
 void[N] data_;


define "N"



}

Instances of struct S are allocated by standard GC new and S.data_ 
can contain pointers/ranges to GC allocated data.
If is GC disabled then  program run fine. But when is GC enabled 
then it fail randomly.


how does it fail?




private auto sizeOf(T)(){return T.sizeof;}


Hm... wouldn't enum sizeOf(T) = T.sizeof work better?



struct ExprImpl(Ts...){
 enum N = max(staticMap!(sizeOf, Ts));


This is clever!



 invariant(kind_ != 0);
 uint kind_ = 0;
 void[N] data_;

 this(T)(auto ref T x){/+emplace T to data_ and change kind_ to 
something != 0+/}

}

Ts == structs



data change without triggering invariant after allocation in other 
part of program.


Most definitely this is alignment problem.

Here is what I *think* is happening:

1. You are constructing one of these structs, and storing a pointer as 
the T type.

2. You are on a 64-bit CPU.
3. The pointer is misaligned on the CPU, so when the GC scans this 
struct to see if it's pointing at anything, it sees one half as the 
kind_ value, and the other half is half of the pointer.
4. It misses the object being pointed at by the T inside the struct, and 
collects it, leaving a dangling pointer.

5. Memory corruption.

when you put the void[N] member *first*, it can properly align the item 
(most cases where the compiler is placing data, it starts out aligned) 
but this does not guarantee you have proper alignment, as void[N] has no 
alignment constraints.


I'd recommend instead, changing the uint kind_ to a size_t. This not 
only aligns the void[N] to size_t size, which should put any pointers in 
the right place, but it also makes sure the entire struct is aligned.


BTW, is there a reason you aren't just using Algebraic?

https://dlang.org/phobos/std_variant.html#.Algebraic

-Steve


Re: GC and void[N] in struct

2018-08-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/6/18 2:59 PM, vit wrote:

On Monday, 6 August 2018 at 18:28:11 UTC, Steven Schveighoffer wrote:

On 8/6/18 2:22 PM, vit wrote:

Hello,
I have this struct:

struct S{
 uint kind;
 void[N] data_;


define "N"



}

Instances of struct S are allocated by standard GC new and S.data_ 
can contain pointers/ranges to GC allocated data.
If is GC disabled then  program run fine. But when is GC enabled then 
it fail randomly.


how does it fail?




private auto sizeOf(T)(){return T.sizeof;}


Hm... wouldn't enum sizeOf(T) = T.sizeof work better?



struct ExprImpl(Ts...){
     enum N = max(staticMap!(sizeOf, Ts));


This is clever!



     invariant(kind_ != 0);
     uint kind_ = 0;
     void[N] data_;

     this(T)(auto ref T x){/+emplace T to data_ and change kind_ to 
something != 0+/}

}

Ts == structs



data change without triggering invariant after allocation in other part 
of program.


Most definitely this is alignment problem.

Here is what I *think* is happening:

1. You are constructing one of these structs, and storing a pointer as 
the T type.

2. You are on a 64-bit CPU.
3. The pointer is misaligned on the CPU, so when the GC scans this 
struct to see if it's pointing at anything, it sees one half as the 
kind_ value, and the other half is half of the pointer.
4. It misses the object being pointed at by the T inside the struct, and 
collects it, leaving a dangling pointer.

5. Memory corruption.

when you put the void[N] member *first*, it can properly align the item 
(most cases where the compiler is placing data, it starts out aligned) 
but this does not guarantee you have proper alignment, as void[N] has no 
alignment constraints.


I'd recommend instead, changing the uint kind_ to a size_t. This not 
only aligns the void[N] to size_t size, which should put any pointers in 
the right place, but it also makes sure the entire struct is aligned.


-Steve


Re: GC and void[N] in struct

2018-08-06 Thread vit via Digitalmars-d-learn

On Monday, 6 August 2018 at 19:17:58 UTC, nkm1 wrote:

On Monday, 6 August 2018 at 18:22:24 UTC, vit wrote:

Hello,
I have this struct:

struct S{
uint kind;
void[N] data_;

}

Instances of struct S are allocated by standard GC new and 
S.data_ can contain pointers/ranges to GC allocated data.
If is GC disabled then  program run fine. But when is GC 
enabled then it fail randomly.


If the definition of S look like this:

struct S{
void[N] data_;
uint kind;
}

then program run fine with GC.enable.

Whats the problem? Something with alignment?


Probably. Try something like:

struct S
{
uint kind;
align((void *).alignof) void[N] data_;
}

And see if it solves the problem.


align((void *).alignof) work, thanks.


Re: GC and void[N] in struct

2018-08-06 Thread nkm1 via Digitalmars-d-learn

On Monday, 6 August 2018 at 18:22:24 UTC, vit wrote:

Hello,
I have this struct:

struct S{
uint kind;
void[N] data_;

}

Instances of struct S are allocated by standard GC new and 
S.data_ can contain pointers/ranges to GC allocated data.
If is GC disabled then  program run fine. But when is GC 
enabled then it fail randomly.


If the definition of S look like this:

struct S{
void[N] data_;
uint kind;
}

then program run fine with GC.enable.

Whats the problem? Something with alignment?


Probably. Try something like:

struct S
{
uint kind;
align((void *).alignof) void[N] data_;
}

And see if it solves the problem.


Re: GC and void[N] in struct

2018-08-06 Thread vit via Digitalmars-d-learn
On Monday, 6 August 2018 at 18:28:11 UTC, Steven Schveighoffer 
wrote:

On 8/6/18 2:22 PM, vit wrote:

Hello,
I have this struct:

struct S{
     uint kind;
     void[N] data_;


define "N"



}

Instances of struct S are allocated by standard GC new and 
S.data_ can contain pointers/ranges to GC allocated data.
If is GC disabled then  program run fine. But when is GC 
enabled then it fail randomly.


how does it fail?

-Steve



private auto sizeOf(T)(){return T.sizeof;}

struct ExprImpl(Ts...){
enum N = max(staticMap!(sizeOf, Ts));

invariant(kind_ != 0);
uint kind_ = 0;
void[N] data_;

this(T)(auto ref T x){/+emplace T to data_ and change kind_ 
to something != 0+/}

}

Ts == structs



data change without triggering invariant after allocation in 
other part of program.





Re: GC and void[N] in struct

2018-08-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/6/18 2:22 PM, vit wrote:

Hello,
I have this struct:

struct S{
     uint kind;
     void[N] data_;


define "N"



}

Instances of struct S are allocated by standard GC new and S.data_ can 
contain pointers/ranges to GC allocated data.
If is GC disabled then  program run fine. But when is GC enabled then it 
fail randomly.


how does it fail?

-Steve


GC and void[N] in struct

2018-08-06 Thread vit via Digitalmars-d-learn

Hello,
I have this struct:

struct S{
uint kind;
void[N] data_;

}

Instances of struct S are allocated by standard GC new and 
S.data_ can contain pointers/ranges to GC allocated data.
If is GC disabled then  program run fine. But when is GC enabled 
then it fail randomly.


If the definition of S look like this:

struct S{
void[N] data_;
uint kind;
}

then program run fine with GC.enable.

Whats the problem? Something with alignment?





Re: Prime number

2018-08-06 Thread Cym13 via Digitalmars-d-learn

On Thursday, 2 August 2018 at 14:37:56 UTC, Greatsam4sure wrote:

On Thursday, 2 August 2018 at 09:35:20 UTC, Cym13 wrote:
On Thursday, 2 August 2018 at 08:30:05 UTC, Greatsam4sure 
wrote:
I know D is very powerful from my little experience. What is 
the idiomatic way to get prime numbers say from 1-30 without 
using loops(outer and inner loop). Can map, filter, fold etc 
in algorithm be use.  Pls show some code with chain call.


I can easily achieve even numberd and odd numbers using 
filter. But prime numbers I have to use 2loops.


I will appreciate any help,just a newbie in D


Denis' answer is good but I'd like to add that the idiomatic D 
solution is to use whatever tool is the most adequate to solve 
the issue. If two loops is more natural it wouldn't make much 
sense to force yourself to use range functions (even though 
I'd obviously understand that stand to learn to use them).




Thanks, I like the idea of using helper function from algorithm 
module to do the magic instead of loops.  I want to know How To 
optimize it to efficient.

I will appreciate any help.


Computing prime numbers efficiently would require something more 
complex like an Atkin sieve which I doubt will be very easy to 
implement without loop.


That said, to start optimizing without changing the algorithm you 
can profile your code with -profile to see where you're spending 
time that you can shave off and rewrite the code to accelerate 
those parts. You should really start by changing the algorithm 
though.


I will also appreciate a link to a comprehensive tutorial on 
the algorithm module. The documentation did not give me all the 
help I needed


Not specifically on the algorithm module but I'd recommend 
reading [1] for a good intro to D from basics to advanced topics.


For algorithms especially, I'd recommend reading on templates [2] 
and ranges [3].


Especially one thing you should know to understand the concepts 
behind most range-based functions is that most of them try to 
work on infinite sequences of things and therefore make 
assumptions only about the first items and never about the last 
ones. That's why functions like std.algorithm.find don't just 
return the element or its position but the sub-sequence starting 
at that element. There are exceptions though, and this comment 
may not make much sense at first so feel free to ignore it for 
the moment, but hopefully it'll come back to you when you need it.


[1]: https://ddili.org/ders/d.en/index.html
[2]: https://ddili.org/ders/d.en/templates.html
[3]: https://ddili.org/ders/d.en/ranges.html


Re: foreach on a tuple using aliases

2018-08-06 Thread Timon Gehr via Digitalmars-d-learn

On 06.08.2018 14:37, Steven Schveighoffer wrote:

On 8/5/18 11:40 AM, Timon Gehr wrote:

On 05.08.2018 16:07, Steven Schveighoffer wrote:

So is this a bug? Is it expected?


It's a bug. The two copies of 'item' are not supposed to be the same 
symbol. (Different types -> different symbols.)


Yep. I even found it has nothing to do with foreach on a tuple: 
https://run.dlang.io/is/vxQlIi


I wonder though, it shouldn't really be a different type that triggers 
it, right?


It shouldn't.


Re: Why does templated interface function return something different than final function?

2018-08-06 Thread Timoses via Digitalmars-d-learn
On Thursday, 2 August 2018 at 20:35:57 UTC, Steven Schveighoffer 
wrote:


Looking at the AST, it appears that toImpl doesn't recognize 
what inout(iface) is:


toImpl!(string, inout(iface))
{
@system string toImpl(ref inout(iface) value)
{
import std.array : appender;
import std.format : FormatSpec, formatValue;
Appender!string w = appender();
FormatSpec!char f = FormatSpec;
formatValue(w, value, f);
return w.data();
}

}

Vs. the nice neat call for const(iface)

toImpl!(string, const(iface))
{
@system string toImpl(const(iface) value)
{
return toStr(value);
}

}

Note the ref there, too. This means it can't cast to const. I 
wonder if that's an issue.


-Steve


Thanks for the insight. To me it sounds like std.conv `toImpl` 
doesn't properly handle inout types in this case.


Re: dtoh

2018-08-06 Thread Seb via Digitalmars-d-learn

On Monday, 6 August 2018 at 13:28:05 UTC, Laeeth Isharc wrote:

Hi Walter.

Can dtoh be open-sourced now that dmd is?


Laeeth.


Better write Walter a direct mail. He doesn't check the learn NG 
very often.


dtoh

2018-08-06 Thread Laeeth Isharc via Digitalmars-d-learn

Hi Walter.

Can dtoh be open-sourced now that dmd is?


Laeeth.


Re: foreach on a tuple using aliases

2018-08-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/5/18 11:40 AM, Timon Gehr wrote:

On 05.08.2018 16:07, Steven Schveighoffer wrote:

So is this a bug? Is it expected?


It's a bug. The two copies of 'item' are not supposed to be the same 
symbol. (Different types -> different symbols.)


Yep. I even found it has nothing to do with foreach on a tuple: 
https://run.dlang.io/is/vxQlIi


I wonder though, it shouldn't really be a different type that triggers 
it, right? I mean 2 separate aliases to different variables that are the 
same type, I would hope would re-instantiate. Otherwise something like 
.offsetof would be wrong.





Is it too difficult to fix?
...


Unlikely.


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

-Steve


Re: foreach on a tuple using aliases

2018-08-06 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/5/18 10:48 AM, Alex wrote:

void main()
{
     Foo foo;
     assert(isFoo!foo);
     static struct X { int i; Foo foo; }
     X x;
     static foreach(i, item; typeof(x).tupleof)
     static if(is(typeof(item) == Foo))  // line A
     static assert(isFoo!item);  // line B
     else
     static assert(!isFoo!item);
}


I did try static foreach, but it doesn't work.

The difference here is you are using typeof(x).tupleof, whereas I want 
x.tupleof.


Note that in my real code, I do more than just the static assert, I want 
to use item as a reference to the real field in x.


-Steve


Re: getProtection gives different result when member is accessed via getMember

2018-08-06 Thread Basile B. via Digitalmars-d-learn

On Sunday, 5 August 2018 at 01:48:08 UTC, Yuxuan Shui wrote:

file1.d:
import std.stdio;

file2.d:
import file1;
pragma(msg, __traits(getProtection, __traits(getMember, m1, 
"std"))); // public

pragma(msg, __traits(getProtection, m1.std)); // private

Bug? Intended?


reported for you https://issues.dlang.org/show_bug.cgi?id=19144


Re: getProtection gives different result when member is accessed via getMember

2018-08-06 Thread Basile B. via Digitalmars-d-learn

On Sunday, 5 August 2018 at 01:48:08 UTC, Yuxuan Shui wrote:

file1.d:
import std.stdio;

file2.d:
import file1;
pragma(msg, __traits(getProtection, __traits(getMember, m1, 
"std"))); // public

pragma(msg, __traits(getProtection, m1.std)); // private

Bug? Intended?


It's a bug since in both cases it's the same symbol how can the 
result be different ?