const of AliasSeq is silently ignored

2019-04-08 Thread Yuxuan Shui via Digitalmars-d-learn



In this example:

const(AliasSeq!(int, int)) a;
pragma(msg, typeof(a)); // (int, int)

This kind of make sense, since AliasSeq is not a "single" type. 
But silently dropping const seems bad, the compiler should 
probably report an error/warning in this case?


ElementType of MapResult is a delegate??

2018-12-08 Thread Yuxuan Shui via Digitalmars-d-learn

This surprised me A LOT:

https://d.godbolt.org/z/82a_GZ

So if I call something.map!().array, I get an array of delegates? 
That makes no sense to me.


Re: Circular reference error gone after inspecting members

2018-08-25 Thread Yuxuan Shui via Digitalmars-d-learn

Issue filed: https://issues.dlang.org/show_bug.cgi?id=19190


Re: Circular reference error gone after inspecting members

2018-08-25 Thread Yuxuan Shui via Digitalmars-d-learn
On Saturday, 25 August 2018 at 14:13:18 UTC, rikki cattermole 
wrote:

On 26/08/2018 2:10 AM, Yuxuan Shui wrote:
The offending code base is a little big and hard to reduce. 
I'll try if code is required, but here is the gist of the 
problem:


This snippet of code in my project:

     ...
     alias tmp = genCode!T;
     enum str = tmp.str; // This line here
     ...

Generate a circular reference error.

However, if I do:

     ...
     alias tmp = genCode!T;
     pragma(msg, __traits(allMembers, tmp));
     enum str = tmp.str; // This line here
     ...

Then the error is gone.

Anyone has any idea what could the problem be?


If that pragma(msg) does indeed make it disappear (check -v to 
confirm), then its a bug.


Alright then. I'll spend sometime and see if I can make a minimal 
example.


Circular reference error gone after inspecting members

2018-08-25 Thread Yuxuan Shui via Digitalmars-d-learn
The offending code base is a little big and hard to reduce. I'll 
try if code is required, but here is the gist of the problem:


This snippet of code in my project:

...
alias tmp = genCode!T;
enum str = tmp.str; // This line here
...

Generate a circular reference error.

However, if I do:

...
alias tmp = genCode!T;
pragma(msg, __traits(allMembers, tmp));
enum str = tmp.str; // This line here
...

Then the error is gone.

Anyone has any idea what could the problem be?


getProtection gives different result when member is accessed via getMember

2018-08-04 Thread Yuxuan Shui via Digitalmars-d-learn

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?


Re: Eponymous template member from a template mixin

2018-08-04 Thread Yuxuan Shui via Digitalmars-d-learn
On Saturday, 4 August 2018 at 21:10:32 UTC, Steven Schveighoffer 
wrote:

On 8/4/18 4:10 PM, Yuxuan Shui wrote:

This doesn't work:

template A() {
 void B() {};
}
template B() {
 mixin A!();
}
void main() {
 B!()();
}

Is this intentional?


I believe mixin templates introduce a new symbol namespace to a 
degree. I doubt you would be able to do something like this.


-Steve


What is the rational behind this?


Eponymous template member from a template mixin

2018-08-04 Thread Yuxuan Shui via Digitalmars-d-learn

This doesn't work:

template A() {
void B() {};
}
template B() {
mixin A!();
}
void main() {
B!()();
}

Is this intentional?


Re: Question on @nothrow

2017-07-05 Thread Yuxuan Shui via Digitalmars-d-learn

On Wednesday, 31 May 2017 at 09:31:48 UTC, Jonathan M Davis wrote:
On Wednesday, May 31, 2017 08:18:07 Vasileios Anagnostopoulos 
via Digitalmars-d-learn wrote:

[...]


Well, if you're not doing checked exceptions, the interesting 
question is really what _doesn't_ throw rather than what 
throws, because if the compiler knows that a function doesn't 
throw, it can optimize out the exception handling mechanisms 
that are normally required.


I don't think this is possible in current D? @nothrow functions 
can still throw Error.


Re: Question on @nothrow

2017-07-05 Thread Yuxuan Shui via Digitalmars-d-learn
On Wednesday, 31 May 2017 at 08:18:07 UTC, Vasileios 
Anagnostopoulos wrote:

Hi,

after reading various articles bout the "supposed" drawbacks of 
checked exceptions I started to have questions on @nothrow. Why 
there exists and not a @throws annotation enforced by the 
compiler? I understand that people are divided on checked 
exceptions and each side has some valid points. But explicitly 
marking a function as throwing "something" is another subject. 
Why have the dlang community reached to the decision to use 
@nothrow and not a @throws?


Adding @throws to a function requires changing all the functions 
downstream. Adding @nothrow doesn't.


Re: How to move append to an array?

2017-05-15 Thread Yuxuan Shui via Digitalmars-d-learn

On Tuesday, 16 May 2017 at 01:34:50 UTC, Stanislav Blinov wrote:

On Tuesday, 16 May 2017 at 01:22:49 UTC, Yuxuan Shui wrote:

Can I expand an array with uninitialized object? Or can I rely 
on the compiler to optimize the initialization away?


Built-in arrays always default-initialize their elements. If 
you need something that unsafe, there's 
std.array.uninitializedArray:


http://dlang.org/phobos/std_array.html#uninitializedArray

What are you trying to achieve?


I just wish ~= could take moved objects.


Re: How to move append to an array?

2017-05-15 Thread Yuxuan Shui via Digitalmars-d-learn

On Monday, 15 May 2017 at 23:36:06 UTC, Stanislav Blinov wrote:

On Monday, 15 May 2017 at 21:38:52 UTC, Yuxuan Shui wrote:

Suppose I have a

struct A {
  @disable this(this);
} x;

How do I append it into an array?

Do I have to do

array.length++;
moveEmplace(x, array[$-1]);

?


moveEmplace is for moving an initialized object into an 
uninitialized one. Use the two-argument move() function:


move(x, array[$-1]);


Can I expand an array with uninitialized object? Or can I rely on 
the compiler to optimize the initialization away?


How to move append to an array?

2017-05-15 Thread Yuxuan Shui via Digitalmars-d-learn

Suppose I have a

struct A {
  @disable this(this);
} x;

How do I append it into an array?

Do I have to do

array.length++;
moveEmplace(x, array[$-1]);

?


code.demangle can't demangle a type.

2017-05-13 Thread Yuxuan Shui via Digitalmars-d-learn

So in this document:

http://yshui.gitlab.io/sdpc/sdpc/parsers/whitespace.html

Part of the type name is still mangled. I found ddox use 
core.demangle.demangleType internally. So I guess code.demangle 
is following behind dmd?


Is there a better way to demangle a name?


Re: Function names and lambdas

2017-04-07 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 6 April 2017 at 18:45:26 UTC, Ali Çehreli wrote:
On 04/06/2017 11:37 AM, Russel Winder via Digitalmars-d-learn 
wrote:

[...]


I think it's just a design choice. C implicitly converts the 
name of the function to a pointer to that function. D requires 
the explicit & operator:


alias Func = int function(int);

int foo(int i) {
return i;
}

void main() {
Func[] funcs = [  ];
}

Close to what you mentioned, name of the function can be used 
as an alias template parameter:


void bar(alias func)() {
func(42);
}

int foo(int i) {
return i;
}

void main() {
bar!foo();
}

Ali


Main reason is probably UFCS.


Re: Comparing two AliasSeq

2017-03-24 Thread Yuxuan Shui via Digitalmars-d-learn
On Saturday, 25 March 2017 at 05:20:44 UTC, Jonathan M Davis 
wrote:
On Saturday, March 25, 2017 04:57:26 Yuxuan Shui via 
Digitalmars-d-learn wrote:

[...]


An AliasSeq isn't really ever a type. AliasSeq!(int, float) is 
a list of types, not a type itself, and is expressions supports 
comparing those in at least some instances, because is 
expressions operate on types, and having them support a list of 
types is useful. Calling AliasSeq!(int, float) a type would be 
like claiming that the (int, float) in foo!(int, float) a type. 
It's a list - a list of template arguments in this case - but 
it's still a list and not itself a type.


[...]


Because I want to make use of the "static foreach unrolling" 
feature (I don't know what's the official name).




[...]




Re: Comparing two AliasSeq

2017-03-24 Thread Yuxuan Shui via Digitalmars-d-learn
On Saturday, 25 March 2017 at 04:23:31 UTC, Jonathan M Davis 
wrote:
On Saturday, March 25, 2017 03:25:27 Yuxuan Shui via 
Digitalmars-d-learn wrote:

In this example:

 import std.range;
 template expandRange(alias R) if 
(isInputRange!(typeof(R))) {

 static if (R.empty)
  alias expandRange = AliasSeq!();
 else
  alias expandRange = AliasSeq!(R.front(),
expandRange!(R.drop(1)));
 }

 ///
 unittest {
 import std.range;
 static assert (is(expandRange!(iota(0,5)):
AliasSeq!(0,1,2,3,4)));
 }

The static assert fails, why?


Well, is expressions normally compare types, not values, and 
AliasSeq!(0, 1, 2, 3, 4), isn't a type and doesn't contain 
types.


static assert(is(AliasSeq!int == AliasSeq!int));

passes, whereas

static assert(is(AliasSeq!0 == AliasSeq!0));

does not. So, I expect that the issue is that you're dealing 
with values rather than types. You're also using : instead of 
==, and : _definitely_ is for types (since it checks for 
implicit conversion, not equality), so it wouldn't have 
entirely surprised me if == worked when : didn't, but == 
doesn't either.


What you proobably should do is either convert the AliasSeq's 
to dynamic

arrays or ranges - e.g. [AliasSeq!(0, 1, 2, 3, 4)] or
only(AliasSeq!(0, 1, 2, 3, 4)) - though in both cases, that 
really only
makes sense when you already have an AliasSeq, since [] and 
only will take

the values directly.

- Jonathan M Davis


I see. I always thought tuple() is a type...

So a tuple of types is a type, but a tuple of mixed types and 
values is not a type. Doesn't seem very consistent.


Here is the solution I will go with:

struct test(T...) { }
import std.range;
	static assert (is(test!(expandRange!(iota(0,5))) == test!(0, 1, 
2, 3, 4)));





Comparing two AliasSeq

2017-03-24 Thread Yuxuan Shui via Digitalmars-d-learn

In this example:

import std.range;
template expandRange(alias R) if (isInputRange!(typeof(R))) {
static if (R.empty)
alias expandRange = AliasSeq!();
else
	alias expandRange = AliasSeq!(R.front(), 
expandRange!(R.drop(1)));

}

///
unittest {
import std.range;
static assert (is(expandRange!(iota(0,5)): 
AliasSeq!(0,1,2,3,4)));

}

The static assert fails, why?


template alias parameter vs type parameter.

2017-03-22 Thread Yuxuan Shui via Digitalmars-d-learn

Hi,

Is there any difference, when a type is passed into an alias 
parameter vs into a type parameter?


We can't have alias of instantiated auto ref functions?

2017-03-18 Thread Yuxuan Shui via Digitalmars-d-learn

auto a(T)(auto ref T t) {
return t;
}
void main() {
alias tmp = a!int;
import std.stdio;
writeln(tmp(10));
}

This gives this error message:
test.d(1): Error: 'auto' can only be used as part of 'auto ref' 
for template function parameters


Which is rather useless, and I have to dig into the code to find 
out why: the only way to instantiate a auto ref function is to 
call it. I think this is rather inconvenient.


How to write document for methods under static if?

2017-03-10 Thread Yuxuan Shui via Digitalmars-d-learn

Example:

/**
  test type
*/
struct A(bool T) {
static if (T) {
/// Case 1
int ok(){ return 1; }
} else {
/// case 2
int notok(){ return 1; }
}

/// Other
int other() { return 0; }
}

///
unittest {
A!true x;
A!false y;
}

In documents generated by ddoc, only case 1 is included. In 
documents generated by ddox, none of the cases is included.


What's the proper way to write document in this case?


Re: Another bug?

2017-01-30 Thread Yuxuan Shui via Digitalmars-d-learn

On Monday, 30 January 2017 at 12:40:44 UTC, Jack Applegame wrote:

bug report: https://issues.dlang.org/show_bug.cgi?id=17128


LDC (2.070.2) has a different problem: the dtor is never called.


Re: switch statement with variable branches

2017-01-18 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 19 January 2017 at 02:00:10 UTC, Ali Çehreli wrote:

On 01/18/2017 05:22 PM, Yuxuan Shui wrote:
Somehow I can't use ubyte variables behind 'case', but ulong 
works fine.

Why is that?



case expressions must be constants:

  "The case expressions must all evaluate to a constant value or
   array, or a runtime initialized const or immutable variable 
of

   integral type."

  https://dlang.org/spec/statement.html#SwitchStatement

The fact that it compiles for ulong looks like a bug to me. It 
compiles probably because switch is most likely implemented in 
terms of a chained if-else-if statements by the compiler and it 
just works because there is no explicit check whether they are 
constant or not.


Ali


If you try:

void main() {
alias TestType = ulong; // won't compile if = ubyte
import std.stdio;
TestType a,b,c;
readf("%s %s %s ", , , );
final switch(c){
case a: writeln("a");break;
case b: writeln("b");break;
default: assert(false);
}
}

Then the error message:

test.d(7): Error: case variables not allowed in final switch 
statements
test.d(8): Error: case variables not allowed in final switch 
statements


Makes it looks like that "case variable" is an intended feature.



switch statement with variable branches

2017-01-18 Thread Yuxuan Shui via Digitalmars-d-learn
Somehow I can't use ubyte variables behind 'case', but ulong 
works fine. Why is that?


void main() {
alias TestType = ulong; // won't compile if = ubyte
import std.stdio;
TestType a,b,c;
readf("%s %s %s ", , , );
switch(c){
case a: writeln("a");break;
case b: writeln("b");break;
default: assert(false);
}
}


Chain a range of ranges?

2017-01-16 Thread Yuxuan Shui via Digitalmars-d-learn
The built in chain seems to only be able to chain a fixed number 
of ranges, is there a way to chain a range/array of ranges?


How to initialize a associative array?

2016-12-23 Thread Yuxuan Shui via Digitalmars-d-learn

I tried this:

immutable int[char] xx = ['Q':0, 'B':1, 'N':2, 'R':3, 'P':4];

And got a "non-constant expression" error (with or without 
'immutable').


What's the correct way?


Re: Error and Exception chaining

2016-12-12 Thread Yuxuan Shui via Digitalmars-d-learn

On Tuesday, 13 December 2016 at 00:33:58 UTC, Yuxuan Shui wrote:

On Monday, 12 December 2016 at 22:35:22 UTC, Yuxuan Shui wrote:

On Monday, 12 December 2016 at 22:13:59 UTC, Ali Çehreli wrote:

On 12/12/2016 02:08 PM, Yuxuan Shui wrote:
> [...]
wrote:
>> [...]
Error.bypassedException
>> [...]
mechanism,
>> [...]
Error."
>> [...]
Exception,
>> [...]
otherwise
>> [...]
original
>> [...]
is the Error.
> [...]
Exception to
> [...]

Currently yes. Now this line in my versatile :o) program:

if (n >= errorIndex) {

Two Errors are chained:

Caught
TestError: 3
 TestError: 4

However, there is the following ongoing thread claiming that 
it was a wrong decision:


  http://forum.dlang.org/post/o2n347$2i1g$1...@digitalmars.com

> [...]

From what I could graps from that much of documentation, yes, 
it seems to be a bug.


I did some testing and bypassedException is null in 2.072.1, 
but is not null in 2.070.2




Ali


The unwind process seem to stop one level too early, causing 
language_specific_data to be different, causing 
__dmd_personality_v0 to not chain exception into 
.bypassException.


OK. I think I figured it out. catch(Error x) won't catch 
TestException, so TestException 0,1,2 is not handled at main(). 
However TestError 3 (and TestExcepotion 4 which is chained to it) 
is handled at main(). And dmd won't put Throwables that are 
handled at different places together.


This behavior seems reasonable. So maybe this is actually a bug 
is LDC?


Re: Error and Exception chaining

2016-12-12 Thread Yuxuan Shui via Digitalmars-d-learn

On Monday, 12 December 2016 at 22:35:22 UTC, Yuxuan Shui wrote:

On Monday, 12 December 2016 at 22:13:59 UTC, Ali Çehreli wrote:

On 12/12/2016 02:08 PM, Yuxuan Shui wrote:
> [...]
wrote:
>> [...]
Error.bypassedException
>> [...]
mechanism,
>> [...]
Error."
>> [...]
Exception,
>> [...]
otherwise
>> [...]
original
>> [...]
is the Error.
> [...]
Exception to
> [...]

Currently yes. Now this line in my versatile :o) program:

if (n >= errorIndex) {

Two Errors are chained:

Caught
TestError: 3
 TestError: 4

However, there is the following ongoing thread claiming that 
it was a wrong decision:


  http://forum.dlang.org/post/o2n347$2i1g$1...@digitalmars.com

> [...]

From what I could graps from that much of documentation, yes, 
it seems to be a bug.


I did some testing and bypassedException is null in 2.072.1, 
but is not null in 2.070.2




Ali


The unwind process seem to stop one level too early, causing 
language_specific_data to be different, causing 
__dmd_personality_v0 to not chain exception into .bypassException.


Re: Error and Exception chaining

2016-12-12 Thread Yuxuan Shui via Digitalmars-d-learn

On Monday, 12 December 2016 at 22:13:59 UTC, Ali Çehreli wrote:

On 12/12/2016 02:08 PM, Yuxuan Shui wrote:
> [...]
wrote:
>> [...]
Error.bypassedException
>> [...]
mechanism,
>> [...]
Error."
>> [...]
Exception,
>> [...]
otherwise
>> [...]
original
>> [...]
is the Error.
> [...]
Exception to
> [...]

Currently yes. Now this line in my versatile :o) program:

if (n >= errorIndex) {

Two Errors are chained:

Caught
TestError: 3
 TestError: 4

However, there is the following ongoing thread claiming that it 
was a wrong decision:


  http://forum.dlang.org/post/o2n347$2i1g$1...@digitalmars.com

> [...]

From what I could graps from that much of documentation, yes, 
it seems to be a bug.


I did some testing and bypassedException is null in 2.072.1, but 
is not null in 2.070.2




Ali




Re: Error and Exception chaining

2016-12-12 Thread Yuxuan Shui via Digitalmars-d-learn

Thanks a lot for the explanation!

On Monday, 12 December 2016 at 22:01:54 UTC, Ali Çehreli wrote:
(Note: Looks like there is a bug regarding 
Error.bypassedException member. Would others please confirm.)


On 12/12/2016 01:15 PM, Yuxuan Shui wrote:
> [...]
that Error
> [...]
vague, and I'm
> [...]

You're referring to "[Errors] bypass the normal chaining 
mechanism, such that the chain can only be caught by catching 
the first Error." What it means is that an Error cannot be a 
collateral of an Exception, hiding in its chain. So, when there 
is an Error that would otherwise be a collateral of an 
Exception, you cannot catch the original Exception. What is 
more importantly in-flight at that time is the Error.




But chaining Error to Error works just like chaining Exception to 
Exception?




But bypassedException member of Error is always null. Bug?


Did I just randomly found a bug?



Thank you,
Ali




Error and Exception chaining

2016-12-12 Thread Yuxuan Shui via Digitalmars-d-learn
I read https://dlang.org/spec/statement.html, which told me that 
Error is different in the way it's chained. But that is pretty 
vague, and I'm still confused.


Can someone explain that using examples?

Thanks.


Get return type of a template function without instantiating it

2016-11-22 Thread Yuxuan Shui via Digitalmars-d-learn
Is there a way to get a template function return type with 
instantiating it? The return type is independent of the template 
arguments.


I'm asking because there's potentially recursive template 
instantiation if I do try to instantiate it.


Re: opIndexDispatch?

2016-10-12 Thread Yuxuan Shui via Digitalmars-d-learn
On Wednesday, 12 October 2016 at 23:14:26 UTC, Jonathan M Davis 
wrote:
opIndexUnary, opIndexAssign, and opIndexOpAssign exist to make 
it possible to do some basic operations on the result of 
foo[bar] without having to have opIndex return by ref, but 
assuming that you can return by ref, all of them could be done 
by having opIndex return by ref.


No? If I want to mimics opIndex* by having opIndex return a ref. 
I would need to create a new entry every time opIndex is used to 
access a non-existent key, whether the return value is used as a 
lvalue or not. And opIndex* will solve this problem.


Re: opIndexDispatch?

2016-10-12 Thread Yuxuan Shui via Digitalmars-d-learn
On Monday, 10 October 2016 at 19:16:06 UTC, Jonathan M Davis 
wrote:
On Monday, October 10, 2016 19:01:19 Yuxuan Shui via 
Digitalmars-d-learn wrote:

Hi,

Why is there no opIndexDispatch for overloading a[x].func() ?


There's opIndex for overloading a[x], and then you can call a 
function on the return value. If you want some kind of 
opDispatch on the return value, then the return type will need 
to implement opDispatch.


- Jonathan M Davis


The opIndex* overloads are used for handling the case where the 
key is not already in the data structure, right?


opIndexDispatch?

2016-10-10 Thread Yuxuan Shui via Digitalmars-d-learn

Hi,

Why is there no opIndexDispatch for overloading a[x].func() ?


Re: Member not accessible in delegate body

2016-09-23 Thread Yuxuan Shui via Digitalmars-d-learn
On Friday, 23 September 2016 at 15:29:43 UTC, Rene Zwanenburg 
wrote:

On Friday, 23 September 2016 at 07:54:15 UTC, John C wrote:
How is it possible that "onTextChanged" isn't accessible but 
the private method "changeSize" *is*?


Smells like an oversight. I guess the compiler doesn't see the 
delegate as a member of a Control subclass, so it can't access 
protected members. Private works because private in D means 
module private.


Please file an issue. As a workaround you can try to take the 
address of the method in the closure (untested):


void delegate() foo()
{
  auto func = 

  return () => func(); // I think this will work
}


Quoting the document: "protected only applies inside classes (and 
templates as they can be mixed in) and means that a symbol can 
only be seen by members of the same module, or by a derived 
class."


So protected also means module visibility.


Re: Append const to array

2016-09-20 Thread Yuxuan Shui via Digitalmars-d-learn
On Tuesday, 20 September 2016 at 22:38:33 UTC, Jonathan M Davis 
wrote:
On Tuesday, September 20, 2016 22:23:08 Yuxuan Shui via 
Digitalmars-d-learn wrote:

struct A {
  ulong[] x;
}
struct B {
  ulong x;
}
void main() {
  B[] b;
  const(B) xx = B(1);
  b ~= xx; // Works

  A[] c;
  const(A) yy = A([1]);
  c ~= yy; // Does not
}

What gives?


const(A) means that the ulong[] inside is const(ulong[]). When 
yy is copied
to be appended to c, it goes from const(A) to A, which means 
that
const(ulong[]) would need to be sliced and and set to ulong[], 
which would
violate const, because it would mean that the last element in c 
could mutate
then elements of its x, which would then mutate the elements in 
yy.


- Jonathan M Davis


That makes sense, thanks.


Append const to array

2016-09-20 Thread Yuxuan Shui via Digitalmars-d-learn


struct A {
ulong[] x;
}
struct B {
ulong x;
}
void main() {
B[] b;
const(B) xx = B(1);
b ~= xx; // Works

A[] c;
const(A) yy = A([1]);
c ~= yy; // Does not
}

What gives?


Re: Copy a struct and its context

2016-09-13 Thread Yuxuan Shui via Digitalmars-d-learn
On Tuesday, 13 September 2016 at 20:36:22 UTC, Steven 
Schveighoffer wrote:

On 9/13/16 4:11 PM, Yuxuan Shui wrote:
On Tuesday, 13 September 2016 at 20:00:40 UTC, Steven 
Schveighoffer wrote:
Not familiar with C++ lambda. You can always "specify" how to 
capture

the data by directly declaring it:

auto foo()
{
int x;
static struct S
{
int x;
}
return S(x);
}


It just feels a bit tedious to do something manually while the 
compiler

have enough information to do it for me.


Do what for you? How does it know that you don't want to use a 
closure and a reference to that instead?


Note that all the internals for this are implementation 
defined. Given sufficient conditions, the compiler could 
"cheat" and allocate the data inside the struct itself instead. 
For example, if all referenced data was immutable.


-Steve


For example, a common use case might be I want to capture 
everything by value. In stead of adding all the fields by hand 
and passing them to the constructor, I want the compiler to do it 
for me.


i.e. I wish I could (borrowing C++ syntax):

struct A[=] {
   ...
}

Then the context will be captured by value instead of reference.


Re: Copy a struct and its context

2016-09-13 Thread Yuxuan Shui via Digitalmars-d-learn
On Tuesday, 13 September 2016 at 20:00:40 UTC, Steven 
Schveighoffer wrote:

On 9/13/16 3:42 PM, Yuxuan Shui wrote:

[...]


There's nothing in the language to prevent this optimization.


[...]


Again, could be clearer. But the fact that both the function 
and the struct affect the same data kind of dictates it needs 
to be a reference.



[...]


Not familiar with C++ lambda. You can always "specify" how to 
capture the data by directly declaring it:


auto foo()
{
int x;
static struct S
{
int x;
}
return S(x);
}


It just feels a bit tedious to do something manually while the 
compiler have enough information to do it for me.




In D, if you have a closure, it's going to be heap allocated. 
Just the way it is. If you don't want that, you have to avoid 
them.


-Steve




Re: Copy a struct and its context

2016-09-13 Thread Yuxuan Shui via Digitalmars-d-learn
On Tuesday, 13 September 2016 at 01:32:19 UTC, Steven 
Schveighoffer wrote:

On 9/12/16 4:11 PM, Ali Çehreli wrote:

On 09/10/2016 10:44 PM, Yuxuan Shui wrote:
I recently noticed nested struct capture its context by 
reference

(which, BTW, is not mentioned at all here:
https://dlang.org/spec/struct.html#nested).


" It has access to the context of its enclosing scope (via an 
added hidden field)."


It needs to be a reference. Otherwise, you store the entire 
stack frame in the struct? That wouldn't be a "field". It also 
has write access to the context:


Why not just capture the variables that are actually been 
referenced? Also being a field doesn't put limits on the size of 
the "field".


I like how C++ lambda lets you choose what variables to capture, 
and how are they captured. I'm little disappointed that D doesn't 
let me do the same.





Copy a struct and its context

2016-09-10 Thread Yuxuan Shui via Digitalmars-d-learn
I recently noticed nested struct capture its context by reference 
(which, BTW, is not mentioned at all here: 
https://dlang.org/spec/struct.html#nested). And bliting a struct 
obviously doesn't do a deep copy of its context.


So my question is, is there a way to deep copy the context of a 
struct?


Re: Get all files imported by a D source file

2016-09-09 Thread Yuxuan Shui via Digitalmars-d-learn

On Friday, 9 September 2016 at 10:03:01 UTC, wobbles wrote:
On Thursday, 8 September 2016 at 07:20:52 UTC, Yuxuan Shui 
wrote:
On Thursday, 8 September 2016 at 06:33:00 UTC, Jacob Carlborg 
wrote:

On 2016-09-08 07:39, Yuxuan Shui wrote:

Hi,

I wonder if there's standardized way to gather which files 
are imported
by a source file. I know I can run "dmd -v" and look for 
lines start
with "import", but I don't know if this is the best way to 
do it.


You can use the "-deps" flag.


-deps is even noisier than just -v...


It's pretty noisy alright, but it's also pretty easy to read...

It also shows just how coupled phobos is.
I'm importing one single function (std.stdio.writefln), and all 
the dependencies are imported:

http://pastebin.com/DSC4JhBD


Also the output format seems to change between versions (or 
between compilers, I don't know).


Because dmd 2.071 prefix lines with "depsImport", while ldc 
(based on dmd 2.070.2) doesn't.


Re: Get all files imported by a D source file

2016-09-08 Thread Yuxuan Shui via Digitalmars-d-learn
On Thursday, 8 September 2016 at 06:33:00 UTC, Jacob Carlborg 
wrote:

On 2016-09-08 07:39, Yuxuan Shui wrote:

Hi,

I wonder if there's standardized way to gather which files are 
imported
by a source file. I know I can run "dmd -v" and look for lines 
start
with "import", but I don't know if this is the best way to do 
it.


You can use the "-deps" flag.


-deps is even noisier than just -v...


Get all files imported by a D source file

2016-09-07 Thread Yuxuan Shui via Digitalmars-d-learn

Hi,

I wonder if there's standardized way to gather which files are 
imported by a source file. I know I can run "dmd -v" and look for 
lines start with "import", but I don't know if this is the best 
way to do it.


Re: Performance issue with GC

2016-09-07 Thread Yuxuan Shui via Digitalmars-d-learn

On Wednesday, 7 September 2016 at 22:54:14 UTC, Basile B. wrote:
On Wednesday, 7 September 2016 at 21:20:30 UTC, Yuxuan Shui 
wrote:
I have a little data processing program which makes heavy use 
of associative arrays, and GC almost doubles the runtime of it 
(~2m with GC disabled -> ~4m).


I just want to ask what's the best practice in this situation? 
Do I just use GC.disable and manually run GC.collect 
periodically?


I'd say yes.

Another option: https://github.com/economicmodeling/containers. 
The HashMap will give you a full control on the mem allocs.


This is a really nice library! Thanks a lot.


Performance issue with GC

2016-09-07 Thread Yuxuan Shui via Digitalmars-d-learn
I have a little data processing program which makes heavy use of 
associative arrays, and GC almost doubles the runtime of it (~2m 
with GC disabled -> ~4m).


I just want to ask what's the best practice in this situation? Do 
I just use GC.disable and manually run GC.collect periodically?


Re: Storing a reference

2016-09-01 Thread Yuxuan Shui via Digitalmars-d-learn
On Thursday, 1 September 2016 at 21:07:36 UTC, Steven 
Schveighoffer wrote:

On 9/1/16 4:38 PM, Yuxuan Shui wrote:

[...]


Referring to a null object is not a problem. Your program 
crashes ungracefully, but does not corrupt memory. However, in 
either approach, it can easily end up being a dangling pointer.


But to refer to a null location is quite easy:

int *foo; // null ptr
auto a = x(*foo);
assert(() == null);

Your approach is less desirable because of the closure to point 
at a given reference which can be had with just a reference. 
Needless allocation.


-Steve


Makes sense. Thanks!


Re: Storing a reference

2016-09-01 Thread Yuxuan Shui via Digitalmars-d-learn
On Thursday, 1 September 2016 at 20:28:03 UTC, Rene Zwanenburg 
wrote:
On Thursday, 1 September 2016 at 19:37:25 UTC, Yuxuan Shui 
wrote:

[...]


This will allocate a closure. A struct definition inside a 
function has a hidden context / closure pointer, unless it's a 
static struct.


There is nothing like a ref variable in D. If you want to refer 
to something someplace else, use a pointer. You can create a 
pointer wrapper which acts like a reference (untested):



auto toRef(ref T value)
{
  return Ref!T();
}

struct Ref(T)
{
  private T* value;
  @property ref T _value() { return *value; }
  alias _value this;
}

Note that D's pointer syntax is a bit friendlier than C++'s: 
the dot operator works fine on pointers. A good reason to use 
the Ref wrapper is to forward arithmetic operations to the 
wrapped value.


I think my approach is probably better, because I believe 
(correct me if I'm wrong): 1) it will never refer to a null 
object. 2) after DIP1000 is implemented we will be able to make 
sure there will be no dangling reference.


Storing a reference

2016-09-01 Thread Yuxuan Shui via Digitalmars-d-learn

I just figured out how to store a reference:

@safe:
auto x(ref int a) {
struct A {
ref int xa() { return a; }
}
return A();
}
void main() {
import std.stdio;
int b = 10;
auto a = x(b);
a.xa = 20;
writeln(b); //Prints 20
}

I have no idea if this is a right thing to do. Can someone tell 
me if this is idiomatic D, and whether there're any catches to 
this method or not?


Thanks.


Re: Prevent copy of range in foreach

2016-08-31 Thread Yuxuan Shui via Digitalmars-d-learn

On Wednesday, 31 August 2016 at 18:28:20 UTC, Ali Çehreli wrote:

On 08/31/2016 07:03 AM, Yuxuan Shui wrote:

> I want to make a hash table that uses
> std.experiment.allocator. The bucket is allocated from an
> allocator, and freed in ~this(). I don't want to copy the
whole
> bucket in this(this).

It sounds like you are conflating the concept of a container 
with the concept of a range. The range should be separate from 
the container and should be cheap to copy.


Ali


OK, this would work for cases like containers. But what if I 
represent buffered network input as a range (like File.byLine), 
and I don't want to copy the buffer all the time? Any suggestion 
on how to do that correctly?


Re: Debug prints in @nogc

2016-08-31 Thread Yuxuan Shui via Digitalmars-d-learn

On Wednesday, 31 August 2016 at 19:39:36 UTC, ag0aep6g wrote:

On 08/31/2016 09:23 PM, Yuxuan Shui wrote:
Correct me if I'm wrong. But I believe this is only true when 
the source
code of function is not available. Otherwise the compiler 
should always

know if a function is actually @nogc or not.


Attributes are only inferred in certain cases where the source 
code must be available anyway (templates, `auto` return value). 
For ordinary functions, the compiler only considers them @nogc 
when they're explicitly marked.


For example, the compiler won't let you do this, even though 
f's source code is available and it's obviously de-facto @nogc:



void f() {}
void main() @nogc { f(); }



That's a good point. By IMHO, all the (non-template) function in 
Phobos that can be marked @nogc, should be marked @nogc, 
otherwise it's a bug. If the function is in your own code, you 
should use @nogc, not assumeNogc.


After a second thought, the real use case of assumeNogc is 
probably virtual functions. But then again, it is kind of 
dangerous to use it even in this case.


Re: Debug prints in @nogc

2016-08-31 Thread Yuxuan Shui via Digitalmars-d-learn

On Wednesday, 31 August 2016 at 18:07:46 UTC, Cauterite wrote:

On Wednesday, 31 August 2016 at 16:17:51 UTC, Yuxuan Shui wrote:
No. When you use assumeUnique, you know something the compiler 
does know, and have to use assumeUnique to tell the compiler 
that (at least when you use it correctly). But when you use 
assumeNogc, it's always because you want to bypass compiler 
checks.


assumeNogc works the same way, you're telling the compiler 
something it doesn't know — that the function should be treated 
as @nogc. Using assumeNogc on a function that calls the GC is 
as unsafe as using assumeUnique on a reference that is not 
unique.


Correct me if I'm wrong. But I believe this is only true when the 
source code of function is not available. Otherwise the compiler 
should always know if a function is actually @nogc or not.


Re: Debug prints in @nogc

2016-08-31 Thread Yuxuan Shui via Digitalmars-d-learn

On Wednesday, 31 August 2016 at 15:52:18 UTC, Cauterite wrote:

On Wednesday, 31 August 2016 at 15:10:11 UTC, Seb wrote:
AssumeNogc is potentially dangerous, so I don't know whether 
it can make it directly, but only if you try you know ;-)


So is assumeUnique


No. When you use assumeUnique, you know something the compiler 
does know, and have to use assumeUnique to tell the compiler that 
(at least when you use it correctly). But when you use 
assumeNogc, it's always because you want to bypass compiler 
checks.


Re: Prevent copy of range in foreach

2016-08-31 Thread Yuxuan Shui via Digitalmars-d-learn

On Tuesday, 30 August 2016 at 20:30:12 UTC, Ali Çehreli wrote:

On 08/30/2016 12:06 PM, Yuxuan Shui wrote:
Is there a way to use a range defined with disabled post-blit 
in
foreach? In other words, is there a way to prevent foreach 
from copying

the range?


It's not possible. You can't do much with such a range anyway. 
For example, even r.take(10) requires to copy.


Why do you want to prevent copying? There may be other ways 
around the issue.


I want to make a hash table that uses std.experiment.allocator. 
The bucket is allocated from an allocator, and freed in ~this(). 
I don't want to copy the whole bucket in this(this).


Maybe I should use a reference counter or something?




Should I use move()?


I don't know but I guess you can have a member function to do 
that.


Ali





Prevent copy of range in foreach

2016-08-30 Thread Yuxuan Shui via Digitalmars-d-learn
Is there a way to use a range defined with disabled post-blit in 
foreach? In other words, is there a way to prevent foreach from 
copying the range?


Should I use move()?


std.experimental.allocator and @nogc

2016-07-21 Thread Yuxuan Shui via Digitalmars-d-learn

I was trying to use allocators in a @nogc function.

I tried FreeList!Mallocator and it works fine. But 
AllocatorList!Mallocator doesn't work. dmd complains that 
AllocatorList.allocate is not @nogc, even when 
BookkeepingAllocator is NullAllocator. But if I add '@nogc' to 
AllocatorList.allocate by hand, it works.


Is this probably a bug in how dmd deduce function properties?


Re: Is there a way to make a class variable visible but constant to outsiders, but changeable (mutable) to the class itself?

2016-05-21 Thread Yuxuan Shui via Digitalmars-d-learn

On Saturday, 21 May 2016 at 17:32:47 UTC, dan wrote:
Is it possible to have a class which has a variable which can 
be seen from the outside, but which can only be modified from 
the inside?


Something like:

class C {
  int my_var = 3; // semi_const??
  void do_something() { my_var = 4; }
}

And then in another file

auto c = new C();
c.my_var = 5; // <<<- should trigger a compile-time error
writeln("the value is ", c.my_var);  // <<<- should print 3
c.do_something();
writeln("the value is ", c.my_var);  // <<<- should print 4

Reading Alexandrescu's book suggests the answer is "no" (the 
only relevant type qualifiers are private, package, protected, 
public, and export, and none seem appropriate).


(This effect could be simulated by making my_var into a 
function, but i don't want to do that.)


TIA for any info!

dan


class C {
   int my_var() { return _my_var; }
   int _my_var;
}


Re: Implement async/await using Fiber

2016-05-20 Thread Yuxuan Shui via Digitalmars-d-learn

On Friday, 20 May 2016 at 06:40:42 UTC, Jacob Carlborg wrote:

On 2016-05-20 04:14, Yuxuan Shui wrote:

Hmm... This could work. But I'm not satisfied with this 
solution. What
if I have multiple yield sites in the fiber, and each have 
different

return types?

Maybe I should use a Variant?


I think you can view "yield" as a form of "return". If you 
cannot return different types from a function (without it being 
a template) it would be weird if you could yield different 
types.


But this is yield as in coroutine, not yield as in generators. 
Those yields doesn't return value to the caller of the fiber.


Let's have an example:

void func() {
   string a = wait_for_user_input();
   int b = wait_for_user_to_click_a_button();
}

Those two wait()s could use yield internally to transfer 
execution back to the caller and wait for input. But it's 
difficult with current dlang fiber because there's no (elegant) 
way to pass data (preferably with different types) while 
transferring executing to/from fibers.


Re: Implement async/await using Fiber

2016-05-19 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 19 May 2016 at 23:42:03 UTC, Ali Çehreli wrote:

On 05/19/2016 12:57 PM, Yuxuan Shui wrote:

[...]


You can use a delegate that takes a ref parameter:

import std.stdio;
import core.thread;

void fiberFunc(ref string y) {
y = "produced_by_fiberFunc";
Fiber.yield();
}

void main() {
string data;
auto f = new Fiber(() => fiberFunc(data));
f.call();
writefln("Writing in main: %s", data);
}

Prints:

Writing in main: produced_by_fiberFunc

Also see std.concurrency.Generator. Both methods appear here:

  http://ddili.org/ders/d.en/fibers.html

Ali


Hmm... This could work. But I'm not satisfied with this solution. 
What if I have multiple yield sites in the fiber, and each have 
different return types?


Maybe I should use a Variant?


Implement async/await using Fiber

2016-05-19 Thread Yuxuan Shui via Digitalmars-d-learn
I find this difficult because I can't passing data via 
Fiber.yield/Fiber.call pair. e.g. I want something like:


void fiberFunc() {
   //Add some file descriptor to main loop
   string y = Fiber.yield();
   writeln(y);
}

auto f = new Fiber();
f.call();
mainloop {
   if (fd_readable)
  f.call(fd.rawRead());
}

I can probably using a derived fiber class and pass the result 
via class members, but that seems clumsy and not very general. 
Any ideas?




Re: aliasing/referencing expressions in with statements

2016-04-21 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 21 April 2016 at 23:05:38 UTC, deed wrote:
Often I find myself wanting to alias an expression, such as 
verbose fields, possibly nested. AFAIK, the with statement 
makes it easier, but not as good as it could have been. What 
I'd like to express is for example something like this:


[...]


Maybe use something like:

auto a = () => instanceA.verboseFieldA.verboseFieldB;


Re: Problem using shared D library from C shared library

2016-04-06 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 7 April 2016 at 04:36:02 UTC, Yuxuan Shui wrote:

On Thursday, 7 April 2016 at 04:24:48 UTC, Yuxuan Shui wrote:

[...]


Looks like _d_arrayappendcTX asked for a enormous amount of 
memory and it fails, can't figure out why


Just find out it's my own fault.

BTW, memory block allocated by core.stdc.stdlib.malloc will not 
be scanned by collector, right?


Re: Problem using shared D library from C shared library

2016-04-06 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 7 April 2016 at 04:24:48 UTC, Yuxuan Shui wrote:

On Thursday, 7 April 2016 at 03:37:39 UTC, Yuxuan Shui wrote:
On Thursday, 7 April 2016 at 03:19:58 UTC, rikki cattermole 
wrote:

On 07/04/2016 3:18 PM, Yuxuan Shui wrote:

On Thursday, 7 April 2016 at 02:01:31 UTC, Mike Parker wrote:

[...]


static this/static ~this should work, right?


They execute when the runtime is started.


So now I add call rt_init in the C shared library. Now the D 
library no longer gets SIGSEGV, but throws no memory exception 
when it tries to allocate.


Back trace:

(gdb) bt
#0  0x7fffe19e006c in _d_throwdwarf () from 
/lib64/libphobos2.so.0.70
#1  0x7fffe19af2ab in onOutOfMemoryErrorNoGC () from 
/lib64/libphobos2.so.0.70
#2  0x7fffe19cbfa3 in 
gc.gc.GC.__T9runLockedS47_D2gc2gc2GC12mallocNoSyncMFNbmkKmxC8TypeInfoZPvS21_D2gc2gc10mallocTimelS21_D2gc2gc10numMallocslTmTkTmTxC8TypeInfoZ.runLocked() () from /lib64/libphobos2.so.0.70
#3  0x7fffe19c4f66 in gc.gc.GC.malloc() () from 
/lib64/libphobos2.so.0.70
#4  0x7fffe19cda18 in gc_qalloc () from 
/lib64/libphobos2.so.0.70
#5  0x7fffe19e17dd in rt.lifetime.__arrayAlloc() () from 
/lib64/libphobos2.so.0.70
#6  0x7fffe19e6445 in _d_arrayappendcTX () from 
/lib64/libphobos2.so.0.70
#7  0x7fffe19e5b47 in _d_arrayappendT () from 
/lib64/libphobos2.so.0.70


Looks like _d_arrayappendcTX asked for a enormous amount of 
memory and it fails, can't figure out why


Re: Problem using shared D library from C shared library

2016-04-06 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 7 April 2016 at 03:37:39 UTC, Yuxuan Shui wrote:
On Thursday, 7 April 2016 at 03:19:58 UTC, rikki cattermole 
wrote:

On 07/04/2016 3:18 PM, Yuxuan Shui wrote:

On Thursday, 7 April 2016 at 02:01:31 UTC, Mike Parker wrote:

[...]


static this/static ~this should work, right?


They execute when the runtime is started.


So now I add call rt_init in the C shared library. Now the D 
library no longer gets SIGSEGV, but throws no memory exception 
when it tries to allocate.


Back trace:

(gdb) bt
#0  0x7fffe19e006c in _d_throwdwarf () from 
/lib64/libphobos2.so.0.70
#1  0x7fffe19af2ab in onOutOfMemoryErrorNoGC () from 
/lib64/libphobos2.so.0.70
#2  0x7fffe19cbfa3 in 
gc.gc.GC.__T9runLockedS47_D2gc2gc2GC12mallocNoSyncMFNbmkKmxC8TypeInfoZPvS21_D2gc2gc10mallocTimelS21_D2gc2gc10numMallocslTmTkTmTxC8TypeInfoZ.runLocked() () from /lib64/libphobos2.so.0.70
#3  0x7fffe19c4f66 in gc.gc.GC.malloc() () from 
/lib64/libphobos2.so.0.70
#4  0x7fffe19cda18 in gc_qalloc () from 
/lib64/libphobos2.so.0.70
#5  0x7fffe19e17dd in rt.lifetime.__arrayAlloc() () from 
/lib64/libphobos2.so.0.70
#6  0x7fffe19e6445 in _d_arrayappendcTX () from 
/lib64/libphobos2.so.0.70
#7  0x7fffe19e5b47 in _d_arrayappendT () from 
/lib64/libphobos2.so.0.70




Re: Problem using shared D library from C shared library

2016-04-06 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 7 April 2016 at 03:19:58 UTC, rikki cattermole wrote:

On 07/04/2016 3:18 PM, Yuxuan Shui wrote:

On Thursday, 7 April 2016 at 02:01:31 UTC, Mike Parker wrote:

[...]


static this/static ~this should work, right?


They execute when the runtime is started.


So now I add call rt_init in the C shared library. Now the D 
library no longer gets SIGSEGV, but throws no memory exception 
when it tries to allocate.




Re: Problem using shared D library from C shared library

2016-04-06 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 7 April 2016 at 02:01:31 UTC, Mike Parker wrote:

On Thursday, 7 April 2016 at 01:50:31 UTC, Yuxuan Shui wrote:

[...]


The runtime is needed if you are going to use any of its 
features, like the GC. If you restrict yourself strictly to C 
in D (and that means avoiding thinks like builtin AAs, array 
concatenation, and anything that touches the runtime) you can 
do without it.


The functions you want are core.runtime.rt_init for 
initialization and core.runtime.rt_term for cleanup [1]. On 
Windows, you can guarantee these will be called by adding a 
DLLMain checking for DLL_PROCESS_ATTACH and DLL_PROCESS_DETACH. 
On other platforms, you'll need to work out something else.


[1] http://dlang.org/phobos/core_runtime.html#.rt_init


static this/static ~this should work, right?


Re: Problem using shared D library from C shared library

2016-04-06 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 7 April 2016 at 02:01:31 UTC, Mike Parker wrote:

On Thursday, 7 April 2016 at 01:50:31 UTC, Yuxuan Shui wrote:

[...]


The runtime is needed if you are going to use any of its 
features, like the GC. If you restrict yourself strictly to C 
in D (and that means avoiding thinks like builtin AAs, array 
concatenation, and anything that touches the runtime) you can 
do without it.


The functions you want are core.runtime.rt_init for 
initialization and core.runtime.rt_term for cleanup [1]. On 
Windows, you can guarantee these will be called by adding a 
DLLMain checking for DLL_PROCESS_ATTACH and DLL_PROCESS_DETACH. 
On other platforms, you'll need to work out something else.


[1] http://dlang.org/phobos/core_runtime.html#.rt_init


Thanks a lot.

I wish this can be better documented, though.


Re: Problem using shared D library from C shared library

2016-04-06 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 7 April 2016 at 01:42:54 UTC, rikki cattermole wrote:

On 07/04/2016 1:38 PM, Yuxuan Shui wrote:

[...]


Have you started D's runtime?


How to start D's runtime? I followed the examples found here: 
https://dlang.org/dll-linux.html#dso9, which doesn't say anything 
about starting the runtime.


Problem using shared D library from C shared library

2016-04-06 Thread Yuxuan Shui via Digitalmars-d-learn
I have a D shared library which is loaded by a C shared library, 
which is in turn loaded by my main program.


When the D library tries to allocate something, the whole program 
get an SIGSEGV in __GI___pthread_mutex_lock.


Stack trace:

(gdb) bt
#0  __GI___pthread_mutex_lock (mutex=0x7fffc1b8) at 
../nptl/pthread_mutex_lock.c:66
#1  0x7fffe19cbeef in 
gc.gc.GC.__T9runLockedS47_D2gc2gc2GC12mallocNoSyncMFNbmkKmxC8TypeInfoZPvS21_D2gc2gc10mallocTimelS21_D2gc2gc10numMallocslTmTkTmTxC8TypeInfoZ.runLocked() () from /var/services/homes/.../install/linux/lib64/libphobos2.so.0.70
#2  0x7fffe19c4f66 in gc.gc.GC.malloc() () from 
/var/services/homes/.../install/linux/lib64/libphobos2.so.0.70
#3  0x7fffe19cda18 in gc_qalloc () from 
/var/services/homes/.../install/linux/lib64/libphobos2.so.0.70
#4  0x7fffe19e17dd in rt.lifetime.__arrayAlloc() () from 
/var/services/homes/.../install/linux/lib64/libphobos2.so.0.70
#5  0x7fffe19e6d26 in _d_arrayliteralTX () from 
/var/services/homes/.../install/linux/lib64/libphobos2.so.0.70


What can be the problem?


Re: Possible bug in RVO?

2016-04-04 Thread Yuxuan Shui via Digitalmars-d-learn

On Monday, 4 April 2016 at 21:31:08 UTC, Ali Çehreli wrote:

On 04/04/2016 09:36 AM, Anonymouse wrote:

On Monday, 4 April 2016 at 03:55:26 UTC, Yuxuan Shui wrote:

[...]

assert(x.aa.length > 0);  // <-- boom

[...]


No idea myself but that's where it seems to go wrong.


Looks like a bug. Just to make it more visible:

auto clobber(ref Set x, ref Set o) {
writefln("entered clobber- x.aa: %s", x.aa);
Set ret;
writefln("did not touch x.aa - x.aa: %s", x.aa);
ret.aa = x.aa;
return ret;
}

x.aa changes during the second call:

entered clobber- x.aa: [1:true]
did not touch x.aa - x.aa: [1:true]
entered clobber- x.aa: [1:true]
did not touch x.aa - x.aa: []  <-- What happened?

Ali


I filed an bug report here: 
https://issues.dlang.org/show_bug.cgi?id=15869


Re: Possible bug in RVO?

2016-04-03 Thread Yuxuan Shui via Digitalmars-d-learn

On Monday, 4 April 2016 at 03:28:01 UTC, Yuxuan Shui wrote:

I have encountered a weird bug.

I defined a Set class, which has a opBinary!"-". And somehow 
this:


auto tmp = set_a-set_b;

produces different results as this:

set_a = set_a-set_b;

the latter will produce an empty set.

I tried to reduce the source code to get a test case. But this 
problem just goes away after removing some code.


Any ideas what I could have done wrong?


A slightly more reduced test case:

struct Set {
void insert(ulong v) {
aa[v] = true;
}
@disable this(this);
bool[ulong] aa;
}
auto clobber(ref Set x, ref Set o) {
Set ret;
ret.aa = x.aa;
return ret;
}
struct XX {
Set a, b, tmp;
this(int n) {
a.insert(1);
		//a.aa[1] = true;  <--- Swap above line with this doesn't 
trigger the bug

tmp = a.clobber(b);
a = a.clobber(b);
}
}
void main(){
import std.stdio;
XX xx = XX(0);
writeln(xx.a.aa.length);
writeln(xx.tmp.aa.length);
}


Re: Possible bug in RVO?

2016-04-03 Thread Yuxuan Shui via Digitalmars-d-learn

On Monday, 4 April 2016 at 03:55:26 UTC, Yuxuan Shui wrote:

On Monday, 4 April 2016 at 03:28:01 UTC, Yuxuan Shui wrote:

I have encountered a weird bug.

I defined a Set class, which has a opBinary!"-". And somehow 
this:


auto tmp = set_a-set_b;

produces different results as this:

set_a = set_a-set_b;

the latter will produce an empty set.

I tried to reduce the source code to get a test case. But this 
problem just goes away after removing some code.


Any ideas what I could have done wrong?


A slightly more reduced test case:



And LDC has the same problem with the first test case, but not 
with the second one.





Re: Possible bug in RVO?

2016-04-03 Thread Yuxuan Shui via Digitalmars-d-learn

On Monday, 4 April 2016 at 03:28:01 UTC, Yuxuan Shui wrote:

I have encountered a weird bug.

I defined a Set class, which has a opBinary!"-". And somehow 
this:


auto tmp = set_a-set_b;

produces different results as this:

set_a = set_a-set_b;

the latter will produce an empty set.

I tried to reduce the source code to get a test case. But this 
problem just goes away after removing some code.


Any ideas what I could have done wrong?


OK, I think I got a test case:

import std.traits;
struct Set {
public:
void insert(ulong v) {
aa[v] = true;
}
size_t size() const {
return aa.length;
}
auto opBinary(string op)(ref Set o) const {
Set ret;
foreach(k; aa.byKey)
if (k !in o.aa)
ret.insert(k);
return ret;
}
@disable this(this);
bool[ulong] aa;
}

struct XX {
Set a, b, tmp;
this(int n) {
a.insert(n);
tmp = a-b;
a = a-b;
}
}
void main(){
import std.stdio;
XX xx = XX(1000);
writeln(xx.a.size);
writeln(xx.tmp.size);
}

This does not happen when 'a' is on stack, that's why I was 
having trouble reproducing it.


I don't think this is valid code, because Set has disabled 
post-blit, 'a = a-b' should report an error. However, I don't 
think current behavior of dmd is correct either.


Possible bug in RVO?

2016-04-03 Thread Yuxuan Shui via Digitalmars-d-learn

I have encountered a weird bug.

I defined a Set class, which has a opBinary!"-". And somehow this:

auto tmp = set_a-set_b;

produces different results as this:

set_a = set_a-set_b;

the latter will produce an empty set.

I tried to reduce the source code to get a test case. But this 
problem just goes away after removing some code.


Any ideas what I could have done wrong?


Re: No aa.byKey.length?

2016-04-03 Thread Yuxuan Shui via Digitalmars-d-learn

On Monday, 4 April 2016 at 00:50:27 UTC, Jonathan M Davis wrote:
On Sunday, April 03, 2016 23:46:10 John Colvin via 
Digitalmars-d-learn wrote:
On Saturday, 2 April 2016 at 16:00:51 UTC, Jonathan M Davis 
wrote:

> [...]

Maybe

aa.byKey().takeExactly(aa.length)


Yeah, that's a clever workaround.

- Jonathan M Davis


So should we not add length to byKey?


No aa.byKey.length?

2016-04-01 Thread Yuxuan Shui via Digitalmars-d-learn

Why?

This is annoying when I need to feed it into a function that 
requires hasLength.


Re: key in aa.keys, but aa[key] give range violation?

2016-03-29 Thread Yuxuan Shui via Digitalmars-d-learn

On Wednesday, 30 March 2016 at 00:26:49 UTC, Yuxuan Shui wrote:

My code looks something like this:

bool[ulong][ulong] edge;
foreach(u; from)
foreach(v; to_)
edge[u][v] = true;
foreach(u; edge.keys) {
auto adj = edge[u];
//
}

And sometimes edge[u] would give Range violation error.


I guess I'm not supposed to do aa.remove() while iterate through 
it?


key in aa.keys, but aa[key] give range violation?

2016-03-29 Thread Yuxuan Shui via Digitalmars-d-learn

My code looks something like this:

bool[ulong][ulong] edge;
foreach(u; from)
foreach(v; to_)
edge[u][v] = true;
foreach(u; edge.keys) {
auto adj = edge[u];
//
}

And sometimes edge[u] would give Range violation error.


Re: getOverloads, but also include all the imported members

2016-03-25 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 24 March 2016 at 15:52:49 UTC, Adam D. Ruppe wrote:

On Thursday, 24 March 2016 at 15:07:09 UTC, Yuxuan Shui wrote:

Is there a way to do this automatically?


No. You have to decide to bring them together if you want them 
to overload.


Oh, sorry, this is not what I meant.

What I wanted to know is if it's possible to automate this 
aliasing process, by using for example templates?


Re: getOverloads, but also include all the imported members

2016-03-24 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 24 March 2016 at 13:55:31 UTC, Adam D. Ruppe wrote:

On Thursday, 24 March 2016 at 12:11:33 UTC, Marc Schütz wrote:

On Wednesday, 23 March 2016 at 20:54:20 UTC, Yuxuan Shui wrote:

module one;
void func(int a){}
/
module two;
import one;
void func(float a){}


Add in module two:

alias func = one.func;


Indeed, the two funcs are NOT overloaded right now unless you 
add that alias. See : http://dlang.org/hijack.html for details.


Is there a way to do this automatically?


getOverloads, but also include all the imported members

2016-03-23 Thread Yuxuan Shui via Digitalmars-d-learn

Say:

module one;
void func(int a){}

/

module two;
import one;
void func(float a){}

Is there a way to get both func() in module two?


Re: Is it safe to use 'is' to compare types?

2016-03-10 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 10 March 2016 at 02:14:19 UTC, H. S. Teoh wrote:
On Thu, Mar 10, 2016 at 01:33:41AM +, Yuxuan Shui via 
Digitalmars-d-learn wrote:

[...]


You can't rely on invoking the compiler to link these objects, 
because if you're using shared libraries, it will be the OS's 
dynamic linker that will get invoked to resolve the references, 
and different versions of shared libraries may have a different 
set of TypeInfo's, and the compiler may not be able to generate 
the required TypeInfo's.


A better way is to use the OS linker's "weak symbol" feature, 
where a symbol is allowed to be defined multiple times (with 
identical content), and the linker (both dynamic and static) 
will choose the first definition that it finds.


However weak symbol overriding is deprecated on Linux (see 
ld.so(8)).


If we want to go all out to solve this problem, there are clearly 
solutions. But for now there doesn't seem to be enough benefit to 
justify the amount of work needed.





T




Re: Is it safe to use 'is' to compare types?

2016-03-09 Thread Yuxuan Shui via Digitalmars-d-learn

On Wednesday, 9 March 2016 at 22:26:38 UTC, Ali Çehreli wrote:

On 03/09/2016 07:05 AM, Yuxuan Shui wrote:

> Can we left TypeInfo symbol undefined in the shared
libraries? i.e. D
> compiler will strip out TypeInfo definition when creating .so.
> (Alternatively, we can have TypeInfo always undefined in .o,
and
> generate them in linking stage only when creating executables)

That would require a linker that's aware of D but as far as I 
know, all system languages use the system linker.


Ali


Hmm, how about this:

During compilation, D generate undefined TypeInfo symbols, but it 
also embed type information in the object file (like what Rust 
does). And then, when dmd/ldc/gdc/whatever is called for linking 
executables, it will scan object files and generate another 
object file containing the TypeInfos, and link them together with 
the system linker. If the compiler is called for linking shared 
libraries, it doesn't.


Re: Is it safe to use 'is' to compare types?

2016-03-09 Thread Yuxuan Shui via Digitalmars-d-learn

On Tuesday, 8 March 2016 at 23:13:32 UTC, Anon wrote:

On Tuesday, 8 March 2016 at 20:26:04 UTC, Yuxuan Shui wrote:

[...]


[Note: I phrase my answer in terms of Linux shared libraries 
(*.so) because D doesn't actually have proper Windows DLL 
support yet. The same would apply to DLLs, it just feels wrong 
describing functionality that doesn't exist.]


[...]


Can we left TypeInfo symbol undefined in the shared libraries? 
i.e. D compiler will strip out TypeInfo definition when creating 
.so. (Alternatively, we can have TypeInfo always undefined in .o, 
and generate them in linking stage only when creating executables)




Re: Is it safe to use 'is' to compare types?

2016-03-08 Thread Yuxuan Shui via Digitalmars-d-learn
On Monday, 7 March 2016 at 16:13:45 UTC, Steven Schveighoffer 
wrote:

On 3/4/16 4:30 PM, Yuxuan Shui wrote:
On Friday, 4 March 2016 at 15:18:55 UTC, Steven Schveighoffer 
wrote:

[...]


Thanks for answering. But I still don't understand why 
TypeInfo would
need to be allocated. Aren't typeid() just returning 
references to the

__DxxTypeInfo___initZ symbol?


You misunderstood, I meant the typeinfo *for* an allocated 
object, not that the typeinfo was allocated.


In some cases, 2 different objects allocated from different 
libraries (usually DLL-land) may reference TypeInfo from 
different segments, even though the TypeInfo is identical.


-Steve


Hmm... Does that mean each DLL will have their own TypeInfo 
symbols for the same type?


Re: If stdout is __gshared, why does this throw / crash?

2016-03-05 Thread Yuxuan Shui via Digitalmars-d-learn

On Saturday, 5 March 2016 at 14:18:31 UTC, Atila Neves wrote:
With a small number of threads, things work as intended in the 
code below. But with 1000, on my machine it either crashes or 
throws an exception:



import std.stdio;
import std.parallelism;
import std.range;


void main() {
stdout = File("/dev/null", "w");
foreach(t; 1000.iota.parallel) {
writeln("Oops");
}
}



I get, depending on the run, "Bad file descriptor", "Attempting 
to write to a closed file", or segfaults. What am I doing wrong?


Atila


Could this be a bug in phobos/compiler?


D thinks it is OK to mess around with TypeInfo

2016-03-04 Thread Yuxuan Shui via Digitalmars-d-learn

For example

struct A{}
@safe void main(){
import std.stdio;
A a, b;
auto y = typeid(a);
y.name = "Nope, I'm not A";
auto x = typeid(b);
writeln(x);
}

Make changes to TypeInfo will affect all the future typeid() 
results! And D is OK with that?


IMO, TypeInfo returned by typeid() should be immutable.


Re: Is it safe to use 'is' to compare types?

2016-03-04 Thread Yuxuan Shui via Digitalmars-d-learn
On Friday, 4 March 2016 at 15:18:55 UTC, Steven Schveighoffer 
wrote:

On 3/3/16 6:58 PM, Yuxuan Shui wrote:

On Thursday, 3 March 2016 at 23:51:16 UTC, Adam D. Ruppe wrote:

On Thursday, 3 March 2016 at 23:46:50 UTC, Yuxuan Shui wrote:
Will typeid(a) is typeid(b) yield different results than 
typeid(a) ==

typeid(b)?


No. Indeed, opEquals on TypeInfo just calls is itself.


But opEquals also has extra comparison:

 auto ti = cast(const TypeInfo)o;
 return ti && this.toString() == ti.toString();

This makes me feel they are not the same.


In some cases, for instance using DLLs, the TypeInfo for an 
object allocated in one way may be identical, but be a 
different instance from the TypeInfo allocated in another way. 
This is why the string comparison occurs.


Note that comparing ANY object will first check if they are the 
same instance before calling any functions (this is in 
object.opEquals)


-Steve


Thanks for answering. But I still don't understand why TypeInfo 
would need to be allocated. Aren't typeid() just returning 
references to the __DxxTypeInfo___initZ symbol?


Re: Is it safe to use 'is' to compare types?

2016-03-03 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 3 March 2016 at 23:58:39 UTC, Yuxuan Shui wrote:

On Thursday, 3 March 2016 at 23:51:16 UTC, Adam D. Ruppe wrote:

On Thursday, 3 March 2016 at 23:46:50 UTC, Yuxuan Shui wrote:
Will typeid(a) is typeid(b) yield different results than 
typeid(a) == typeid(b)?


No. Indeed, opEquals on TypeInfo just calls is itself.


But opEquals also has extra comparison:

auto ti = cast(const TypeInfo)o;
return ti && this.toString() == ti.toString();

This makes me feel they are not the same.


Oh, I get it. 'a is b' works for the results of typeid(). But not 
for duplicates of TypeInfo.


For example:

import std.stdio;
A a, b;
auto x = typeid(a), y = typeid(b);
writeln(x is y);
	auto xz = ((cast(ubyte 
*)x)[0..typeof(x).classinfo.init.length]).dup; //Evil

auto z = cast(typeof(x))(cast(void *)xz);
writeln(x is z); //false
writeln(x == z); //true




Re: Is it safe to use 'is' to compare types?

2016-03-03 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 3 March 2016 at 23:51:16 UTC, Adam D. Ruppe wrote:

On Thursday, 3 March 2016 at 23:46:50 UTC, Yuxuan Shui wrote:
Will typeid(a) is typeid(b) yield different results than 
typeid(a) == typeid(b)?


No. Indeed, opEquals on TypeInfo just calls is itself.


But opEquals also has extra comparison:

auto ti = cast(const TypeInfo)o;
return ti && this.toString() == ti.toString();

This makes me feel they are not the same.


Is it safe to use 'is' to compare types?

2016-03-03 Thread Yuxuan Shui via Digitalmars-d-learn
Will typeid(a) is typeid(b) yield different results than 
typeid(a) == typeid(b)?


Re: Struct Inheritence

2016-02-19 Thread Yuxuan Shui via Digitalmars-d-learn

On Friday, 19 February 2016 at 21:58:24 UTC, user001 wrote:
Well struct don't have it, but i would like something like it 
but only for data, i don't need functions or anything like that 
just data.


[...]


How about

struct A
{
int valueA;
}

struct B
{
A a;
int valueB;
alias a this;
}

struct C
{
B b;
int valueC;
alias b this;
}

?


Re: Modify Function Pointer to Take Additional Parameters

2016-02-19 Thread Yuxuan Shui via Digitalmars-d-learn

On Friday, 19 February 2016 at 20:45:23 UTC, jmh530 wrote:

On Friday, 19 February 2016 at 15:00:51 UTC, jmh530 wrote:


This works.

But when I re-write foo to take that into account as in below, 
I get an error that I can't implicitly convert int 
function(int x) to int function(int x, int y).



I don't think I had looked at what you had done carefully 
enough. Basically, you just define a new function and take a 
function pointer of that. That might be a brute force solution.


I tried to use a cast (below) to modify the function pointer, 
but it is printing the second number instead of the first. I 
find this behavior strange...


int foo(int x)
{
return x;
}

void main()
{
import std.stdio : writeln;

auto foo_ = cast(int function(int x, int y)) 

writeln(foo_(1, 200)); //prints 200
}


I don't think it's safe to convert between function pointer with 
different number of arguments... It's possible to mess up the 
stack frame.


Also '(int x, int y)=>f(x)' is clearly a delegate because it 
refers to local variable 'f', you can't just cast it to 'int 
function(int, int)'.


Can't chain reduce(seed, range)

2015-08-30 Thread Yuxuan Shui via Digitalmars-d-learn
Why is reduce defined as 'auto reduce(S, R)(S seed, R r)', 
instead of reduce(R r, S seed)? I can't chain it.


Maybe provide both?


Re: More threads - Slower program ??

2015-08-12 Thread Yuxuan Shui via Digitalmars-d-learn

On Wednesday, 12 August 2015 at 23:15:48 UTC, Adam D. Ruppe wrote:

On Wednesday, 12 August 2015 at 23:06:32 UTC, Yuxuan Shui wrote:

What is wrong here?


I didn't look too closely, but there's some memory allocations 
going on there which have the potential of locking all the 
threads any time one of them tries to allocate.


Parallelism's benefits are largely erased by the memory 
allocator lock and can be set back by the cache being 
invalidated as it jumps around that allocated memory, so you 
generally want to make sure the threads are doing work on local 
variables only.


This restricts what you can do with strings, since most the 
std.string functions allocate new strings for their return 
values...


Is there a way to do thread-local allocations?


More threads - Slower program ??

2015-08-12 Thread Yuxuan Shui via Digitalmars-d-learn
Here is a small program 
(https://gist.github.com/yshui/a426f73be77d1d699555) that uses 
taskPool to parallely reading from /proc/pid/ and sum the swap 
usage.


Individual tasks has zero dependency between each other, but when 
I remove the 'defaultPoolThreads(1)' line, the programs takes 8x 
more CPU time and also runs longer in total (I have 12 cores).


What is wrong here?



How to make a standalone .a using dub?

2015-07-29 Thread Yuxuan Shui via Digitalmars-d-learn
Is there a way to have dub pack the library along with all its 
dependencies into a single .a?


Re: How to make a standalone .a using dub?

2015-07-29 Thread Yuxuan Shui via Digitalmars-d-learn

On Thursday, 30 July 2015 at 00:14:23 UTC, Yuxuan Shui wrote:
Is there a way to have dub pack the library along with all its 
dependencies into a single .a?


And if not, is there any D build system capable of doing this? 
reggae maybe?


Re: Template function that accept strings and array of strings

2015-07-15 Thread Yuxuan Shui via Digitalmars-d-learn

On Wednesday, 15 July 2015 at 21:57:50 UTC, badlink wrote:
Hello, I can't figure how to write a template function that 
accept either strings or array of strings.


This is my current code:

bool hasItemParent(T)(const(char)[] itemId, const(T)[] parentId)
if (is(typeof(T) == char) || (isArray!T  is(typeof(T[]) == 
char)))

{...}

I used const(T)[] because I'd like to accept immutable and 
mutable strings.

But calling it with an immutable string generate this error:

Error: template cache.MetadataCache.hasItemParent cannot deduce 
function from argument types !()(string, string), candidates 
are:
cache.MetadataCache.hasItemParent(T)(const(char)[] itemId, 
const(T)[] parentId) if (is(typeof(T) == char))


Any suggestions ?


T is already a type, you don't need to typeof() it.

This should work:

bool hasItemParent(T)(const(char)[] itemId, const(T)[] parentId)
if (is(T == char) || (isArray!T  is(ElementType!T == char)))



  1   2   >