digitalmars.D - C++17 cannot beat D surely
- Russel Winder via Digitalmars-d (14/14) Jun 03 2017 Bj=C3=B6rn Fahller has done compile time sort in C++17 here http://playf...
- Andrei Alexandrescu (9/13) Jun 03 2017 There is nothing to do really. Just use standard library sort.
- Russel Winder via Digitalmars-d (14/25) Jun 03 2017 But is this sort guaranteed to happen at compile time rather than
- Meta (4/19) Jun 03 2017 Yes: https://dlang.org/spec/function.html#interpretation
- Jacob Carlborg (8/10) Jun 03 2017 Yes. It's the context that decides if it occurs at compile time or at
- Basile B. (5/13) Jun 03 2017 Meeep. Wrong. The example is just wrong. 'static auto b = ...' is
- Stanislav Blinov (7/23) Jun 03 2017 Meep. Wrong :)
- ag0aep6g (5/10) Jun 03 2017 Meep. Meep. I wouldn't say you're wrong, but there's nitpicking to be do...
- Stanislav Blinov (4/15) Jun 03 2017 Mental note to self: never write assuming sentences in a NG :)
- Basile B. (5/29) Jun 03 2017 Actually i know where my error comes from. It comes from "static
- Steven Schveighoffer (4/17) Jun 03 2017 I'd say this deserves a blog post but it would be too short.
- Stanislav Blinov (3/22) Jun 03 2017 It already looks like a great blog post as is :)
- Basile B. (11/30) Jun 03 2017 Yes but let's correct the mistake first ;-]
- Timon Gehr (3/35) Jun 03 2017 This is worse. Now there is an allocation at runtime.
- jmh530 (3/15) Jun 03 2017 So maybe we can do a blog post on when to use static or enum?
- Andrei Alexandrescu (2/20) Jun 03 2017 Yes please! cc Mike. -- Andrei
- Mike Parker (52/73) Jun 03 2017 Any volunteers? This one surprised me.
- Adam D. Ruppe (6/10) Jun 03 2017 I don't think I can do a full-on blog post, but I can answer it
- Mike Parker (9/19) Jun 03 2017 Right, but I was under the impression that was only for direct
- Mike Parker (2/7) Jun 03 2017 Nevermind. I see where I got mixed up.
- Jonathan M Davis via Digitalmars-d (7/27) Jun 03 2017 As the enum has no address, it can't store anything. So, _anything_ that...
- Mike Parker (3/10) Jun 03 2017 Yeah, it hit me after my first reply to Adam. I'm in the middle
- Yuxuan Shui (9/19) Jun 06 2017 I think the allocation is because sort returns a SortedRange, not
- Steven Schveighoffer (15/32) Jun 06 2017 I think it's because the compiler isn't smart enough to pull out the
- =?UTF-8?Q?Ali_=c3=87ehreli?= (11/13) Jun 06 2017 One of the most effective examples is comparing .ptr with (seemingly)
- =?UTF-8?Q?Ali_=c3=87ehreli?= (9/12) Jun 06 2017 Sorry to notice this late but printing that ptr exposes the copy-paste
- Stanislav Blinov (16/30) Jun 06 2017 A bit OT, but how about this one?
- Walter Bright (3/18) Jun 06 2017 One trouble with making them the same is if one of the users of e change...
- Stefan Koch (2/20) Jun 03 2017 In General, prefer static immutable.
- Tourist (5/24) Jun 03 2017 Title would be longer:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (6/7) Jun 03 2017 I made many good friends at C++Now. Some of them know Atila from CppCon
- H. S. Teoh via Digitalmars-d (35/43) Jun 03 2017 [...]
- Stanislav Blinov (2/6) Jun 03 2017 ...except when you have `if (__ctfe)` :P
- H. S. Teoh via Digitalmars-d (9/17) Jun 03 2017 Ah, but if you want your function to work both at CTFE and runtime, then
- Jacob Carlborg (4/9) Jun 04 2017 Or using malloc/free at runtime but the GC at compile time.
- Jonathan M Davis via Digitalmars-d (4/43) Jun 04 2017 Be careful, or Mike will start hounding you to write the actual article....
- Mike Parker (5/8) Jun 04 2017 It's already written! And I'm looking for reviewers [1] so I can
- Atila Neves (10/17) Jun 05 2017 Beer involved. Conference. And they knew _me_? *Shocked*
- Russel Winder via Digitalmars-d (15/36) Jun 04 2017 a. that was my point in making the original post; and
- Vittorio Romeo (12/12) Jun 04 2017 Could someone clarify why the generated assembly for
- rikki cattermole (4/19) Jun 04 2017 _Dmain is exactly 2 instructions, so nope equivalent :)
- Vittorio Romeo (3/23) Jun 04 2017 I see. Is there any argument that can be passed to ldc in order
- rikki cattermole (3/27) Jun 04 2017 Should be a way, since you can pass arg directly via ldc to ld. But I
- David Nadlinger (5/7) Jun 04 2017 It is indeed done by default on Windows and Linux. If you dump
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (2/4) Jun 04 2017 Doesn't the strip command work?
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/8) Jun 04 2017 Oh wait, you didn't mean symbols, you meant code. LLVM has passes
- Era Scarecrow (6/7) Jun 06 2017 Actually i wouldn't mind a vlog or some short presentations on a
- Stefan Koch (5/12) Jun 06 2017 I could post a video about a simple ctfe transcompiler.
Bj=C3=B6rn Fahller has done compile time sort in C++17 here http://playfulp= r ogramming.blogspot.co.uk/2017/06/constexpr-quicksort-in-c17.html Surely D can do better? --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 03 2017
On 06/03/2017 01:03 PM, Russel Winder via Digitalmars-d wrote:Björn Fahller has done compile time sort in C++17 here http://playfulpr ogramming.blogspot.co.uk/2017/06/constexpr-quicksort-in-c17.html Surely D can do better?There is nothing to do really. Just use standard library sort. void main() { import std.algorithm, std.stdio; enum a = [ 3, 1, 2, 4, 0 ]; static auto b = sort(a); writeln(b); } Andrei
Jun 03 2017
On Sat, 2017-06-03 at 13:32 -0400, Andrei Alexandrescu via Digitalmars- d wrote:[=E2=80=A6] =20 There is nothing to do really. Just use standard library sort. =20 void main() { import std.algorithm, std.stdio; enum a =3D [ 3, 1, 2, 4, 0 ]; static auto b =3D sort(a); writeln(b); } =20But is this sort guaranteed to happen at compile time rather than runtime? --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Jun 03 2017
On Saturday, 3 June 2017 at 18:31:37 UTC, Russel Winder wrote:On Sat, 2017-06-03 at 13:32 -0400, Andrei Alexandrescu via Digitalmars- d wrote:Yes: https://dlang.org/spec/function.html#interpretation And there's no jumping through ridiculous hoops, unlike the article.[…] There is nothing to do really. Just use standard library sort. void main() { import std.algorithm, std.stdio; enum a = [ 3, 1, 2, 4, 0 ]; static auto b = sort(a); writeln(b); }But is this sort guaranteed to happen at compile time rather than runtime?
Jun 03 2017
On 2017-06-03 20:31, Russel Winder via Digitalmars-d wrote:But is this sort guaranteed to happen at compile time rather than runtime?Yes. It's the context that decides if it occurs at compile time or at runtime. Something declared as "static" or "enum" requires that the value can be evaluated at compile time. That's the beauty of D, the same functions can be used both at compile time and at runtime. -- /Jacob Carlborg
Jun 03 2017
On Saturday, 3 June 2017 at 18:45:56 UTC, Jacob Carlborg wrote:On 2017-06-03 20:31, Russel Winder via Digitalmars-d wrote:Meeep. Wrong. The example is just wrong. 'static auto b = ...' is not a compile-time variable. It's just a variable that's like a global but declared within a function. Remember the singleton pattern using 'static Stuff instance'.But is this sort guaranteed to happen at compile time rather than runtime?Yes. It's the context that decides if it occurs at compile time or at runtime. Something declared as "static" or "enum" requires that the value can be evaluated at compile time.
Jun 03 2017
On Saturday, 3 June 2017 at 20:18:59 UTC, Basile B. wrote:On Saturday, 3 June 2017 at 18:45:56 UTC, Jacob Carlborg wrote:Meep. Wrong :) Static initializers for static variables and constants are evaluated at compile time, initializing them with runtime values is a compile-time error. Yes, you can't do a static assert on b. It's still initialized at compile time though.On 2017-06-03 20:31, Russel Winder via Digitalmars-d wrote:Meeep. Wrong. The example is just wrong. 'static auto b = ...' is not a compile-time variable. It's just a variable that's like a global but declared within a function. Remember the singleton pattern using 'static Stuff instance'.But is this sort guaranteed to happen at compile time rather than runtime?Yes. It's the context that decides if it occurs at compile time or at runtime. Something declared as "static" or "enum" requires that the value can be evaluated at compile time.
Jun 03 2017
On 06/03/2017 10:29 PM, Stanislav Blinov wrote:Meep. Wrong :) Static initializers for static variables and constants are evaluated at compile time, initializing them with runtime values is a compile-time error.Meep. Meep. I wouldn't say you're wrong, but there's nitpicking to be done. You can't use a run-time value as the initializer, but you *can* initialize a static variable with a run-time value: using a static constructor.
Jun 03 2017
On Saturday, 3 June 2017 at 21:04:16 UTC, ag0aep6g wrote:On 06/03/2017 10:29 PM, Stanislav Blinov wrote:Mental note to self: never write assuming sentences in a NG :) You're correct, of course. I meant inline initialization, as presented in the code in question.Meep. Wrong :) Static initializers for static variables and constants are evaluated at compile time, initializing them with runtime values is a compile-time error.Meep. Meep. I wouldn't say you're wrong, but there's nitpicking to be done. You can't use a run-time value as the initializer, but you *can* initialize a static variable with a run-time value: using a static constructor.
Jun 03 2017
On Saturday, 3 June 2017 at 20:29:04 UTC, Stanislav Blinov wrote:On Saturday, 3 June 2017 at 20:18:59 UTC, Basile B. wrote:Actually i know where my error comes from. It comes from "static immutable". Since "static immutable" can be used in place of "enum" i've assumed that this was the real intention and not "static auto...".On Saturday, 3 June 2017 at 18:45:56 UTC, Jacob Carlborg wrote:Meep. Wrong :) Static initializers for static variables and constants are evaluated at compile time, initializing them with runtime values is a compile-time error. Yes, you can't do a static assert on b. It's still initialized at compile time though.On 2017-06-03 20:31, Russel Winder via Digitalmars-d wrote:Meeep. Wrong. The example is just wrong. 'static auto b = ...' is not a compile-time variable. It's just a variable that's like a global but declared within a function. Remember the singleton pattern using 'static Stuff instance'.But is this sort guaranteed to happen at compile time rather than runtime?Yes. It's the context that decides if it occurs at compile time or at runtime. Something declared as "static" or "enum" requires that the value can be evaluated at compile time.
Jun 03 2017
On Saturday, 3 June 2017 at 17:32:41 UTC, Andrei Alexandrescu wrote:On 06/03/2017 01:03 PM, Russel Winder via Digitalmars-d wrote:I'd say this deserves a blog post but it would be too short. -SteveBjörn Fahller has done compile time sort in C++17 here http://playfulpr ogramming.blogspot.co.uk/2017/06/constexpr-quicksort-in-c17.html Surely D can do better?There is nothing to do really. Just use standard library sort. void main() { import std.algorithm, std.stdio; enum a = [ 3, 1, 2, 4, 0 ]; static auto b = sort(a); writeln(b); }
Jun 03 2017
On Saturday, 3 June 2017 at 19:12:46 UTC, Steven Schveighoffer wrote:On Saturday, 3 June 2017 at 17:32:41 UTC, Andrei Alexandrescu wrote:It already looks like a great blog post as is :)On 06/03/2017 01:03 PM, Russel Winder via Digitalmars-d wrote:I'd say this deserves a blog post but it would be too short. -SteveBjörn Fahller has done compile time sort in C++17 here http://playfulpr ogramming.blogspot.co.uk/2017/06/constexpr-quicksort-in-c17.html Surely D can do better?There is nothing to do really. Just use standard library sort. void main() { import std.algorithm, std.stdio; enum a = [ 3, 1, 2, 4, 0 ]; static auto b = sort(a); writeln(b); }
Jun 03 2017
On Saturday, 3 June 2017 at 19:12:46 UTC, Steven Schveighoffer wrote:On Saturday, 3 June 2017 at 17:32:41 UTC, Andrei Alexandrescu wrote:Yes but let's correct the mistake first ;-] void main() { import std.algorithm, std.stdio; enum a = [ 3, 1, 2, 4, 0 ]; enum b = sort(a);// static is not CT !!!!! static assert(b[0] == 0); // does not pass with static auto b... writeln(b); }On 06/03/2017 01:03 PM, Russel Winder via Digitalmars-d wrote:I'd say this deserves a blog post but it would be too short. -SteveBjörn Fahller has done compile time sort in C++17 here http://playfulpr ogramming.blogspot.co.uk/2017/06/constexpr-quicksort-in-c17.html Surely D can do better?There is nothing to do really. Just use standard library sort. void main() { import std.algorithm, std.stdio; enum a = [ 3, 1, 2, 4, 0 ]; static auto b = sort(a); writeln(b); }
Jun 03 2017
On 03.06.2017 22:16, Basile B. wrote:On Saturday, 3 June 2017 at 19:12:46 UTC, Steven Schveighoffer wrote:There is no mistake. (But 'auto' is redundant.)On Saturday, 3 June 2017 at 17:32:41 UTC, Andrei Alexandrescu wrote:Yes but let's correct the mistake first ;-] ...On 06/03/2017 01:03 PM, Russel Winder via Digitalmars-d wrote:I'd say this deserves a blog post but it would be too short. -SteveBjörn Fahller has done compile time sort in C++17 here http://playfulpr ogramming.blogspot.co.uk/2017/06/constexpr-quicksort-in-c17.html Surely D can do better?There is nothing to do really. Just use standard library sort. void main() { import std.algorithm, std.stdio; enum a = [ 3, 1, 2, 4, 0 ]; static auto b = sort(a); writeln(b); }void main() { import std.algorithm, std.stdio; enum a = [ 3, 1, 2, 4, 0 ]; enum b = sort(a);// static is not CT !!!!! static assert(b[0] == 0); // does not pass with static auto b... writeln(b); }This is worse. Now there is an allocation at runtime.
Jun 03 2017
On Saturday, 3 June 2017 at 22:18:06 UTC, Timon Gehr wrote:There is no mistake. (But 'auto' is redundant.)So maybe we can do a blog post on when to use static or enum? Because smart people don't seem to be agreeing on this...void main() { import std.algorithm, std.stdio; enum a = [ 3, 1, 2, 4, 0 ]; enum b = sort(a);// static is not CT !!!!! static assert(b[0] == 0); // does not pass with static auto b... writeln(b); }This is worse. Now there is an allocation at runtime.
Jun 03 2017
On 06/03/2017 07:41 PM, jmh530 wrote:On Saturday, 3 June 2017 at 22:18:06 UTC, Timon Gehr wrote:Yes please! cc Mike. -- AndreiThere is no mistake. (But 'auto' is redundant.)So maybe we can do a blog post on when to use static or enum? Because smart people don't seem to be agreeing on this...void main() { import std.algorithm, std.stdio; enum a = [ 3, 1, 2, 4, 0 ]; enum b = sort(a);// static is not CT !!!!! static assert(b[0] == 0); // does not pass with static auto b... writeln(b); }This is worse. Now there is an allocation at runtime.
Jun 03 2017
On Sunday, 4 June 2017 at 03:28:32 UTC, Andrei Alexandrescu wrote:On 06/03/2017 07:41 PM, jmh530 wrote:Any volunteers? This one surprised me. Looking at the disassembly over at godbolt, I see this when using enum b = sort(a): ``` lea rax, [rbp-64] mov QWORD PTR [rax], 0 mov QWORD PTR [rax+8], 0 mov QWORD PTR [rbp-48], 0 mov QWORD PTR [rbp-40], 0 mov DWORD PTR [rbp-32], 0 mov DWORD PTR [rbp-44], 1 mov DWORD PTR [rbp-40], 2 mov DWORD PTR [rbp-36], 3 mov DWORD PTR [rbp-32], 4 mov esi, 5 mov edi, OFFSET FLAT:_D11TypeInfo_Ai6__initZ call _d_arrayliteralTX mov rdx, QWORD PTR [rbp-48] mov QWORD PTR [rax], rdx mov rdx, QWORD PTR [rbp-40] mov QWORD PTR [rax+8], rdx mov edx, DWORD PTR [rbp-32] mov DWORD PTR [rax+16], edx mov QWORD PTR [rbp-64], 5 mov QWORD PTR [rbp-56], rax mov rax, QWORD PTR [rbp-64] mov rdx, QWORD PTR [rbp-56] mov rcx, rax mov rbx, rdx mov rax, rdx mov rdi, rcx mov rsi, rax call writeln ``` And this when using static b = sort(a) (and the same with static immutable b): ``` mov rdx, QWORD PTR fs:std.range.SortedRange!(int[], "a < b").SortedRange example.main().b tpoff mov rax, QWORD PTR fs:std.range.SortedRange!(int[], "a < b").SortedRange example.main().b tpoff+8 mov rdi, rdx mov rsi, rax call writeln ``` 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.On Saturday, 3 June 2017 at 22:18:06 UTC, Timon Gehr wrote:Yes please! cc Mike. -- AndreiThere is no mistake. (But 'auto' is redundant.)So maybe we can do a blog post on when to use static or enum? Because smart people don't seem to be agreeing on this...void main() { import std.algorithm, std.stdio; enum a = [ 3, 1, 2, 4, 0 ]; enum b = sort(a);// static is not CT !!!!! static assert(b[0] == 0); // does not pass with static auto b... writeln(b); }This is worse. Now there is an allocation at runtime.
Jun 03 2017
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)
Jun 03 2017
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:Right, but I was under the impression that was only for direct use of the enum literal: enum a = [1, 2, 3]; auto b = a; I thought that assigning the result of a function call to an enum would force a compile-time evaluation of the function, so I would expect enum b = call(lit) to be identical to static immutable b = call(lit).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)
Jun 03 2017
On Sunday, 4 June 2017 at 04:47:56 UTC, Mike Parker wrote:On Sunday, 4 June 2017 at 04:39:21 UTC, Adam D. Ruppe wrote:I thought that assigning the result of a function call to an enum would force a compile-time evaluation of the function, so I would expect enum b = call(lit) to be identical to static immutable b = call(lit).Nevermind. I see where I got mixed up.
Jun 03 2017
On Sunday, June 04, 2017 04:47:56 Mike Parker via Digitalmars-d wrote:On Sunday, 4 June 2017 at 04:39:21 UTC, Adam D. Ruppe wrote:As the enum has no address, it can't store anything. So, _anything_ that's an enum is going to be effectively copy-pasted everywhere that it's used. The compiler is smart enough to just copy-past the result and not the expression, but the result still must be copied, and in the case of a dynamic array, that means an allocation. - Jonathan M DavisOn Sunday, 4 June 2017 at 04:34:44 UTC, Mike Parker wrote:Right, but I was under the impression that was only for direct use of the enum literal: enum a = [1, 2, 3]; auto b = a; I thought that assigning the result of a function call to an enum would force a compile-time evaluation of the function, so I would expect enum b = call(lit) to be identical to static immutable b = call(lit).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)
Jun 03 2017
On Sunday, 4 June 2017 at 05:12:13 UTC, Jonathan M Davis wrote:As the enum has no address, it can't store anything. So, _anything_ that's an enum is going to be effectively copy-pasted everywhere that it's used. The compiler is smart enough to just copy-past the result and not the expression, but the result still must be copied, and in the case of a dynamic array, that means an allocation. - Jonathan M DavisYeah, it hit me after my first reply to Adam. I'm in the middle of putting together a blog post right now.
Jun 03 2017
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 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]);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)
Jun 06 2017
On 6/6/17 8:28 PM, Yuxuan Shui wrote:On Sunday, 4 June 2017 at 04:39:21 UTC, Adam D. Ruppe wrote:I think it's because the compiler isn't smart enough to pull out the allocation for SortedRange!(...)([0,1,2,3,4])[1], but it is smart enough to know that [0,1,2,3,4][1] does not need to allocate. But it is pretty well known that enum'ing an array can have it allocate wherever it is used. For example, if you do this: enum b = a.sort.array; auto c = b; It will allocate. If you do: auto d = b; It will allocate again. That is an interesting artifact though. Another good reason to use static. -SteveOn Sunday, 4 June 2017 at 04:34:44 UTC, Mike Parker wrote: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]);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)
Jun 06 2017
On 06/06/2017 06:09 PM, Steven Schveighoffer wrote:But it is pretty well known that enum'ing an array can have it allocate wherever it is used.One of the most effective examples is comparing .ptr with (seemingly) itself: void main() { enum e = [ 1 ]; static assert(e.ptr != e.ptr); assert(e.ptr != e.ptr); } Both asserts pass. I'm surprised that e.ptr is usable at compile time. Fine, I guess... :) Ali
Jun 06 2017
On 06/06/2017 08:06 PM, Ali Çehreli wrote:enum e = [ 1 ]; static assert(e.ptr != e.ptr); I'm surprised that e.ptr is usable at compile time.Sorry to notice this late but printing that ptr exposes the copy-paste behavior of enums: pragma(msg, e.ptr); Outputs &[1][0] That makes sense. It's still interesting that static assert accepts that address comparison. I guess it knows that the result is always false. Ali
Jun 06 2017
On Wednesday, 7 June 2017 at 03:06:34 UTC, Ali Çehreli wrote:On 06/06/2017 06:09 PM, Steven Schveighoffer wrote:A bit OT, but how about this one? struct Tree { struct Node { Node* left, right; } Node* root = new Node; } void main() { Tree tree1, tree2; assert(tree1.root); assert(tree2.root); assert(tree1.root != tree2.root); // fails } Not `static`, not `enum`, but `new` at compile time and `root` is of course statically initialized :)But it is pretty well known that enum'ing an array can haveit allocatewherever it is used.One of the most effective examples is comparing .ptr with (seemingly) itself: void main() { enum e = [ 1 ]; static assert(e.ptr != e.ptr); assert(e.ptr != e.ptr); } Both asserts pass. I'm surprised that e.ptr is usable at compile time. Fine, I guess... :) Ali
Jun 06 2017
On 6/6/2017 8:06 PM, Ali Çehreli wrote:On 06/06/2017 06:09 PM, Steven Schveighoffer wrote: > But it is pretty well known that enum'ing an array can have it allocate > wherever it is used. One of the most effective examples is comparing .ptr with (seemingly) itself: void main() { enum e = [ 1 ]; static assert(e.ptr != e.ptr); assert(e.ptr != e.ptr); } Both asserts pass. I'm surprised that e.ptr is usable at compile time. Fine, I guess... :)One trouble with making them the same is if one of the users of e changes an element. Do the rest of the users see the change or the original?
Jun 06 2017
On Saturday, 3 June 2017 at 23:41:37 UTC, jmh530 wrote:On Saturday, 3 June 2017 at 22:18:06 UTC, Timon Gehr wrote:In General, prefer static immutable.There is no mistake. (But 'auto' is redundant.)So maybe we can do a blog post on when to use static or enum? Because smart people don't seem to be agreeing on this...void main() { import std.algorithm, std.stdio; enum a = [ 3, 1, 2, 4, 0 ]; enum b = sort(a);// static is not CT !!!!! static assert(b[0] == 0); // does not pass with static auto b... writeln(b); }This is worse. Now there is an allocation at runtime.
Jun 03 2017
On Saturday, 3 June 2017 at 19:12:46 UTC, Steven Schveighoffer wrote:On Saturday, 3 June 2017 at 17:32:41 UTC, Andrei Alexandrescu wrote:Title would be longer: Don't bring a knife to a gun fight especially if it is a knife made of a spoon, a toothbrush, duct tape and a shoelaceOn 06/03/2017 01:03 PM, Russel Winder via Digitalmars-d wrote:I'd say this deserves a blog post but it would be too short. -SteveBjörn Fahller has done compile time sort in C++17 here http://playfulpr ogramming.blogspot.co.uk/2017/06/constexpr-quicksort-in-c17.html Surely D can do better?There is nothing to do really. Just use standard library sort. void main() { import std.algorithm, std.stdio; enum a = [ 3, 1, 2, 4, 0 ]; static auto b = sort(a); writeln(b); }
Jun 03 2017
On 06/03/2017 12:12 PM, Steven Schveighoffer wrote:I'd say this deserves a blog post but it would be too short.I made many good friends at C++Now. Some of them know Atila from CppCon and other C++ conferences. (Beer involved. :) ) They told me Atila would routinely tell them during C++ presentations "This wouldn't be a talk at a DConf; it's a language feature in D." :) Ali
Jun 03 2017
On Sat, Jun 03, 2017 at 03:00:56PM -0700, Ali Çehreli via Digitalmars-d wrote:On 06/03/2017 12:12 PM, Steven Schveighoffer wrote:[...] In this case, I'd say "this wouldn't be an article about D; it's a language feature." :-D Though I'd say we *could* add meat to the article by explaining what exactly CTFE is, how it works, and why you could just call the standard library sort at compile-time and have it Just Work(tm) without having to jump through hoops. And perhaps demonstrate how easy it is to do this not just with sort, but with far more complex things. In fact, significant chunks of Phobos are now available at CTFE. For example, you can call std.format at compile-time to perform some pretty hairy string formatting and have the result baked into your executable so that you incur none of the cost of computing it at runtime. The best part of all this is, as long as you have already written runtime code that's CTFE-compatible, you don't have to do anything else to make it work at compile-time. No messing around with constexpr, no awkward special syntax, no need to jump through hoops, invoke arcane black magic, etc.. Just call the code with normal runtime syntax from an expression whose value needs to be known at compile-time, and the compiler does the rest of you. And if you need a particular functionality both at compile-time and during runtime, there's no need to write it twice in two different sublanguages. You just write one function once, and call it from both CTFE and at runtime. It Just Works(tm). Then we could add the icing on the cake by showing off one of Andrei's(?) little gems in std.random: a RNG generator that checks *at compile-time* whether a particular set of RNG parameters would produce a poor-quality RNG, and abort with a compile-error if so. Meaning that if the thing compiles at all, you have a minimum quality guarantee. (This particular gem is described in detail in TDPL, btw, and is one of the things about D that blew me away when I first read it.) T -- Valentine's Day: an occasion for florists to reach into the wallets of nominal lovers in dire need of being reminded to profess their hypothetical love for their long-forgotten.I'd say this deserves a blog post but it would be too short.I made many good friends at C++Now. Some of them know Atila from CppCon and other C++ conferences. (Beer involved. :) ) They told me Atila would routinely tell them during C++ presentations "This wouldn't be a talk at a DConf; it's a language feature in D." :)
Jun 03 2017
On Sunday, 4 June 2017 at 05:38:24 UTC, H. S. Teoh wrote:And if you need a particular functionality both at compile-time and during runtime, there's no need to write it twice in two different sublanguages. You just write one function once, and call it from both CTFE and at runtime. It Just Works(tm)....except when you have `if (__ctfe)` :P
Jun 03 2017
On Sun, Jun 04, 2017 at 06:08:28AM +0000, Stanislav Blinov via Digitalmars-d wrote:On Sunday, 4 June 2017 at 05:38:24 UTC, H. S. Teoh wrote:Ah, but if you want your function to work both at CTFE and runtime, then why write `if (__ctfe)` in the first place? :-D Unless, of course, you're optimizing for runtime with something that's incompatible with CTFE, like inline assembly or something. Then you're on your own. :-D T -- People say I'm indecisive, but I'm not sure about that. -- YHL, CONLANGAnd if you need a particular functionality both at compile-time and during runtime, there's no need to write it twice in two different sublanguages. You just write one function once, and call it from both CTFE and at runtime. It Just Works(tm)....except when you have `if (__ctfe)` :P
Jun 03 2017
On 2017-06-04 08:18, H. S. Teoh via Digitalmars-d wrote:Ah, but if you want your function to work both at CTFE and runtime, then why write `if (__ctfe)` in the first place? :-D Unless, of course, you're optimizing for runtime with something that's incompatible with CTFE, like inline assembly or something. Then you're on your own. :-DOr using malloc/free at runtime but the GC at compile time. -- /Jacob Carlborg
Jun 04 2017
On Saturday, June 03, 2017 22:38:24 H. S. Teoh via Digitalmars-d wrote:On Sat, Jun 03, 2017 at 03:00:56PM -0700, Ali Çehreli via Digitalmars-dwrote:Be careful, or Mike will start hounding you to write the actual article. ;) - Jonathan M DavisOn 06/03/2017 12:12 PM, Steven Schveighoffer wrote:[...] In this case, I'd say "this wouldn't be an article about D; it's a language feature." :-D Though I'd say we *could* add meat to the article by explaining what exactly CTFE is, how it works, and why you could just call the standard library sort at compile-time and have it Just Work(tm) without having to jump through hoops. And perhaps demonstrate how easy it is to do this not just with sort, but with far more complex things. In fact, significant chunks of Phobos are now available at CTFE. For example, you can call std.format at compile-time to perform some pretty hairy string formatting and have the result baked into your executable so that you incur none of the cost of computing it at runtime. The best part of all this is, as long as you have already written runtime code that's CTFE-compatible, you don't have to do anything else to make it work at compile-time. No messing around with constexpr, no awkward special syntax, no need to jump through hoops, invoke arcane black magic, etc.. Just call the code with normal runtime syntax from an expression whose value needs to be known at compile-time, and the compiler does the rest of you. And if you need a particular functionality both at compile-time and during runtime, there's no need to write it twice in two different sublanguages. You just write one function once, and call it from both CTFE and at runtime. It Just Works(tm). Then we could add the icing on the cake by showing off one of Andrei's(?) little gems in std.random: a RNG generator that checks *at compile-time* whether a particular set of RNG parameters would produce a poor-quality RNG, and abort with a compile-error if so. Meaning that if the thing compiles at all, you have a minimum quality guarantee. (This particular gem is described in detail in TDPL, btw, and is one of the things about D that blew me away when I first read it.)I'd say this deserves a blog post but it would be too short.I made many good friends at C++Now. Some of them know Atila from CppCon and other C++ conferences. (Beer involved. :) ) They told me Atila would routinely tell them during C++ presentations "This wouldn't be a talk at a DConf; it's a language feature in D." :)
Jun 04 2017
On Sunday, 4 June 2017 at 07:49:36 UTC, Jonathan M Davis wrote:Be careful, or Mike will start hounding you to write the actual article. ;) - Jonathan M DavisIt's already written! And I'm looking for reviewers [1] so I can get it in shape in time to publish Monday. [1] http://forum.dlang.org/post/mosjryaaatmhqcpimmbs forum.dlang.org
Jun 04 2017
On Saturday, 3 June 2017 at 22:00:56 UTC, Ali Çehreli wrote:On 06/03/2017 12:12 PM, Steven Schveighoffer wrote:Beer involved. Conference. And they knew _me_? *Shocked* :P There were two distinct talks at CppCon2017 involving some seriously crazy C++ metaprogramming that I said that about. Very interesting how they made the compiler bend over backwards, very high-level stuff. Then when everyone was leaving the room I couldn't help but think that nobody would even mention those techniques in D, you'd get the job done in 5min. AtilaI'd say this deserves a blog post but it would be too short.I made many good friends at C++Now. Some of them know Atila from CppCon and other C++ conferences. (Beer involved. :) ) They told me Atila would routinely tell them during C++ presentations "This wouldn't be a talk at a DConf; it's a language feature in D." :)
Jun 05 2017
On Sat, 2017-06-03 at 19:12 +0000, Steven Schveighoffer via Digitalmars-d wrote:On Saturday, 3 June 2017 at 17:32:41 UTC, Andrei Alexandrescu=C2=A0 wrote:a. that was my point in making the original post; and b. no it isn't, it is the right length. It would make a great article for Overload. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winderOn 06/03/2017 01:03 PM, Russel Winder via Digitalmars-d wrote:=20 I'd say this deserves a blog post but it would be too short. =20 -SteveBj=C3=B6rn Fahller has done compile time sort in C++17 here=C2=A0 http://playfulpr ogramming.blogspot.co.uk/2017/06/constexpr-quicksort-in-c17.html =20 Surely D can do better?=20 There is nothing to do really. Just use standard library sort. =20 void main() { import std.algorithm, std.stdio; enum a =3D [ 3, 1, 2, 4, 0 ]; static auto b =3D sort(a); writeln(b); }
Jun 04 2017
Could someone clarify why the generated assembly for void main() nogc { import std.algorithm; enum a = [3, 1, 2, 0]; // inferred to be int[] enum b = sort(a); static assert(b[0] == 0); } is 1380 lines with ldc 1.3.0 (-O3 -release -betterC -flto=full)? You can see the result on godbolt here: https://godbolt.org/g/BNRnO9 It's kind of surprising compared to C++'s 2 lines: https://godbolt.org/g/vXrxaY
Jun 04 2017
On 04/06/2017 11:06 AM, Vittorio Romeo wrote:Could someone clarify why the generated assembly for void main() nogc { import std.algorithm; enum a = [3, 1, 2, 0]; // inferred to be int[] enum b = sort(a); static assert(b[0] == 0); } is 1380 lines with ldc 1.3.0 (-O3 -release -betterC -flto=full)? You can see the result on godbolt here: https://godbolt.org/g/BNRnO9 It's kind of surprising compared to C++'s 2 lines: https://godbolt.org/g/vXrxaY_Dmain is exactly 2 instructions, so nope equivalent :) The linker isn't stripping out unused symbols however (from what I can tell).
Jun 04 2017
On Sunday, 4 June 2017 at 10:21:16 UTC, rikki cattermole wrote:On 04/06/2017 11:06 AM, Vittorio Romeo wrote:I see. Is there any argument that can be passed to ldc in order to strip the unused symbols?Could someone clarify why the generated assembly for void main() nogc { import std.algorithm; enum a = [3, 1, 2, 0]; // inferred to be int[] enum b = sort(a); static assert(b[0] == 0); } is 1380 lines with ldc 1.3.0 (-O3 -release -betterC -flto=full)? You can see the result on godbolt here: https://godbolt.org/g/BNRnO9 It's kind of surprising compared to C++'s 2 lines: https://godbolt.org/g/vXrxaY_Dmain is exactly 2 instructions, so nope equivalent :) The linker isn't stripping out unused symbols however (from what I can tell).
Jun 04 2017
On 04/06/2017 11:27 AM, Vittorio Romeo wrote:On Sunday, 4 June 2017 at 10:21:16 UTC, rikki cattermole wrote:Should be a way, since you can pass arg directly via ldc to ld. But I would expect it to have done it by default anyway.On 04/06/2017 11:06 AM, Vittorio Romeo wrote:I see. Is there any argument that can be passed to ldc in order to strip the unused symbols?Could someone clarify why the generated assembly for void main() nogc { import std.algorithm; enum a = [3, 1, 2, 0]; // inferred to be int[] enum b = sort(a); static assert(b[0] == 0); } is 1380 lines with ldc 1.3.0 (-O3 -release -betterC -flto=full)? You can see the result on godbolt here: https://godbolt.org/g/BNRnO9 It's kind of surprising compared to C++'s 2 lines: https://godbolt.org/g/vXrxaY_Dmain is exactly 2 instructions, so nope equivalent :) The linker isn't stripping out unused symbols however (from what I can tell).
Jun 04 2017
On Sunday, 4 June 2017 at 10:39:09 UTC, rikki cattermole wrote:Should be a way, since you can pass arg directly via ldc to ld. But I would expect it to have done it by default anyway.It is indeed done by default on Windows and Linux. If you dump the object code before it gets to the linker, it will still show the unused symbols, though. — David
Jun 04 2017
On Sunday, 4 June 2017 at 10:27:14 UTC, Vittorio Romeo wrote:I see. Is there any argument that can be passed to ldc in order to strip the unused symbols?Doesn't the strip command work?
Jun 04 2017
On Sunday, 4 June 2017 at 14:13:24 UTC, Ola Fosheim Grøstad wrote:On Sunday, 4 June 2017 at 10:27:14 UTC, Vittorio Romeo wrote:Oh wait, you didn't mean symbols, you meant code. LLVM has passes for that: https://blog.quarkslab.com/global-dead-code-elimination-for-llvm-revisited.htmlI see. Is there any argument that can be passed to ldc in order to strip the unused symbols?Doesn't the strip command work?
Jun 04 2017
On Saturday, 3 June 2017 at 19:12:46 UTC, Steven Schveighoffer wrote:I'd say this deserves a blog post but it would be too short.Actually i wouldn't mind a vlog or some short presentations on a variety of subjects. Maybe even continuations of presentations that could have been at the Dlang conference except weren't due to time constraints.
Jun 06 2017
On Tuesday, 6 June 2017 at 08:00:11 UTC, Era Scarecrow wrote:On Saturday, 3 June 2017 at 19:12:46 UTC, Steven Schveighoffer wrote:I could post a video about a simple ctfe transcompiler. or sqlite-d. I have to wait until my computer is fixed though.I'd say this deserves a blog post but it would be too short.Actually i wouldn't mind a vlog or some short presentations on a variety of subjects. Maybe even continuations of presentations that could have been at the Dlang conference except weren't due to time constraints.
Jun 06 2017