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


Suggestion: Bug fix releases (Re: Dicebot on leaving D: It is anarchy driven development in all its glory.)

2018-08-25 Thread Yuxuan Shui via Digitalmars-d
On Wednesday, 22 August 2018 at 11:59:37 UTC, Paolo Invernizzi 
wrote:

Just found by chance, if someone is interested [1] [2].

/Paolo

[1] 
https://gitlab.com/mihails.strasuns/blog/blob/master/articles/on_leaving_d.md
[2] 
https://blog.mist.global/articles/My_concerns_about_D_programming_language.html


I find Dicebot's article resonates quite strongly with me. I have 
been using D for hobby projects (i.e. not a lot of code) for 
about 3 years. During that time I found a handful of compiler 
bugs. An average programmer like me shouldn't be able to find 
bugs in the compiler so frequently.


And there are other problems, like language features interact 
weirdly, unhelpful/misleading error messages. All of this really 
gives me an impression that D is an immature language.


I think this is a pretty big problem, and I think it has not been 
given enough attention (never appeared in bold in the vision 
documents), probably until now.


So what if, we just forget about @safe, @nogc, and stuff like 
that for while, do a feature freeze and try our best to fix all 
the bugs, and rough corners?


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?


Re: Alignment of symbol is not kept during linking

2018-08-10 Thread Yuxuan Shui via Digitalmars-d

On Friday, 10 August 2018 at 08:46:46 UTC, Kagamin wrote:

On Thursday, 9 August 2018 at 14:15:31 UTC, Yuxuan Shui wrote:
The alignment is specified for the section, and it apparently 
kept. problem is individual symbols in the section don't have 
a alignment.


If the section is aligned at 16 bytes and the symbol is aligned 
at 16 bytes in the section, then the symbol will be aligned at 
16 bytes, I don't thunk this can go wrong.


I think you are correct. And I finally found out what is the 
culprit: The section is not actually aligned.


Bug report: https://issues.dlang.org/show_bug.cgi?id=19148


Re: Alignment of symbol is not kept during linking

2018-08-09 Thread Yuxuan Shui via Digitalmars-d

On Thursday, 9 August 2018 at 13:50:00 UTC, Kagamin wrote:

On Thursday, 9 August 2018 at 13:30:38 UTC, Yuxuan Shui wrote:
I searched around, and there seems to be no way to specify 
alignment on symbol, so I don't think the linker is in the 
wrong here.


The alignment should be specified for section.


The alignment is specified for the section, and it apparently 
kept. problem is individual symbols in the section don't have a 
alignment.


Re: Alignment of symbol is not kept during linking

2018-08-09 Thread Yuxuan Shui via Digitalmars-d

Clarifications:

On Thursday, 9 August 2018 at 13:30:38 UTC, Yuxuan Shui wrote:
I'm trying to build LDC with dmd and Musl, but the result ldc 
will always crash. I track that down to an unalignment SIMD 
access to a global variable. Apparently C++ compiler thinks the 
variable should be aligned to 16 bytes, but it's only aligned 
to 8 bytes.


SIMD is generated by the C++ compiler, the unaligned read happens 
in C++ code.


The accessed variable is a __gshared global variable.




Alignment of symbol is not kept during linking

2018-08-09 Thread Yuxuan Shui via Digitalmars-d
I'm trying to build LDC with dmd and Musl, but the result ldc 
will always crash. I track that down to an unalignment SIMD 
access to a global variable. Apparently C++ compiler thinks the 
variable should be aligned to 16 bytes, but it's only aligned to 
8 bytes.


After some more digging, I find out dmd does try to do the right 
thing here. In the .o file, the offending symbol is indeed 
aligned to 16 bytes. But, after linking, that symbol got bumped 8 
bytes for some reason.


I searched around, and there seems to be no way to specify 
alignment on symbol, so I don't think the linker is in the wrong 
here.


C compilers would not put variables like that in .data, instead 
they use SHN_COMMON, and specify alignment there. LDC will just 
put every symbol into their own section, which also supports 
alignment. dmd should probably do the same.


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: A struct with a tuple as alias this, is kind of confusing

2018-07-27 Thread Yuxuan Shui via Digitalmars-d

On Friday, 27 July 2018 at 10:48:08 UTC, ag0aep6g wrote:

On 07/27/2018 12:19 PM, Yuxuan Shui wrote:

On Friday, 27 July 2018 at 10:17:21 UTC, Yuxuan Shui wrote:

[...]


Oh no, is it just defining arrays in the is() statement, 
though?


Yup.


But wait, this works:

alias C = A!(1,2,3);
static if (C[0] < C[1])
    pragma(msg, "Ha!");


Looks like DMD decides that `C[0]` and `C[1]` can't be types in 
that situation, so it tries the alias this. That's in line with 
how alias this is supposed to work: only kick in when the code 
wouldn't compile otherwise.


Let's just say this is confusing as hell.


Re: A struct with a tuple as alias this, is kind of confusing

2018-07-27 Thread Yuxuan Shui via Digitalmars-d

On Friday, 27 July 2018 at 10:17:21 UTC, Yuxuan Shui wrote:
First, it surprised me that I can't index a struct like that. 
So:


struct A(T...) {
alias S = T;
alias S this;
}

alias B = A!(int, double);
B[0] x; // Actually an array

Then, it surprised me again, that I actually can index it, 
sometimes


static if (!is(B[0] == B[1]))
pragma(msg, "Works!");

Why is this language like this :(


Oh no, is it just defining arrays in the is() statement, though?

But wait, this works:

alias C = A!(1,2,3);
static if (C[0] < C[1])
   pragma(msg, "Ha!");


A struct with a tuple as alias this, is kind of confusing

2018-07-27 Thread Yuxuan Shui via Digitalmars-d

First, it surprised me that I can't index a struct like that. So:

struct A(T...) {
alias S = T;
alias S this;
}

alias B = A!(int, double);
B[0] x; // Actually an array

Then, it surprised me again, that I actually can index it, 
sometimes


static if (!is(B[0] == B[1]))
pragma(msg, "Works!");

Why is this language like this :(


Re: I have a plan.. I really DO

2018-07-10 Thread Yuxuan Shui via Digitalmars-d-announce

On Friday, 6 July 2018 at 21:15:46 UTC, H. S. Teoh wrote:
On Fri, Jul 06, 2018 at 08:16:36PM +, Ecstatic Coder via 
Digitalmars-d-announce wrote: [...]
I've never said that this is something smart to do. I'm just 
saying that this code can perfectly be executed once in a C++ 
game frame without having to worry for a game freeze, because 
the string buffer deallocation is done once per frame too.


While with many GC languages, you actually DON'T KNOW when all 
those unused string buffers will be claimed.

[...]

Of course, for someone looking for an excuse not to use D, they 
will always find another reason why this is not sufficient. But 
that only strengthens the point that the GC is just a 
convenient excuse not to use D.


Not a good excuse to not fix GC, though.

Solve that problem, and they will just move on to the next 
excuse, because the GC is not the real reason; the real reason 
is probably non-technical. Like good ole inertia: people are 
lazy and set in their ways, and resist changing what they've 
grown comfortable with. But actually admitting this would make 
them look bad, so it is easier to find a convenient excuse like 
the GC (or whatever else is different from the status quo).


If that's the case, then we are doom. We might just as well 
forget about getting popular, and instead spend time making the 
language better.


Like fixing the GC.

(Although I don't quite agree with you. Some people DO resist 
change, that's why some decades old languages are still popular. 
But look at the popularity of new languages like Go, and Rust, 
and the ever-change landscape of front-end development. There're 
tons of people who adapt certain technology just because it is 
new, why can't that happen to D?)





T





Re: Normalize void

2018-07-10 Thread Yuxuan Shui via Digitalmars-d

On Tuesday, 10 July 2018 at 11:37:25 UTC, ag0aep6g wrote:

On 07/10/2018 11:56 AM, Yuxuan Shui wrote:

Possible alternatives:

* struct Void {}. Takes 1 byte, not as ideal
* alias Void = AliasSeq!(). Doesn't work as template argument. 
i.e.

   SomeTemplate!Void; // actually become SomeTemplate!()


What about `void[0]`? It's a proper type. You can declare a 
field with it. Size is 0.


Nice!


Re: Normalize void

2018-07-10 Thread Yuxuan Shui via Digitalmars-d

On Tuesday, 10 July 2018 at 09:50:45 UTC, Yuxuan Shui wrote:
Suppose I want to create a type to contain either a return 
value or an error, I could probably do something like this:


[...]


Breaking changes:

void[] x;
pragma(msg, x[0].sizeof); // now 0?


Re: Normalize void

2018-07-10 Thread Yuxuan Shui via Digitalmars-d

On Tuesday, 10 July 2018 at 09:50:45 UTC, Yuxuan Shui wrote:
Suppose I want to create a type to contain either a return 
value or an error, I could probably do something like this:


[...]


Possible alternatives:

* struct Void {}. Takes 1 byte, not as ideal
* alias Void = AliasSeq!(). Doesn't work as template argument. 
i.e.

  SomeTemplate!Void; // actually become SomeTemplate!()


Normalize void

2018-07-10 Thread Yuxuan Shui via Digitalmars-d
Suppose I want to create a type to contain either a return value 
or an error, I could probably do something like this:


struct Result(T, E) {
bool is_err;
union {
T result;
E error;
}
}

This will probably work fine, unless I don't need an error for 
some of the use cases (i.e. I want it to behave more like a 
Nullable). I can't just pass 'void' to 'E', because I can't 
define variable with type void. So I will have to:


struct Result(T, E) {
bool is_err;
union {
T result;
static if (!is(E == void))
E error;
}
}

I hope you can see what I mean here: 'void' is a special case I 
need to explicitly handle in templates. And special cases are bad.


What I want is for 'void' to behave like a normal type. This is 
not a crazy idea. 'void' can be considered as a unit type[0] in 
type theory. Basically, it is a type that can hold exactly 1 
value (so you don't need any storage space to store it). And it 
exists in many programming languages.


D actually already partially have 'void' as a unit type. For 
example:


void a() { return a(); } // returning void in a void function

Why don't we make it consistent across the whole language?

Here is how 'void' would behave if we made it a unit type:

void a; // fine
pragma(msg, a.sizeof); // 0
void b = a; // fine
writeln(a); // prints something intelligent about void

struct A {
void placeholder; // fine
}
pragma(msg, A.sizeof); // 1, same as empty struct

[0]: https://en.wikipedia.org/wiki/Unit_type


Re: Is package.d a good idea?

2018-07-01 Thread Yuxuan Shui via Digitalmars-d

On Sunday, 1 July 2018 at 18:03:41 UTC, Adam D. Ruppe wrote:

On Sunday, 1 July 2018 at 14:23:36 UTC, Yuxuan Shui wrote:
I was suggesting we do what Rust did. i.e. 'import foo', 
imports foo.d, which can in turn do 'import foo.bar', which 
will import foo/bar.d.


Yeah, that's the way it should have been done in the first 
place. Nowhere else in D does it require a specific filename 
except package.d - it is a pointless inconsistency anyway.


Now we just need to wait for someone to write the DIP


Re: Is package.d a good idea?

2018-07-01 Thread Yuxuan Shui via Digitalmars-d

On Sunday, 1 July 2018 at 11:55:17 UTC, Jonathan M Davis wrote:
On Sunday, July 01, 2018 11:36:51 Yuxuan Shui via Digitalmars-d 
wrote:

[...]


The entire reason that package.d was added as a feature was so 
that modules could be split into packages without breaking 
code, and it's still valuable for that.


[...]


I was suggesting we do what Rust did. i.e. 'import foo', imports 
foo.d, which can in turn do 'import foo.bar', which will import 
foo/bar.d.


Is package.d a good idea?

2018-07-01 Thread Yuxuan Shui via Digitalmars-d
In Rust, they have something call mod.rs, which is very similar 
to package.d. When you use a module 'foo' in Rust, it can either 
be 'foo.rs' or 'foo/mod.rs'. If 'foo' has sub-modules, it has to 
be 'foo/mod.rs'.


Now in the Rust 2018 edition, they are getting rid of mod.rs. So 
when you import 'foo', rustc will always look for 'foo.rs', and 
if 'foo' has submodules, it can still reside in 
'foo/submodule.rs'.


This makes me think if package.d is a good idea, and if we should 
try to get rid of it as well.


Re: Why are we not using libbacktrace for backtrace?

2018-06-14 Thread Yuxuan Shui via Digitalmars-d

On Thursday, 14 June 2018 at 17:26:50 UTC, Johannes Pfau wrote:

Am Thu, 14 Jun 2018 01:19:30 + schrieb Yuxuan Shui:

Just ran into a problem where program will crash during stack 
trace. Turns out not only does druntime not support compressed 
debug info, it cannot handle it at all.


So I was thinking why don't we use a existing and proven 
library for this, instead of roll our own?


GDC uses libbacktrace since 2013: 
https://github.com/D-Programming-GDC/ 
GDC/blob/master/libphobos/libdruntime/gcc/backtrace.d


I think the main problem for DMD/LDC is that libbacktrace is 
not an installed library, it's only available while building 
GCC.


libbacktrace is a standalone library: 
https://github.com/ianlancetaylor/libbacktrace


GCC is using it.


Why are we not using libbacktrace for backtrace?

2018-06-13 Thread Yuxuan Shui via Digitalmars-d
Just ran into a problem where program will crash during stack 
trace. Turns out not only does druntime not support compressed 
debug info, it cannot handle it at all.


So I was thinking why don't we use a existing and proven library 
for this, instead of roll our own?


Re: What's happening with the `in` storage class

2018-06-09 Thread Yuxuan Shui via Digitalmars-d

On Saturday, 9 June 2018 at 07:56:08 UTC, Jonathan M Davis wrote:
Now that it is defined with DIP 1000, it seems like pretty much 
everyone trying to use it has a hard time understanding it at 
first (at least beyond the really simple cases).


It might have been because that the DIP is written in a somewhat 
confusing way.



- Jonathan M Davis





Re: DIP Draft Review News

2018-06-04 Thread Yuxuan Shui via Digitalmars-d-announce

On Monday, 4 June 2018 at 11:28:26 UTC, rikki cattermole wrote:

	Thought: Couldn't we have alternative names in the parameter 
instead? E.g.

```D
void foo(int x/x0/width, int y/y0/height){}
```


This intuitively means that any combination of the parameter 
names would work (e.g. (x, y0), (width, y)), which is not what we 
want.


Re: DIP Draft Review News

2018-06-04 Thread Yuxuan Shui via Digitalmars-d-announce

On Monday, 4 June 2018 at 10:30:18 UTC, rikki cattermole wrote:

On 04/06/2018 10:05 PM, Yuxuan Shui wrote:

On Monday, 4 June 2018 at 05:46:04 UTC, rikki cattermole wrote:

[...]


Not sure what you meant? This definitely does not error out: 
https://godbolt.org/g/PAiFPw


```D
@named:
int add(int a, int b);
int add(int b, int a) {
assert(a > 0);
return a + b;
}

void main() {
add(2, 0);
}
```



This shouldn't fail to compile. I think it's made clear in the 
DIP, parameter names play no role in overload resolution.



[...]


Care to elaborate why? In this DIP, name prefix on caller side 
is optional, caller is allowed to leave out any number of 
argument names if they want.


Not all parameters should be used as named arguments. Two 
syntax's one purpose isn't desired, which the DIP currently 
encourages.


Why is this two syntaxes one purpose?



Personally I want to keep named and unnamed completely separate 
and focus more upon public API.




While I'm not keen on 2 and definitely would love for 3, my 
first point is what will determine if I vote yes or not 
(assuming it gets there). My instincts are saying that it 
simply hasn't been thought through enough just yet and that 
there will be some real trouble with it.


I've dwelt on this for a couple of months now, and keeping 
thinking on it myself is not going to help. That's why I'm asking 
for feedback.




Ambiguity is nobody's friend when it comes to programming 
language proposals. You have time to think it over, and I could 
be very wrong (of course); but other wise as a lite version of 
named arguments its not a bad DIP, just maybe we can do better 
for D ;)




Re: DIP Draft Review News

2018-06-04 Thread Yuxuan Shui via Digitalmars-d-announce

On Monday, 4 June 2018 at 05:46:04 UTC, rikki cattermole wrote:

On 04/06/2018 5:01 PM, Mike Parker wrote:

Named arguments lite


I'm concerned about this DIP (keep in mind I wrote a referenced 
WIP DIP).


1. Reordering of parameters that match (with overloads)

```D
int add(int a, int b);
int add(int b, int a) { ... }
```

This part of the DIP needs quite a bit of filling out and I 
expect to have a lot of corner cases.


Are you saying that you have an add that is extern'd or do you 
mean a named argument function overload? By conventional wisdom 
it definitely should error out.


Not sure what you meant? This definitely does not error out: 
https://godbolt.org/g/PAiFPw




2. All or nothing.

```D
int add(int x, int y);
@named:
int add(int b, int a) { ... }
```

This is one of the reasons some people /don't/ want named 
arguments and have said that they out right would not use a 
language with it.




Care to elaborate why? In this DIP, name prefix on caller side is 
optional, caller is allowed to leave out any number of argument 
names if they want.




Re: Clash When Using Function as Template Value-Parameters?

2018-05-29 Thread Yuxuan Shui via Digitalmars-d

On Tuesday, 29 May 2018 at 12:37:04 UTC, Vijay Nayar wrote:

On Tuesday, 29 May 2018 at 11:36:11 UTC, Yuxuan Shui wrote:


No, wait a second. (a)=>a is in default argument list, so it 
is in the global scope. And it was instantiated when you 
instantiate BTree with char.


Could you explain that part a bit for me?  Yes, (a) => a is a 
default value, but when you say it is in the global scope, are 
you saying that a single object "(a) => a" is created in the 
global scope and not created for each template argument list, 
e.g. "BTree!int" and "BTree!char"?


I actually do not know in what scope such objects would be 
created, I had assumed it was per template-parameter list, but 
are you saying this is not the case?


I believe that is the case. Normally that will be fine, because 
you can't modify them. Type-deduced lambda is a very special 
case, as in their parameter types are deduced on first use, so in 
a sense, they are "modified" by the first instantiation.


BTW, I can't find the documentation about defining lambda with 
their parameter types omitted anywhere.


Re: Clash When Using Function as Template Value-Parameters?

2018-05-29 Thread Yuxuan Shui via Digitalmars-d

On Tuesday, 29 May 2018 at 11:34:03 UTC, Yuxuan Shui wrote:

On Saturday, 26 May 2018 at 11:56:30 UTC, Vijay Nayar wrote:
I've been experimenting with code that uses std.functional : 
binaryFun and unaryFun, but I have found that using these 
methods makes it impossible to add function attributes like 
@safe, @nogc, pure, and nothrow, because no guarantee can be 
made about the functions created via a stream.  For example, 
if you expect a comparator function like "a == b", someone can 
pass in "a.data--" instead.


[...]


This is probably a bug. BTree!char.lambda is clearly not the 
same as BTree!int.lambda, but the compiler seems to disagree?


No, wait a second. (a)=>a is in default argument list, so it is 
in the global scope. And it was instantiated when you instantiate 
BTree with char.


Re: Clash When Using Function as Template Value-Parameters?

2018-05-29 Thread Yuxuan Shui via Digitalmars-d

On Saturday, 26 May 2018 at 11:56:30 UTC, Vijay Nayar wrote:
I've been experimenting with code that uses std.functional : 
binaryFun and unaryFun, but I have found that using these 
methods makes it impossible to add function attributes like 
@safe, @nogc, pure, and nothrow, because no guarantee can be 
made about the functions created via a stream.  For example, if 
you expect a comparator function like "a == b", someone can 
pass in "a.data--" instead.


[...]


This is probably a bug. BTree!char.lambda is clearly not the same 
as BTree!int.lambda, but the compiler seems to disagree?


Re: Error about constructor calls in loops/labels, but there are no loops and labels?

2018-05-21 Thread Yuxuan Shui via Digitalmars-d
I've been using Swift in the past few years quite a bit, and it 
always amuses me when it can't figure out some kind of 
inference that seems trivial, but it just gives up because the 
compiler takes too long to determine: "This [one line] 
statement is too difficult, please split into multiple 
statements." This is the kind of stuff you would be 
encountering.


Clarification to my last point. I'm saying Swift's compiler is 
not smart enough, because other type inference languages doesn't 
seem to have this weird limitation. Worst case is they can't 
infer the type, then they fail back to not inferring, which is 
not worse than not having type inference.




-Steve





Re: Error about constructor calls in loops/labels, but there are no loops and labels?

2018-05-21 Thread Yuxuan Shui via Digitalmars-d

My response below might be a little off-topic.

On Monday, 21 May 2018 at 13:06:14 UTC, Steven Schveighoffer 
wrote:

[snip]

There is something to be said for keeping the compiler dumb:

1. Dumb is easy to implement, explain, and understand -- if you 
set the bar low then more compilers will be able to handle the 
use cases. Having code that compiles with all available 
compilers is better than something that you need a specific 
"really smart" compiler to work.


This would have been a fair point if there is more than one 
working D frontend right now. Maybe you are arguing the bar of D 
could be lower? Then the problem of where to draw the line pops 
up again. "Being dumb" couldn't be a goal of the language, right?


2. No matter how smart you make the compiler, you will get into 
situations that it can't figure out (halting problem).


True.

If you are going to have some situations that it doesn't 
handle, then it's really just a matter of where to draw the 
line. D has this problem with forward references -- it's a 
never ending battle of shuffling things around sometimes. The 
smarter you get, the more odd and difficult to deal with the 
cases that won't work become.


I would argue this is not because the compiler is too smart. This 
is because the behavior of the compiler is not pinned down. How D 
resolve forward references is not well documented, so when 
problem occurs you have to guess (or read the compiler source 
code, like a real man) to figure out how to solve it.




With inner functions, it's really easy to satisfy the compiler 
here. You just have to make a few changes in your code, I don't 
see it being a huge problem.


Not a huge problem, but certainly a rough edge that might make 
someone think D is an unrefined language.




I've been using Swift in the past few years quite a bit, and it 
always amuses me when it can't figure out some kind of 
inference that seems trivial, but it just gives up because the 
compiler takes too long to determine: "This [one line] 
statement is too difficult, please split into multiple 
statements." This is the kind of stuff you would be 
encountering.


Not sure if this is another case of compiler being not smart 
enough? And the solution seems to be pretty simple here.




-Steve





Re: Error about constructor calls in loops/labels, but there are no loops and labels?

2018-05-20 Thread Yuxuan Shui via Digitalmars-d

On Sunday, 20 May 2018 at 14:39:28 UTC, Jonathan M Davis wrote:
Well, constructors are one of the few places that the compiler 
attempts flow analysis for stuff other than optimization, 
because it pretty much has to in order to do what the language 
needs. And no, it's not very sophisticated about it, because 
it's simpler to guarantee correctness that way. It also 
highlights why Walter is usually against doing much in the way 
of flow analysis. By designing the language such that it 
doesn't need much flow analysis, you mostly avoid problems like 
this. Unfortunately, it becomes more or less impossible to 
completely avoid it in constructors when you have const or 
immutable members, so the compiler does have to do some flow 
analysis in constructors. And it seems that Walter's solution 
in this sort of situation is to err on the side of having the 
compiler be stupid in order to avoid better guarantee 
correctness.


Not being a compiler expert, I can't really comment on what the 
best approach would be here, but I know that Walter is 
typically against flow analysis at the semantic pass level 
precisely because it's very hard to get right, and it's always 
a battle between having it be sophisticated enough to not get 
in the programmers way and having it actually be guaranteed to 
be correct. As I understand it, flow analysis in stuff like the 
optimizer is _much_ easier, because the constructs you're 
dealing with are much easier. That's also why Walter and Andrei 
really like to design advanced language features in terms of 
lowering into simpler features (e.g. the use of destructors and 
scope statments all get lowered to try-catch-finally blocks). 
It's much easier to guarantee correctness with simpler features.


As for this particular case, I expect that the best course of 
action is to report it in bugzilla and see what Walter thinks 
is the best approach. I can comment on Walter's basic approach 
and reasoning based on what he's said about these issues in the 
past, but I can't way what his response would be to this 
particular example.


- Jonathan M Davis


I would argue that the best approach is to design the language to 
avoid flow analysis as much as possible. But for places that need 
it, the compiler should do as best as it can.


Re: Error about constructor calls in loops/labels, but there are no loops and labels?

2018-05-20 Thread Yuxuan Shui via Digitalmars-d

On Sunday, 20 May 2018 at 00:05:39 UTC, Jonathan M Davis wrote:
because it tends to become very difficult to get right in all 
cases and results in situations where the programmer is forced 
to do something in order to make the compiler shut up


Well, doesn't this post show exactly this problem, and that's 
because the compiler is too dumb?


Making the compiler smarter will only decrease the number of 
these cases.


Re: Error about constructor calls in loops/labels, but there are no loops and labels?

2018-05-19 Thread Yuxuan Shui via Digitalmars-d
On Thursday, 17 May 2018 at 20:32:23 UTC, Steven Schveighoffer 
wrote:

On 5/17/18 4:25 PM, DarkHole wrote:
On Thursday, 17 May 2018 at 20:02:19 UTC, Steven Schveighoffer 
wrote:

On 5/17/18 3:55 PM, DarkHole wrote:
This strange code - https://run.dlang.io/is/BKgv49 - fails 
with error "Error: constructor calls not allowed in loops or 
after labels", but there is no loops or labels.


Switch cases are labels.


But why?


You mean why is it an error? Probably because the compiler 
needs to guarantee you are calling the super constructor, and 
it can't figure out the flow when it sees labels/loops. Not 
that it's always impossible, but it's likely a complication the 
compiler devs don't want to deal with.


-Steve


Why isn't the compiler doing proper flow analysis? Is it that 
just no one bothered to implement it?


Re: Extend the call site default argument expansion mechanism?

2018-05-15 Thread Yuxuan Shui via Digitalmars-d

On Tuesday, 15 May 2018 at 13:59:37 UTC, jmh530 wrote:
On Tuesday, 15 May 2018 at 13:16:21 UTC, Steven Schveighoffer 
wrote:

[snip]

Hm... neat idea. Somehow, opDispatch can probably be used to 
make this work even more generically (untested):


struct WithAlloc(alias alloc)
{
   auto opDispatch(string s, Args...)(auto ref Args args) if 
(__traits(compiles, mixin(s ~ "(args, alloc)")))

   {
  mixin("return " ~ s ~ "(args, alloc);");
   }
}

-Steve


Example:
https://run.dlang.io/is/RV2xIH


Sadly with(WithAlloc!alloc) doesn't work. (If you have to use 
withAlloc.func everywhere, it kind of destroy the point, doesn't 
it?)


Re: Extend the call site default argument expansion mechanism?

2018-05-15 Thread Yuxuan Shui via Digitalmars-d

On Friday, 11 May 2018 at 18:55:03 UTC, Meta wrote:

On Friday, 11 May 2018 at 15:03:41 UTC, Uknown wrote:

[...]


It's not as pretty, and I don't know if it works outside this 
toy example yet, but you can do:


import std.stdio;

struct Allocator
{
auto call(alias F, Args...)(Args args)
{
return F(this, args);
}

void deallocateAll()
{
writeln("deallocateAll");
}
}

void f1(Allocator a, int n) { writeln("f1"); }
void f2(Allocator, string s, double d) { writeln("f2"); }

void main()
{
with (Allocator())
{
scope(exit) deallocateAll;
call!f1(2);
call!f2("asdf", 1.0);
}
}


I found another alternative to this:

https://godbolt.org/g/3Etims


Re: Extend the call site default argument expansion mechanism?

2018-05-11 Thread Yuxuan Shui via Digitalmars-d

On Thursday, 10 May 2018 at 15:15:03 UTC, Paul Backus wrote:
On Thursday, 10 May 2018 at 14:37:00 UTC, rikki cattermole 
wrote:

On 11/05/2018 2:33 AM, Yuxuan Shui wrote:

On Thursday, 10 May 2018 at 14:28:39 UTC, JN wrote:

But doing it with default argument expansion saves you 1 
allocation, has 1 less type, while being just as readable. I 
think that's a win.


class -> struct, now it is back to 1 allocation.


Even easier:

alias createDataStructure = (...) => new DataStructure(..., 
alloc);


I think one problem with this and Factory, is that you have to 
create one alias/lambda/factory type for every type that takes an 
allocator.


Re: Extend the call site default argument expansion mechanism?

2018-05-10 Thread Yuxuan Shui via Digitalmars-d

On Thursday, 10 May 2018 at 14:30:49 UTC, Seb wrote:

On Thursday, 10 May 2018 at 14:15:18 UTC, Yuxuan Shui wrote:

So in D I can use default argument like this:

int f(int line=__LINE__) {}

[...]


Why not define a TLS or global variable like theAllocator?
Or if you know it at compile-time as an alias?


Because my proposal is better encapsulated. Definitions of 
expanded default arguments are scoped, so in the given example, 
you can have different __ALLOC__ in different scope, where 
different allocators might be needed.


My proposal is basically an alias, but an alias which is 
recognized by compiler as subtitution keywords for default 
arguments (like __LINE__, __FILE__).


Re: Extend the call site default argument expansion mechanism?

2018-05-10 Thread Yuxuan Shui via Digitalmars-d

On Thursday, 10 May 2018 at 14:28:39 UTC, JN wrote:

On Thursday, 10 May 2018 at 14:15:18 UTC, Yuxuan Shui wrote:

[...]


For things like this you can use the OOP Factory pattern, 
pseudocode:


class DataStructureFactory
{
  this(Allocator alloc)
  {
this.alloc = alloc;
  }

  Allocator alloc;

  DataStructure createDataStructure(...)
  {
return new DataStructure(..., alloc)
  }
}

DataStructureFactory factory = new DataStructureFactory(new 
SomeAllocator())

auto data1 = factory.createDataStructure(...)
auto data2 = factory.createDataStructure(...)
auto data3 = factory.createDataStructure(...)


But doing it with default argument expansion saves you 1 
allocation, has 1 less type, while being just as readable. I 
think that's a win.


Re: Extend the call site default argument expansion mechanism?

2018-05-10 Thread Yuxuan Shui via Digitalmars-d

On Thursday, 10 May 2018 at 14:17:50 UTC, rikki cattermole wrote:

On 11/05/2018 2:15 AM, Yuxuan Shui wrote:

[...]


Bad idea, too much magic.


This magic is already there in D. I just want to use it in a 
different way.


Extend the call site default argument expansion mechanism?

2018-05-10 Thread Yuxuan Shui via Digitalmars-d

So in D I can use default argument like this:

int f(int line=__LINE__) {}

And because default argument is expanded at call site, f() will 
be called with the line number of the call site.


This is a really clever feature, and I think a similar feature 
can be useful in other ways.


Say I need to construct a bunch of data structure that takes an 
Allocator argument, I need to do this:


...
auto alloc = new SomeAllocator();
auto data1 = new DataStructure(..., alloc);
auto data2 = new DataStructure(..., alloc);
auto data3 = new DataStructure(..., alloc);
...

This looks redundant. But if we have the ability to define more 
special keywords like __LINE__, we can do something like this:


...
// constructor of DataStructure
this(Allocator alloc=__ALLOC__) {...}
...
auto alloc = new SomeAllocator();
define __ALLOC__ = alloc;
// And we don't need to pass alloc everytime
...

Is this a good idea?


Re: partially mutable immutable type problem, crazy idea

2018-05-08 Thread Yuxuan Shui via Digitalmars-d

On Wednesday, 9 May 2018 at 00:58:51 UTC, jmh530 wrote:

On Tuesday, 8 May 2018 at 22:31:10 UTC, Yuxuan Shui wrote:

snip]


This doesn't compile for me on run.dlang.io:

onlineapp.d(22): Error: template onlineapp.f cannot deduce 
function from argument types !()(B), candidates are:

onlineapp.d(1):onlineapp.f(T)(immutable T a)


Not supposed to. Was proposing an (crazy) idea here.


Re: partially mutable immutable type problem, crazy idea

2018-05-08 Thread Yuxuan Shui via Digitalmars-d
After watching the DConf 2018 video, I came up with this wild 
idea:


auto f(T)(immutable T a) {
// If T is a aggregate type, and I only use (directly
// or indirectly) the immutable fields of T,
// Then it should be OK to call f() with a partially mutable 
type

return a.x+1;
}

void main() {
struct A {
int x;
}
A a;
immutable(A) b;
f(a); // <- not fine
f(b); // <- fine

class B {
immutable int x = 10;
double f;
}
auto c = new B;
f(c); // <- fine too
}

I think this should solve the reference counting an immutable 
object, no? To f(), T will just looks like a normal immutable, 
uncopyable (because copying means modifying the reference 
counter) type


Re: Unreachable warning is annoying

2018-03-13 Thread Yuxuan Shui via Digitalmars-d
On Tuesday, 13 March 2018 at 14:40:21 UTC, Steven Schveighoffer 
wrote:

On 3/13/18 10:25 AM, Yuxuan Shui wrote:

[...]


This has been discussed before. There are a few ways around 
this. One is to do what you did. Another is to append a 
sentinel, or use id to terminate the loop:


foreach(id, R; S) {
static if(is(T == R))
return id;
else static if(id + 1 == S.length)
return -1;
}


Wait, I don't understand how this works.

Isn't this going to be expanded to something like:

return 0;
return 4;
// One return for every match
...
return -1;

Shouldn't this trigger unreachable warning too?



IMO, the "unreachable statement" error is bogus because it's 
reachable depending on the template parameters! In the coder's 
eyes, what matters is whether the line of source is reachable 
or not, not whether it's reachable in that instantiation.


Agreed.



-Steve




Unreachable warning is annoying

2018-03-13 Thread Yuxuan Shui via Digitalmars-d

See this simple example:

int staticFind(T, S...)() {
foreach(id, R; S) {
if (is(T == R))
return id;
}
}
return -1;
}

staticFind!(int, int, double) will generate a 'statement is 
unreachable' warning, and staticFind!(int, double) won't.


This behaviour is understandable, but annoying. If template 
writer cares about this unreachable warning, they basically can't 
use any early return at all.


So previous example has to be re-written into:

int staticFind(T, S...)() {
int ret = -1;
foreach(id, R; S) {
if (is(T == R) && ret == -1)
ret = id;
}
}
return ret;
}

However, this might not always be so simple in more complex 
functions. And this could potentially increase compilation time 
(maybe?).




Re: How to stringify a template instantiation expression?

2018-03-02 Thread Yuxuan Shui via Digitalmars-d

On Thursday, 1 March 2018 at 17:48:02 UTC, Simen Kjærås wrote:

On Thursday, 1 March 2018 at 16:46:30 UTC, Yuxuan Shui wrote:

[...]


string TemplateStringOf(T...)()
if (T.length == 1)
{
import std.traits : TemplateOf, TemplateArgsOf;
import std.meta : AliasSeq, staticMap;
import std.string : indexOf;
import std.conv : text;
static if (is(typeof({ alias a = TemplateOf!T; })))
{
alias Tmp = TemplateOf!T;
alias Args = TemplateArgsOf!T;

[...]


Ah, thanks. I was trying to match template instantiation using 
is() (i.e. is(T == S!R, S, R...)). But this doesn't work if T is 
a template.


Reading the code of TemplateOf, I realized I have to use template 
constraints for that. Maybe we can add support for something like 
is(alias T == ...)?


Re: How to stringify a template instantiation expression?

2018-03-01 Thread Yuxuan Shui via Digitalmars-d

On Thursday, 1 March 2018 at 16:46:30 UTC, Yuxuan Shui wrote:

On Wednesday, 28 February 2018 at 15:49:25 UTC, aliak wrote:
On Wednesday, 28 February 2018 at 15:09:56 UTC, Yuxuan Shui 
wrote:
For a template instantiation expression like A!(B, C!(D, E)), 
I want to get a string "A!(B, C!(D, E))", better if A, B, C, 
D, E is replaced by fully qualified name.


Is this possible?


A!(B, C!(D, E)).stringof I guess. Will print the former.

There's a Learn forum as well btw :)

Cheers


Did you actually try that? With dmd 2.079-rc1, this:

template A(T...) {}
struct B {}
struct D {}
struct E {}
template C(T...) {}
pragma(msg, (A!(B, C!(D, E))).stringof);

Prints:

A!(B, __T1CTS2ax1DTSQh1EZ)

When compiled


Even worse, if the template instantiation yields another 
template, e.g:


template A(T) { template A(T) {} }

A!int.stringof returns "A(T)", which is not useful at all.


Re: How to stringify a template instantiation expression?

2018-03-01 Thread Yuxuan Shui via Digitalmars-d

On Wednesday, 28 February 2018 at 15:49:25 UTC, aliak wrote:
On Wednesday, 28 February 2018 at 15:09:56 UTC, Yuxuan Shui 
wrote:
For a template instantiation expression like A!(B, C!(D, E)), 
I want to get a string "A!(B, C!(D, E))", better if A, B, C, 
D, E is replaced by fully qualified name.


Is this possible?


A!(B, C!(D, E)).stringof I guess. Will print the former.

There's a Learn forum as well btw :)

Cheers


Did you actually try that? With dmd 2.079-rc1, this:

template A(T...) {}
struct B {}
struct D {}
struct E {}
template C(T...) {}
pragma(msg, (A!(B, C!(D, E))).stringof);

Prints:

A!(B, __T1CTS2ax1DTSQh1EZ)

When compiled


How to stringify a template instantiation expression?

2018-02-28 Thread Yuxuan Shui via Digitalmars-d
For a template instantiation expression like A!(B, C!(D, E)), I 
want to get a string "A!(B, C!(D, E))", better if A, B, C, D, E 
is replaced by fully qualified name.


Is this possible?


Re: What does rt/sections_elf_shared.d do? (Porting dmd to musl)

2017-12-17 Thread Yuxuan Shui via Digitalmars-d

On Sunday, 17 December 2017 at 12:45:58 UTC, Yuxuan Shui wrote:
However, going through sections_elf_shared.d, it makes me feel 
it's doing some magic tricks with dl functions, but I don't 
know what for?




Looks like it's also repeating some work that is already done by 
the dynamic linker...




What does rt/sections_elf_shared.d do? (Porting dmd to musl)

2017-12-17 Thread Yuxuan Shui via Digitalmars-d
I'm trying to get dmd and phobos working with musl. Right now I 
have a bootstrapped compiler built with musl, which seems to work 
fine. However user applications will segmentation fault before 
even reaches main.


I investigated a bit. Looks like musl is not happy with how 
druntime uses dlopen related functions. When a D library loads, 
it tries to call _d_dso_registry, which will try to get a handle 
of the library using dlopen. Meaning dlopen will be called on the 
library itself while it's still loading. This seems to break 
musl. Although this might also be a bug on musl side: it tries to 
call init functions even when RTLD_NOLOAD is passed to dlopen.


However, going through sections_elf_shared.d, it makes me feel 
it's doing some magic tricks with dl functions, but I don't know 
what for?


If my understand is correct, it's used to register TLS storage to 
GC. If that's the case, there must be simpler ways to do that.


Re: Supporting musl libc

2017-12-11 Thread Yuxuan Shui via Digitalmars-d

On Tuesday, 17 May 2016 at 08:51:01 UTC, Jacob Carlborg wrote:
As an alternative to glibc there's a C standard library called 
musl [1]. This is the C standard library used by ELLCC [2], a 
cross-compiler based on Clang. This cross-compiler makes it 
very easy to target other platforms and can be used as the C 
compiler when building with LDC.


The issue is that musl doesn't support the functions defined by 
execinfo.h: backtrace, backtrace_symbols_fd and 
backtrace_symbols, since these are glibc extensions. As far as 
I can see, these functions are used in two places in druntime: 
src/rt/backtrace/dwarf.d [3] and src/core/runtime.d [4].


The imports of execinfo is guarded by version(CRuntime_Glibc). 
I see that CRuntime_Glibc is a predefined version identifier 
defined by the compiler on Linux.


I'm not sure how to best handle different C standard libraries 
when it comes to choosing which one to use. Is it best to 
choose that when building the compiler or when building 
druntime? Or can it be a runtime option?


[1] https://www.musl-libc.org
[2] http://ellcc.org
[3] 
https://github.com/dlang/druntime/blob/master/src/rt/backtrace/dwarf.d#L41
[4] 
https://github.com/dlang/druntime/blob/master/src/core/runtime.d#L433-L434


I tried to build dmd on musl, and it seems to work relatively 
well.


I need to build dmd 2.067 for bootstrapping. It doesn't build 
out-of-box, but there's patches floating around.


There're some missing symbols in druntime: a couple math related, 
backtrace() and backtrace_symbols(). The former ones can be 
workaround, but and proper solution is needed. The latter ones 
can be solved by linking in libbacktrace().


Re: Proposal: Support for objects in switch statements

2017-10-31 Thread Yuxuan Shui via Digitalmars-d
On Wednesday, 1 November 2017 at 01:16:32 UTC, solidstate1991 
wrote:
After I started to alter my graphics engine to use the multiple 
kinds of bitmaps (now using multiple language features, like 
templates and aliases) on one layer, I noticed that type 
detection of bitmap objects would be easier and better 
readable, if instead of:


if(bitmapObject.classinfo == typeof(Bitmap4Bit)){
...
}else if(bitmapObject.classinfo == typeof(Bitmap8Bit)){...

I could easily use this:

switch(bitmapObject.classinfo){
case typeof(Bitmap4Bit):
...
case typeof(Bitmap8Bit):
}

On the other hand I cannot really think other uses for such 
language feature, maybe with structs.


Maybe use something similar to recieve()? Like:

match(obj, (Type1 x) => {}, (Type2 x) => {}, ...)


Re: -betterC and extern(C++) classes

2017-09-10 Thread Yuxuan Shui via Digitalmars-d
On Sunday, 10 September 2017 at 14:42:42 UTC, Moritz Maxeiner 
wrote:
On Sunday, 10 September 2017 at 14:04:20 UTC, rikki cattermole 
wrote:

On 10/09/2017 2:19 PM, Moritz Maxeiner wrote:
If TypeInfo for extern(C++) classes is removed, couldn't 
final extern(C++) classes without base class and which don't 
implement any interfaces omit the vtable so that the 
following assert holds:


---
final extern(C++) class Foo {}
static assert (__traits(classInstanceSize, Foo) == 0LU);
---

The reason I ask is that fairly often I have an abstraction 
that's better suited as a reference type than a value type, 
but doesn't need any runtime polymorphy (or the monitor 
standard classes have). Structs + pointers are the only way I 
know of to avoid the (in this special case) unneeded vtable 
overhead, but it always ends up looking worse to read.


We can do it for any class if its final.


Even final classes can always inherit (potentially already 
overridden) virtual methods from their parent classes and since 
all normal D classes inherit from core.object : Object [1], 
which defines virtual methods (`toString`, `toHash`, `opCmp, 
and `opEquals`), I don't see how this can be true.


With a final class reference, we always know what function to 
call at compile time (since it can't be inherited). Therefore we 
don't need a vtable.




The problem isn't generating the vtable's. But the information 
required for casting.


This applies to normal D classes, but D doesn't support 
(dynamic) casts for extern(C++) classes, anyway, so this 
shouldn't be an issue for them.


[1] 
https://github.com/somzzz/druntime/blob/74882c8a48dd8a827181e3b89c4f0f205c881ac5/src/object.d#L50





Re: -betterC and extern(C++) classes

2017-09-10 Thread Yuxuan Shui via Digitalmars-d
By the way, can we dynamic_cast extern(C++) classes in C++? If 
not, what are we generating these TypeInfo_Class for?


Re: -betterC and extern(C++) classes

2017-09-10 Thread Yuxuan Shui via Digitalmars-d

On Sunday, 10 September 2017 at 09:31:55 UTC, Walter Bright wrote:

On 9/10/2017 1:40 AM, Yuxuan Shui wrote:
I was experimenting with -betterC and found out that C++ 
classes doesn't work. Because the resulting object file needs 
a symbol "_D14TypeInfo_Class6__vtblZ" which is in druntime. I 
suppose this is to support T.classinfo?


Could we remove T.classinfo and make classes work under 
-betterC? Or is there some other reason preventing this from 
happening?


Yes, we do want to move towards "Better C++" working in an 
analogous manner, and that means removing the typeinfo 
dependency.


Is there a plan? Are there any simple tasks I can take/help?


-betterC and extern(C++) classes

2017-09-10 Thread Yuxuan Shui via Digitalmars-d
I was experimenting with -betterC and found out that C++ classes 
doesn't work. Because the resulting object file needs a symbol 
"_D14TypeInfo_Class6__vtblZ" which is in druntime. I suppose this 
is to support T.classinfo?


Could we remove T.classinfo and make classes work under -betterC? 
Or is there some other reason preventing this from happening?


Thanks.


Re: Release D 2.076.0

2017-09-01 Thread Yuxuan Shui via Digitalmars-d-announce

On Friday, 1 September 2017 at 14:03:26 UTC, Martin Nowak wrote:

Glad to announce D 2.076.0.

This release comes with static foreach, many -betterC 
enhancements, various phobos additions, an -mcpu=avx2 switch, 
and lots of bugfixes.


Thanks to everyone involved in this .

http://dlang.org/download.html 
http://dlang.org/changelog/2.076.0.html


- -Martin


" -betterC enhancements " is listed twice in the changelog


Re: Dynamic array leak?

2017-08-11 Thread Yuxuan Shui via Digitalmars-d

On Friday, 11 August 2017 at 18:44:56 UTC, bitwise wrote:

struct S {
static int count = 0;
this(int x) { ++count; }
this(this) { ++count; }
~this() { --count; }
}

int main(string[] argv)
{
S[] x = [S(1), S(1)];
writeln("GC allocated: ", (GC.addrOf(x.ptr) !is null));
x = null;
GC.collect();
writeln("live objects: ", S.count);
return 0;
}

output:
GC allocated: true
live objects: 2

expected:
GC allocated: true
live objects: 0

Is this a bug?

I thought that the first writeln() may be leaving a copy of the 
pointer lingering on the stack somewhere, but the output is 
still "live objects: 2" with that line commented out.


  Thanks


My guess is a pointer to the array still lives somewhere on the 
stack. This gives the expected output:


void f()
{
S[] x = [S(1), S(1)];
writeln("GC allocated: ", (GC.addrOf(x.ptr) !is null));
x = null;
}

int main(string[] argv)
{
f();
GC.collect();
writeln("live objects: ", S.count);
return 0;
}


Re: [OT] Generative C++

2017-08-03 Thread Yuxuan Shui via Digitalmars-d

On Tuesday, 1 August 2017 at 22:06:28 UTC, Walter Bright wrote:

On 7/31/2017 5:41 AM, Joakim wrote:
If he's right that C++ use is so balkanized, this will 
simplify some code but further balkanize the language.  That 
might be worth it for them, but rather than simplifying the 
language, it makes it more powerful and more complex, heading 
higher up into the hills rather than the lower ground he 
claims to be heading for.


I can't say I understand the proposal, but if it is similar to 
AST macros, my argument against that is well known and similar 
to yours.


Can you give us a pointer to your arguments? Some of us (me) are 
not familiar with them.


Thanks!


[OT] Generative C++

2017-07-28 Thread Yuxuan Shui via Digitalmars-d
Someone made an interesting proposal to C++: 
https://herbsutter.files.wordpress.com/2017/07/p0707r1.pdf


Thoughts?


Re: proposed @noreturn attribute

2017-07-20 Thread Yuxuan Shui via Digitalmars-d

On Wednesday, 19 July 2017 at 10:35:37 UTC, Stefan Koch wrote:

On Wednesday, 19 July 2017 at 10:24:35 UTC, Marc Schütz wrote:
On Sunday, 16 July 2017 at 20:44:13 UTC, Andrei Alexandrescu 
wrote:
Perhaps we go the inverse route and define the bottom type as 
typeof(*null). Would that simplify matters? There is some 
good consistency about it:


null: a pointer to anything. But can't be dereferenced.
*null: well, therefore... anything. But can't be created.


That sounds more like a top type, though, because as you said 
it can be "anything". A bottom type can not be anything, but 
only nothing.


It's the bottom.
Bottom is to Types, as Object is to Classes.


Actually, Object should be considered the Top type. All Classes 
are sub-classes of Object.


Re: proposed @noreturn attribute

2017-07-18 Thread Yuxuan Shui via Digitalmars-d

On Tuesday, 18 July 2017 at 15:26:59 UTC, Timon Gehr wrote:

On 18.07.2017 14:19, Stefan Koch wrote:

[...]


D has a C-inspired first-order type system, so it is not 
necessarily crucial to have it in D. (The reason I got involved 
in this thread is that it was proposed to add Bottom as a type 
that is not really a type; 'void' is annoying enough as the 
'null' of types. We don't really need another one of those.)


[...]


What about void?


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: C++17 cannot beat D surely

2017-06-06 Thread Yuxuan Shui via Digitalmars-d

On Sunday, 4 June 2017 at 04:39:21 UTC, Adam D. Ruppe wrote:

On Sunday, 4 June 2017 at 04:34:44 UTC, Mike Parker wrote:
I would not have expected enum b = sort(a) to trigger an 
allocation. auto b, yes, of course (and the disassembly from 
that is not much different). So I'd love to see a blog post 
explaining it.


I don't think I can do a full-on blog post, but I can answer it 
in a couple sentences: `enum` is treated by the compiler just 
like literals. Array literals allocate at each usage point, 
therefore enum arrays allocate at each usage point. (*each* 
usage point)


I think the allocation is because sort returns a SortedRange, not 
an array.


So even this allocates:

enum b = a.sort;
writeln(b[1]);

OTOH, this doesn't allocate:

enum b = a.sort.array;
writeln(b[1]);


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: weird empty string

2017-05-12 Thread Yuxuan Shui via Digitalmars-d

On Saturday, 13 May 2017 at 00:59:14 UTC, Stanislav Blinov wrote:

On Saturday, 13 May 2017 at 00:36:55 UTC, mogu wrote:

```d
if (null)
"1".writeln;
if ("")
"2".writeln;
if ("" == null)
"3".writeln;
```

Output:
2
3

How to understand this?


Boolean conversion on an array works on array's pointer, not 
it's length. So even though `"".length == 0`, `"".ptr != null`, 
and so `cast(bool)"" == true`.


However

if ([])
"1".writeln;

prints nothing.

So why does "" has non-null pointer while [] has null pointer? 
Looks inconsistent.


Turn .opApply into ranges

2017-05-09 Thread Yuxuan Shui via Digitalmars-d

I wondered if I can turn struct that defines opApply into ranges.

And it turns out to be surprisingly easy:

https://gist.github.com/yshui/716cfe987c89997760cabc2c951ca430

Maybe we can phase out opApply support in foreach? ;)

BTW, is there a way to get the "element type" from .opApply?


Re: Working code in an upcoming PR by Timon Gehr

2017-05-09 Thread Yuxuan Shui via Digitalmars-d-announce

On Tuesday, 9 May 2017 at 13:19:09 UTC, Timon Gehr wrote:

On 07.05.2017 19:03, Stanislav Blinov wrote:
On Sunday, 7 May 2017 at 16:57:58 UTC, Andrei Alexandrescu 
wrote:

[...]


I see only unsurprising Jpeg artifacts and not much more :)
It's too low resolution to make anything out.


It's approximately this:

---
alias Seq(T...)=T;

void main(){
import std.stdio: writeln;
import std.conv: to;
static foreach(i;Seq!(0,1,2)){
mixin(`int x`~to!string(i)~" = i;");
}
writeln(x0," ",x1," ",x2);
}

---
./src/dmd -run staticforeach.d
DMD v2.075.0-devel-fd4ff76 DEBUG
0 1 2
---

That was the first test case that worked.
I have made it almost feature-complete yesterday:

https://github.com/tgehr/dmd/blob/static-foreach/test_staticforeach.d


Yes! Finally!


Local pointer escape under current DIP1000 implementation

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

Code:

@safe auto id(scope int *p) {
int*[] a;
a ~= p;
return a;
}
@safe int *bar() {
int i;
return id()[0]; //pointer to local escaped
}

Compiles with -dip1000


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: CTFE Status 2

2017-04-05 Thread Yuxuan Shui via Digitalmars-d

On Wednesday, 5 April 2017 at 16:06:39 UTC, H. S. Teoh wrote:
On Wed, Apr 05, 2017 at 11:20:28AM +, Yuxuan Shui via 
Digitalmars-d wrote:

[...]


Did you read the entire article?

There is an entire section dedicated to interleaving of CTFE 
and templates.  And no, you still cannot run CTFE on the same 
part of the AST that is being template-expanded. But you *can* 
run CTFE on a subtree that has already been fully expanded.


And no, the forum post you linked to has nothing to do with 
CTFE. The
so-called "static foreach" is unrolled at AST expansion time, 
and is not

run through CTFE at all (unless later on you call the expanded
function at "compile-time"). And is() expressions are also not 
CTFE,

they are also evaluated at AST expansion time.

Read the entire article first. ;-)


T


I was talking about the use of R.front, R.drop in the template.


Re: CTFE Status 2

2017-04-05 Thread Yuxuan Shui via Digitalmars-d

On Sunday, 2 April 2017 at 04:34:34 UTC, H. S. Teoh wrote:
On Sat, Apr 01, 2017 at 05:06:14PM +, Inquie via 
Digitalmars-d wrote: [...]
How far off until newCTFE is usable to compile the majority of 
templates out there?


CTFE and templates are two separate things. You may want to 
read this (draft) article to get a better understanding of how 
they fit together:


https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time


T


CTFE and template expansion might be more tangled than you 
thought.


For example, you do have access to CTFE during template 
expansion: 
http://forum.dlang.org/thread/yaekhryalyxyooaiu...@forum.dlang.org


Re: Of the use of unpredictableSeed

2017-03-26 Thread Yuxuan Shui via Digitalmars-d
On Sunday, 26 March 2017 at 17:55:20 UTC, Nick Sabalausky 
(Abscissa) wrote:


2. Maybe the std.random docs need to be more clear, right up 
top, that it's not for anything security-related.


Agreed. Like what Python did here: 
https://docs.python.org/3/library/random.html





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?


Re: Parameterized template value parameter

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

On Friday, 24 March 2017 at 20:43:18 UTC, Dmitry Olshansky wrote:

On 3/24/17 12:24 AM, Yuxuan Shui wrote:
So I was trying to make my template take a value parameter, 
whose type

is also a parameter to the template. e.g.:

template A(Char[] str, Char);

But dmd complains about 'Char' being undefined. I have to 
write:


template A(Char, Char[] str);

Which is inconvenient, because now 'Char' can't be deduced by 
the compiler.


Can we make the first case work?


How about this?

template A(alias str)
if(is(typeof(str) : Char[], Char)){
alias Char = typeof(str[0]);
//  ...
}


Yes. This is what I ended up doing 
(https://github.com/yshui/sdpc/blob/master/sdpc/parsers.d#L45).


One problem of this is that 'str' is not longer restricted to be 
a compile time value. Which is probably fine, but kind of makes 
me uncomfortable.




In general it's sometimes possible to do the deduction w/o 
introducing more template arguments.


---
Dmitry Olshansky





Re: sdpc - Simple/Stupid D parser combinator

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

On Friday, 24 March 2017 at 17:53:14 UTC, Basile B. wrote:

On Thursday, 23 March 2017 at 22:55:10 UTC, Yuxuan Shui wrote:

[...]


Thanks for sharing this but your project is not visible!

Gitlab is a bit confusing because by default repositories are 
private. Go to your project setting(should be 
https://gitlab.com/yshui/sdpc/edit):

- set "Project Visibility" to "public".
- set "Repository" to "everyone with access".


Thanks for pointing this out! Obviously I only set "Visibility" 
to "public" and forgot the other settings...


Parameterized template value parameter

2017-03-23 Thread Yuxuan Shui via Digitalmars-d
So I was trying to make my template take a value parameter, whose 
type is also a parameter to the template. e.g.:


template A(Char[] str, Char);

But dmd complains about 'Char' being undefined. I have to write:

template A(Char, Char[] str);

Which is inconvenient, because now 'Char' can't be deduced by the 
compiler.


Can we make the first case work?


Re: sdpc - Simple/Stupid D parser combinator

2017-03-23 Thread Yuxuan Shui via Digitalmars-d-announce

BTW, ddox cleanly has some problem with this symbol:

https://yshui.gitlab.io/sdpc/sdpc/parsers/skip_whitespace.html


sdpc - Simple/Stupid D parser combinator

2017-03-23 Thread Yuxuan Shui via Digitalmars-d-announce

GitLab: https://gitlab.com/yshui/sdpc
Documents: https://yshui.gitlab.io/sdpc
Dub: http://code.dlang.org/packages/sdpc

I started this project ~1.8 years ago. It only took me a couple 
of weeks to write, and I learned a lot about D's template system 
(and its limitations) by writing it. But back then I wasn't 
confident with the code quality and documentation enough to make 
it public. Then life caught up with me and I can't spend time on 
it.


Recently I finally got some time and decided to cleanup the code 
and make it available to more people. Now I'm comfortable with it 
enough to have more eyes on it.


sdpc is a very simple parser combinator library. So it lacks some 
bells and whistles like left recursion or memoization. But it 
should be able to handle a lot of the simpler use cases.


(I know we have pry now. A bit of competition won't hurt =] ).



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?


Re: Annoying thing about auto ref function template

2017-03-21 Thread Yuxuan Shui via Digitalmars-d

On Tuesday, 21 March 2017 at 01:10:38 UTC, Jonathan M Davis wrote:
On Monday, March 20, 2017 22:14:37 Yuxuan Shui via 
Digitalmars-d wrote:
On Monday, 20 March 2017 at 21:53:47 UTC, Jonathan M Davis 
wrote:

> [...]

Makes sense...

OK, attempt 2: how about support implicit partial application 
for templates?


Well, you can do something like

template foo(T)
{
auto foo()(auto ref T t)
{
return t;
}
}

void main()
{
alias f = foo!int;
auto a = f(42);
}

and then foo!int, but you're not going to get a function 
pointer out of it, since for that, you need to instantiate the 
inner function template. It does give partial instantiation 
though.


- Jonathan M Davis


This is looks doable. Can we do this for all auto ref functions 
in phobos?


Re: Annoying thing about auto ref function template

2017-03-20 Thread Yuxuan Shui via Digitalmars-d

On Monday, 20 March 2017 at 21:53:47 UTC, Jonathan M Davis wrote:
On Monday, March 20, 2017 21:37:26 Yuxuan Shui via 
Digitalmars-d wrote:

[...]


auto ref for non-templates would not be quite the same thing, 
and regardless, it wouldn't help any with explictly 
instantiating a template that had an auto ref parameter. So, it 
really wouldn't solve the problem at all. It would just make it 
so that if you didn't want a templated function, you could use 
auto ref.


[...]


Makes sense...

OK, attempt 2: how about support implicit partial application for 
templates?


[...]




Re: Annoying thing about auto ref function template

2017-03-20 Thread Yuxuan Shui via Digitalmars-d

On Monday, 20 March 2017 at 21:34:14 UTC, Yuxuan Shui wrote:
On Monday, 20 March 2017 at 21:08:40 UTC, Jonathan M Davis 
wrote:

[...]


This is a bit tedious because it requires you creating a new 
function.


Maybe we can create a template for that. But still, auto ref 
requires us to do things differently, which is annoying.


Easy solution: just support auto ref for non-templates.

I think someone has already did work on that?


Re: Annoying thing about auto ref function template

2017-03-20 Thread Yuxuan Shui via Digitalmars-d

On Monday, 20 March 2017 at 21:08:40 UTC, Jonathan M Davis wrote:
On Monday, March 20, 2017 13:20:52 Jonathan M Davis via 
Digitalmars-d wrote:
So, yes, this particular restriction can be annoying, but 
there is a good reason for the restriction (though the error 
message _is_ pretty bad), and I have no idea how we would fix 
the problem.


After thinking about this further, it does occur to me that 
there's a fairly simple workaround. e.g.


auto foo(T)(T t)
{
return bar(t);
}

auto bar(T)(auto ref T t)
{
...
}

Then you can just use foo!int. Now, that requires you to pick 
whether it's ref or not, but if there were a way to explicitly 
instantiate a function with an auto ref parameter, you'd have 
to do that anyway.


- Jonathan M Davis


This is a bit tedious because it requires you creating a new 
function.


Maybe we can create a template for that. But still, auto ref 
requires us to do things differently, which is annoying.


Re: Annoying thing about auto ref function template

2017-03-20 Thread Yuxuan Shui via Digitalmars-d

On Monday, 20 March 2017 at 19:49:03 UTC, Yuxuan Shui wrote:
And you can't do that with an auto ref template, which makes 
them quite annoying.




BTW, the error message you get when you try to do this, is not 
very helpful:


'auto' can only be used as part of 'auto ref' for template 
function parameters






Annoying thing about auto ref function template

2017-03-20 Thread Yuxuan Shui via Digitalmars-d
An auto ref function template should behave like a normal 
function template, but it doesn't.


You can fully instantiate a function template by specifying all 
of its template parameters, but you can't do that with auto ref 
templates. The only way to instantiate an auto ref template is to 
call it.


This makes auto ref an outlier. Because you get a function by 
instantiate function template, you can pass the result as 
template alias argument, and you can create alias of the 
resulting function. And you can't do that with an auto ref 
template, which makes them quite annoying.


I wonder why is auto ref designed this way? And can we change 
this?


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.


Re: DConf 2017 Schedule

2017-03-16 Thread Yuxuan Shui via Digitalmars-d-announce

On Wednesday, 15 March 2017 at 22:07:26 UTC, Bastiaan Veelo wrote:

On Wednesday, 15 March 2017 at 14:06:23 UTC, Yuxuan Shui wrote:

So someone already wrote a parser combinator for D?

I searched code.dlang.org (1.5 years ago?), and there was 
none, so I wasted couple weeks writing my own


So, is yours on code.dlang.org? If it would have been, maybe 
Dmitry wouldn't have to waste his time. Anyway, Pegged 
definitely was there already.


:-)


It's called sdpc on code.dlang.org. its quality is probably not 
as high, and probably won't compile right now. Because I didn't 
have time to polish it. But I did create a toy language using it 
back then.


Re: DConf 2017 Schedule

2017-03-15 Thread Yuxuan Shui via Digitalmars-d-announce

On Tuesday, 14 March 2017 at 20:16:34 UTC, Ali Çehreli wrote:

On 03/14/2017 09:35 AM, Moritz Maxeiner wrote:

On Tuesday, 14 March 2017 at 16:12:56 UTC, Mike Parker wrote:
Fresh from the D Foundation HQ, the DConf 2017 schedule [1] 
is now
available for your perusal. If you haven't registered yet, 
you have
just over five weeks to get it done. The registration 
deadline has
been set for April 23, so don't procrastinate. Even better, 
head over

to the registration page [2] and do it now!

[1] http://dconf.org/2017/schedule/
[2] http://dconf.org/2017/registration.html


Thanks, looks like lots of interesting talks!
One thing though:

Day 3: Saturday May 6, 2017
Day 4: Saturday May 7, 2017


Thanks. Apparently, that one's fixed.

Everybody, you can make pull requests to

  https://github.com/dlang/dconf.org

Don't use my clone of the repo as it involves an extra step.

Ali


So someone already wrote a parser combinator for D?

I searched code.dlang.org (1.5 years ago?), and there was none, 
so I wasted couple weeks writing my own


  1   2   3   >