Re: Static foreach pull request
On 5/10/17 3:45 PM, Stefan Koch wrote: On Wednesday, 10 May 2017 at 18:41:30 UTC, Timon Gehr wrote: On 10.05.2017 16:21, Stefan Koch wrote: On Wednesday, 10 May 2017 at 14:13:09 UTC, Timon Gehr wrote: On 10.05.2017 15:18, Stefan Koch wrote: if you try assert([] is null), it should fail. It doesn't. I have tried to make that point before, unsuccessfully. Empty arrays may or may not be null, but the empty array literal is always null. cat t3.d static assert([] is null); --- dmd t.d -c --- t3.d(1): Error: static assert ([] is null) is false void main(){ import std.stdio; enum x = [] is null; auto y = [] is null; writeln(x," ",y); // "false true" } Oh fudge. Another case where the ctfe-engine goes the right way; And the runtime version does not ... we should fix this one of these days. [] lowers to a d runtime call (in lifetime, the function to allocate an array) with no elements. The function must return a valid array with 0 length. null is such an array. It's not an error at all, and should not be fixed or changed IMO. You almost never want to use 'is' on an array, as it compares just the pointer and length. Usually you want '=='. For instance, you would never do: [1, 2, 3] is [1, 2, 3] And expect any sane result. It might actually be true on some compiler that's clever enough! -Steve
Re: Static foreach pull request
On Wednesday, 10 May 2017 at 18:41:30 UTC, Timon Gehr wrote: On 10.05.2017 16:21, Stefan Koch wrote: On Wednesday, 10 May 2017 at 14:13:09 UTC, Timon Gehr wrote: On 10.05.2017 15:18, Stefan Koch wrote: if you try assert([] is null), it should fail. It doesn't. I have tried to make that point before, unsuccessfully. Empty arrays may or may not be null, but the empty array literal is always null. cat t3.d static assert([] is null); --- dmd t.d -c --- t3.d(1): Error: static assert ([] is null) is false void main(){ import std.stdio; enum x = [] is null; auto y = [] is null; writeln(x," ",y); // "false true" } Oh fudge. Another case where the ctfe-engine goes the right way; And the runtime version does not ... we should fix this one of these days.
Re: Static foreach pull request
On 10.05.2017 16:21, Stefan Koch wrote: On Wednesday, 10 May 2017 at 14:13:09 UTC, Timon Gehr wrote: On 10.05.2017 15:18, Stefan Koch wrote: if you try assert([] is null), it should fail. It doesn't. I have tried to make that point before, unsuccessfully. Empty arrays may or may not be null, but the empty array literal is always null. cat t3.d static assert([] is null); --- dmd t.d -c --- t3.d(1): Error: static assert ([] is null) is false void main(){ import std.stdio; enum x = [] is null; auto y = [] is null; writeln(x," ",y); // "false true" }
Re: Static foreach pull request
On Wednesday, 10 May 2017 at 14:13:09 UTC, Timon Gehr wrote: On 10.05.2017 15:18, Stefan Koch wrote: if you try assert([] is null), it should fail. It doesn't. I have tried to make that point before, unsuccessfully. Empty arrays may or may not be null, but the empty array literal is always null. cat t3.d static assert([] is null); --- dmd t.d -c --- t3.d(1): Error: static assert ([] is null) is false
Re: Static foreach pull request
On 10.05.2017 15:18, Stefan Koch wrote: if you try assert([] is null), it should fail. It doesn't. I have tried to make that point before, unsuccessfully. Empty arrays may or may not be null, but the empty array literal is always null.
Re: Static foreach pull request
On Wednesday, 10 May 2017 at 13:11:46 UTC, Atila Neves wrote: On Wednesday, 10 May 2017 at 11:12:06 UTC, Stefan Koch wrote: null : () { Slice* s; s = null; return s; } [] : () { Slice* s; s = alloca(sizeof(*s)); s.base = null; s.length = 0; return s; } Therefore null.length => (cast(Slice*)null).length; which results in a segfault. and [].length => (cast(Slice*)somevalidSliceDiscriptor).length; That's not how "regular" D works though. Atila What do you mean ? Hmm this should be how it works They reason why assert([] == null) holds. is because base is implicitly alias thised. if you try assert([] is null), it should fail.
Re: Static foreach pull request
On Wednesday, 10 May 2017 at 11:12:06 UTC, Stefan Koch wrote: On Wednesday, 10 May 2017 at 09:42:53 UTC, Timon Gehr wrote: [...] So here is the difference between null and []: null : () { Slice* s; s = null; return s; } [] : () { Slice* s; s = alloca(sizeof(*s)); s.base = null; s.length = 0; return s; } Therefore null.length => (cast(Slice*)null).length; which results in a segfault. and [].length => (cast(Slice*)somevalidSliceDiscriptor).length; That's not how "regular" D works though. Atila
Re: Static foreach pull request
On Wednesday, 10 May 2017 at 09:42:53 UTC, Timon Gehr wrote: On 09.05.2017 23:56, Timon Gehr wrote: core.exception.AssertError@ddmd/blockexit.d(90): Assertion failure ... Thanks! (It's a known issue though: https://github.com/tgehr/dmd/blob/static-foreach/test_staticforeach.d#L330.) Actually, yours is a different case with the same outcome (f and idonotexist do not matter at all, the issue exists even for static foreach(j;0..0){}). All static foreach loops over empty (non-AliasSeq) aggregates failed that assertion. The reason was that CTFE can return a null literal from a function that returns T[], but the constant folder cannot actually evaluate null.length for some reason. So here is the difference between null and []: null : () { Slice* s; s = null; return s; } [] : () { Slice* s; s = alloca(sizeof(*s)); s.base = null; s.length = 0; return s; } Therefore null.length => (cast(Slice*)null).length; which results in a segfault. and [].length => (cast(Slice*)somevalidSliceDiscriptor).length;
Re: Static foreach pull request
On 09.05.2017 23:56, Timon Gehr wrote: core.exception.AssertError@ddmd/blockexit.d(90): Assertion failure ... Thanks! (It's a known issue though: https://github.com/tgehr/dmd/blob/static-foreach/test_staticforeach.d#L330.) Actually, yours is a different case with the same outcome (f and idonotexist do not matter at all, the issue exists even for static foreach(j;0..0){}). All static foreach loops over empty (non-AliasSeq) aggregates failed that assertion. The reason was that CTFE can return a null literal from a function that returns T[], but the constant folder cannot actually evaluate null.length for some reason.
Re: Static foreach pull request
On 09.05.2017 23:56, Timon Gehr wrote: core.exception.AssertError@ddmd/blockexit.d(90): Assertion failure ... Thanks! (It's a known issue though: https://github.com/tgehr/dmd/blob/static-foreach/test_staticforeach.d#L330.) I guess the problem is that I do not propagate the error condition properly, but I'm not sure how to do it. (In my frontend, error handling control flow is automated almost completely.) https://github.com/dlang/dmd/pull/6760/commits/0ac9556cb3a0e1ea1de02e97e7f05e866584de84
Re: Static foreach pull request
On 5/10/17 1:00 AM, Andrei Alexandrescu wrote: On 5/10/17 12:56 AM, Timon Gehr wrote: Thanks! (It's a known issue though: https://github.com/tgehr/dmd/blob/static-foreach/test_staticforeach.d#L330.) I guess the problem is that I do not propagate the error condition properly, but I'm not sure how to do it. (In my frontend, error handling control flow is automated almost completely.) Ignorant thought: guard the static foreach with a static if? -- Andrei (as a lowering that is)
Re: Static foreach pull request
On 5/10/17 12:56 AM, Timon Gehr wrote: Thanks! (It's a known issue though: https://github.com/tgehr/dmd/blob/static-foreach/test_staticforeach.d#L330.) I guess the problem is that I do not propagate the error condition properly, but I'm not sure how to do it. (In my frontend, error handling control flow is automated almost completely.) Ignorant thought: guard the static foreach with a static if? -- Andrei
Re: Static foreach pull request
On 09.05.2017 23:39, Guillaume Boucher wrote: On Tuesday, 9 May 2017 at 03:06:37 UTC, Timon Gehr wrote: If you are interested in static foreach making it into the language, please play with the implementation and tell me how to break it. Code: void main() { void f() { idonotexist(); } static foreach(j;0..0) { f(); } } Output: test_staticforeach.d(3): Error: undefined identifier 'idonotexist' Statement::blockExit(0x7f38d5cd35e0) static foreach (j; __error) { f(); } core.exception.AssertError@ddmd/blockexit.d(90): Assertion failure ... Thanks! (It's a known issue though: https://github.com/tgehr/dmd/blob/static-foreach/test_staticforeach.d#L330.) I guess the problem is that I do not propagate the error condition properly, but I'm not sure how to do it. (In my frontend, error handling control flow is automated almost completely.)
Re: Static foreach pull request
On Tuesday, 9 May 2017 at 03:06:37 UTC, Timon Gehr wrote: If you are interested in static foreach making it into the language, please play with the implementation and tell me how to break it. Code: void main() { void f() { idonotexist(); } static foreach(j;0..0) { f(); } } Output: test_staticforeach.d(3): Error: undefined identifier 'idonotexist' Statement::blockExit(0x7f38d5cd35e0) static foreach (j; __error) { f(); } core.exception.AssertError@ddmd/blockexit.d(90): Assertion failure ??:? _d_assertp [0x72e590] ??:? _ZN9blockExit9BlockExit5visitEP9Statement [0x637bd0] ??:? _ZN7Visitor5visitEP22StaticForeachStatement [0x625b45] ??:? _ZN22StaticForeachStatement6acceptEP7Visitor [0x61ebf8] ??:? int ddmd.blockexit.blockExit(ddmd.statement.Statement, ddmd.func.FuncDeclaration, bool) [0x637b69] ??:? _ZN9blockExit9BlockExit5visitEP17CompoundStatement [0x637ef9] ??:? _ZN17CompoundStatement6acceptEP7Visitor [0x61dc61] ??:? int ddmd.blockexit.blockExit(ddmd.statement.Statement, ddmd.func.FuncDeclaration, bool) [0x637b69] ??:? _ZN15FuncDeclaration9semantic3EP5Scope [0x5bba3d] ??:? _ZN6Module9semantic3EP5Scope [0x563f31] ??:? int ddmd.mars.tryMain(ulong, const(char)**) [0x5e2b46] ??:? _Dmain [0x5e3a12] ??:? _D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFNlZv [0x7301da] ??:? scope void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x730124] ??:? scope void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() [0x730196] ??:? scope void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate()) [0x730124] ??:? _d_run_main [0x7300a2] ??:? main [0x5e411f] ??:? __libc_start_main [0xd4999510]
Re: Static foreach pull request
On 5/9/17 3:46 PM, Timon Gehr wrote: On 09.05.2017 08:17, rikki cattermole wrote: On 09/05/2017 7:10 AM, Jack Stouffer wrote: On Tuesday, 9 May 2017 at 03:06:37 UTC, Timon Gehr wrote: ... I'm going to save you some time and tell you that Andrei and Walter are going to require a DIP for this. http://forum.dlang.org/thread/oenjmm$lds$1...@digitalmars.com Also, the DIP has existed for three years, it's just not very polished: https://wiki.dlang.org/DIP57 Cool! Now that you also have a proof of concept implementation, could you please flesh that up to make it solid and submit it as a PR? Thanks! -- Andrei
Re: Static foreach pull request
On 09.05.2017 05:42, Timon Gehr wrote: On 09.05.2017 05:06, Timon Gehr wrote: ... Some examples: https://github.com/tgehr/dmd/blob/71ab1280c88f9f0922fabf89ab3e7e1164b70e8b/src/test_staticforeach.d Better link: https://github.com/tgehr/dmd/blob/static-foreach/src/test_staticforeach.d Moved: https://github.com/tgehr/dmd/blob/static-foreach/test_staticforeach.d
Re: Static foreach pull request
On 09.05.2017 08:17, rikki cattermole wrote: On 09/05/2017 7:10 AM, Jack Stouffer wrote: On Tuesday, 9 May 2017 at 03:06:37 UTC, Timon Gehr wrote: ... I'm going to save you some time and tell you that Andrei and Walter are going to require a DIP for this. http://forum.dlang.org/thread/oenjmm$lds$1...@digitalmars.com Also, the DIP has existed for three years, it's just not very polished: https://wiki.dlang.org/DIP57
Re: Static foreach pull request
On 09.05.2017 09:26, Daniel N wrote: On Tuesday, 9 May 2017 at 03:42:48 UTC, Timon Gehr wrote: On 09.05.2017 05:06, Timon Gehr wrote: ... Some examples: https://github.com/tgehr/dmd/blob/71ab1280c88f9f0922fabf89ab3e7e1164b70e8b/src/test_staticforeach.d Better link: https://github.com/tgehr/dmd/blob/static-foreach/src/test_staticforeach.d EPIC! Thank you so much for doing this! ... Well, there was a hackaton, and I needed to do _something_. :) I thought this will have the highest impact. adds 'enum' and 'alias' on foreach loop variables to force one of the two. (Also works with existing foreach over AliasSeq.) I was wondering, would it be possible to move this to a separate pull request and get it merged before the rest? It would be useful on its own and probably would stand a chance of getting merged much faster... before every detail of static-foreach is agreed upon? Yes, I'll do that.
Re: Static foreach pull request
On Tuesday, 9 May 2017 at 09:17:06 UTC, Corey wrote: On Tuesday, 9 May 2017 at 03:06:37 UTC, Timon Gehr wrote: (the implementation is the result of two days of exhausting trial-and-error figuring out how the DMD frontend works). First time dealing with the frontend? Heck, two days sounds fast to me. I guess having written your own D frontend from scratch must have helped! https://github.com/tgehr/d-compiler
Re: Static foreach pull request
On Tuesday, 9 May 2017 at 03:06:37 UTC, Timon Gehr wrote: (the implementation is the result of two days of exhausting trial-and-error figuring out how the DMD frontend works). First time dealing with the frontend? Heck, two days sounds fast to me.
Re: Static foreach pull request
On Tuesday, 9 May 2017 at 03:42:48 UTC, Timon Gehr wrote: On 09.05.2017 05:06, Timon Gehr wrote: ... Some examples: https://github.com/tgehr/dmd/blob/71ab1280c88f9f0922fabf89ab3e7e1164b70e8b/src/test_staticforeach.d Better link: https://github.com/tgehr/dmd/blob/static-foreach/src/test_staticforeach.d EPIC! Thank you so much for doing this! adds 'enum' and 'alias' on foreach loop variables to force one of the two. (Also works with existing foreach over AliasSeq.) I was wondering, would it be possible to move this to a separate pull request and get it merged before the rest? It would be useful on its own and probably would stand a chance of getting merged much faster... before every detail of static-foreach is agreed upon?
Re: Static foreach pull request
On 09/05/2017 7:10 AM, Jack Stouffer wrote: On Tuesday, 9 May 2017 at 03:06:37 UTC, Timon Gehr wrote: ... I'm going to save you some time and tell you that Andrei and Walter are going to require a DIP for this. http://forum.dlang.org/thread/oenjmm$lds$1...@digitalmars.com
Re: Static foreach pull request
On Tuesday, 9 May 2017 at 03:06:37 UTC, Timon Gehr wrote: ... I'm going to save you some time and tell you that Andrei and Walter are going to require a DIP for this.
Re: Static foreach pull request
On 09.05.2017 05:06, Timon Gehr wrote: ... Some examples: https://github.com/tgehr/dmd/blob/71ab1280c88f9f0922fabf89ab3e7e1164b70e8b/src/test_staticforeach.d Better link: https://github.com/tgehr/dmd/blob/static-foreach/src/test_staticforeach.d