Re: Metaprogramming with D
On Sunday, 7 June 2020 at 00:45:37 UTC, Ali Çehreli wrote: False. And again, even if so, that's not because of D, but because of humans. Can you imagine a CTO, say, in Silicon Valley to have guts to bring D instead of C++? With C++, the CTO will never be blamed; but D, he or she can easily be blamed upon failure. Not because of the technologies but because of politics. In other words, "Nobody ever got fired for choosing [C++]."
Re: Metaprogramming with D
On 6/6/20 5:03 PM, FunkyD wrote:> On Saturday, 6 June 2020 at 09:57:36 UTC, Jan Hönig wrote: > D is pretty good for meta-programming. For certain other things it is > terrible. I am glad I don't know enough about other technologies to feel that way. > String mixins simply mix in D code. It lets you build generic D code. > The big problem here is debugging. There is ZERO ability to properly > debug string mixins. "Zero" is too strong an assertion and because of the following, false: dmd -mixin= ... > Well, what it boils down to is writing out the > string mixin and then debugging that. When I compile my program and there is an issue with a string mixin, Emacs opens the mixin file and shows me the compilation there. This is because dmd's error include the exact line in the where my mixin was broken. Not a shiny IDE but still pretty awesome support. > It would be nice if D had a special D code string that the IDE could > interpret properly. I must be misunderstanding you but it must be an IDE limitation because of the following: writeln(q{ void foo() { } }); My IDE gives me syntax highlighting in that string, so it works somehow. > D basically tries to resolve things after the fact so > > R add(T)(T a, T b) > { > return a + b; > } > > this will attempt to + on a and b after the types are known. If they > can't be added then an error will occur, which is usually cryptic for > templates. That's why we use template constraints and in some cases 'static assert' for custom error messages. > The issue in using D should not be made based on it's metaprogramming. I agree. What feature to use usually emerges by itself. For example, when an algorithm is repeated for many types, it is an opportunity for templates. > D, IMO, is not capable of writing sophisticated programs... "Sophisticated" is relative but such strong assertions can be falsified by a single counterexample. For example, Weka's product is very sophisticated and is written in D. And there is nothing extra or missing in D that makes it incapable in that regard. > this is why > you do not see any. I think the fact that many smart programmers are hostage to other languages is a stronger reason. > No one writes large commercial apps in D. False. > There is > not one! False. And again, even if so, that's not because of D, but because of humans. Can you imagine a CTO, say, in Silicon Valley to have guts to bring D instead of C++? With C++, the CTO will never be blamed; but D, he or she can easily be blamed upon failure. Not because of the technologies but because of politics. > The D ecosystems is poorly structured compared to the top > contenders. Agreed but that is not because D is inferior. Again, that's because people happen to be busy with other technologies. > D is good for small apps, utilities, etc. D can be > integrated with other apps though but then one loses some of the meta > capabilities(since they won't translate). What would one technology that is good for small code not work for a larger system? Threads, communication e.g. memory mapped files, etc. are all there. What magical thing would happen and suddenly D won't work beyond a certain limit? If so, is that any different from any other language? Ali
Re: Metaprogramming with D
On Saturday, 6 June 2020 at 09:57:36 UTC, Jan Hönig wrote: We have two (little) student projects, which should use D for meta-programming/code generation. More specifically string mixins and templates. I understand (at least I think so :)) string mixins. The task is to create a small internal DSL, which is capable of printing out D code, which we then will use as a mixin. So basically using CTFE to create code at compile time. (any additional sources/ideas are welcome). The second project considers templates. My idea was to recreate some template expressions, like we all know and love (hate) in C++. However I am not so sure if that is a really good idea. As far as I understood it, that is basically what ranges in D do. So this would just mean "code linear algebra with ranges", which I am sure plenty of D's libraries do already (mir?). (that doesn't mean, it is not a good learning experience for the student). I would love to hear some opinions on that matter. D is pretty good for meta-programming. For certain other things it is terrible. One of the key features of D is it's meta programming. String mixins simply mix in D code. It lets you build generic D code. The big problem here is debugging. There is ZERO ability to properly debug string mixins. Well, what it boils down to is writing out the string mixin and then debugging that. Visual D does have the ability to open up the output and one can try to compile such things but it can be a pain for complex cases. It would be nice if D had a special D code string that the IDE could interpret properly. Templates are just templates, just generic code. D is far better than C++ and most other languages. Template are more than ranges. Ranges use templates. Templated code simply means generic code. E.g., rather than working with specific integers you work with integer variables. Generally the type of the variable is undefined it constrained but otherwise unknown. R foo(T)(T a) R and T are types. We can call foo with any type, it no longer requires overloading and all that. But if the code in foo depends on specific types then it must be dealt with using various means to constrain the type. D basically tries to resolve things after the fact so R add(T)(T a, T b) { return a + b; } this will attempt to + on a and b after the types are known. If they can't be added then an error will occur, which is usually cryptic for templates. When using templates one generally also cannot debug them as easy. One might get a long error message for simple issues. R above is deduced from type of a + b, which probably would be a T. So such a simple templated function, or generic function can be used to add doubles, ints, floats, etc... anything with + operator. Further more there are more tools available such as passing compile time parameters and such. One can do quite a lot with D's string mixins and templates but the biggest issue is error messages and debugging. Sometimes things are not so easy to do with templates or require strange workarounds, but otherwise probably 98% of all things can be done. When one is working with generic types one has to learn more machinery such as `is`, traits, etc. The issue in using D should not be made based on it's metaprogramming. It will be a mistake! Now, if the only goal is to use D for it's metaprogramming then it is an excellent choice... although there are other languages starting to compete with D and functional languages probably offer better overall cohesiveness if you want to go down the functional route(ultimately there is little difference but the syntax and some of the semantics seem vastly different). D, IMO, is not capable of writing sophisticated programs... this is why you do not see any. No one writes large commercial apps in D. There is not one! The D ecosystems is poorly structured compared to the top contenders. D is good for small apps, utilities, etc. D can be integrated with other apps though but then one loses some of the meta capabilities(since they won't translate).
Re: Metaprogramming with D
On Saturday, 6 June 2020 at 09:57:36 UTC, Jan Hönig wrote: We have two (little) student projects, which should use D for meta-programming/code generation. More specifically string mixins and templates. I found this doc: https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/D-templates-tutorial.md Really, we should put all these docs in a central place.
Re: Use classes as keys in associative array
On Saturday, 6 June 2020 at 20:31:36 UTC, ikod wrote: On Saturday, 6 June 2020 at 16:49:29 UTC, JN wrote: Is it possible to use different class instances as keys for associative array, but compare them by the contents? I tried to override opEquals but it doesn't seem to work. Basically I'd May be wrong, but probably you have to override opEquals to Object, not to another class instance. Oops, sorry, it was answered already
Re: Use classes as keys in associative array
On Saturday, 6 June 2020 at 16:49:29 UTC, JN wrote: Is it possible to use different class instances as keys for associative array, but compare them by the contents? I tried to override opEquals but it doesn't seem to work. Basically I'd May be wrong, but probably you have to override opEquals to Object, not to another class instance.
Re: Use classes as keys in associative array
On Saturday, 6 June 2020 at 16:49:29 UTC, JN wrote: Is it possible to use different class instances as keys for associative array, but compare them by the contents? I tried to override opEquals but it doesn't seem to work. You also need toHash. https://dlang.org/spec/hash-map.html#using_classes_as_key
Use classes as keys in associative array
Is it possible to use different class instances as keys for associative array, but compare them by the contents? I tried to override opEquals but it doesn't seem to work. Basically I'd like this code to work. I know structs would work but I can't use structs for this): import std.stdio; class Name { string s; this(string s) { this.s = s; } } void main() { Name n1 = new Name("John"); Name n2 = new Name("John"); int[Name] ages; ages[n1] = 50; assert(ages[n2] == 50); }
Re: How to port C++ std::is_reference to D ?
On Wednesday, 13 May 2020 at 13:36:14 UTC, wjoe wrote: On Monday, 11 May 2020 at 19:08:09 UTC, Q. Schroll wrote: [...] 1. You can have variables ("data members") of reference type in structs. (They work like head-const pointers; if D had head-const or at least head-const pointers, those would be practically the same, only that references cannot be null.) [...] That's also something I don't really know how to correctly port to D. Anyways, that was insightful. Thank you very much for your explanations. Another thing that just occurred to me is generating types. Say I have an AliasSeq of types. I want to generate a list of delegates taking all of them with all combinations of `ref`ness. Example: alias list = AliasSeq!(int, char, double); I want the AliasSeq alias delegates = AliasSeq!( R delegate(int, char, double), R delegate(ref int, char, double), R delegate(int, ref char, double), R delegate(int, char, ref double), R delegate(ref int, ref char, double), ..., R delegate(ref int, ref char, ref double) ); That would be way easier if `ref` were part of the type (like const/immutable/inout/shared are).
Re: Should it compile?
On Saturday, 6 June 2020 at 12:54:38 UTC, Stanislav Blinov wrote: The moveEmpalce should compile... But not when the *first* argument is const though, like in the example. For *that*, one would have to insert an additional cast.
Re: Should it compile?
On Saturday, 6 June 2020 at 11:58:06 UTC, Basile B. wrote: On Saturday, 6 June 2020 at 08:55:20 UTC, Jack Applegame wrote: Should it compile? I think, it should. maybe it shouldn't but then with another message, for example Error, cannot `void` initialize a `const` declaration. since that makes very little sense, at least as a local variable. (as a member, this can be initialized in a constructor) The moveEmpalce should compile, just like this does: import std.conv : emplace; emplace(&a, 'a'); But, in the case of emplacing into a const, either should be @system (moveEmplace is always @system, but `emplace` for this case is not at the moment). One could do a emplace(&a, move(b)) but that's more moves (and I believe current emplace even would insert a spurious copy there). This is what we get for delegating emplacement and moves into a library instead of having appropriate intrinsics.
Re: Should it compile?
On Saturday, 6 June 2020 at 08:55:20 UTC, Jack Applegame wrote: Should it compile? No, moveEmplace just sees a const reference and doesn't know that a is void-initialized.
Re: Should it compile?
On Saturday, 6 June 2020 at 08:55:20 UTC, Jack Applegame wrote: Should it compile? ```d import std.algorithm.mutation; void main() { const char a = void; const char b ='b'; moveEmplace(b, a); // mutation.d: Error: cannot modify const expression target assert(a == 'b'); } ``` I think, it should. maybe it shouldn't but then with another message, for example Error, cannot `void` initialize a `const` declaration. since that makes very little sense, at least as a local variable. (as a member, this can be initialized in a constructor)
Re: How debugg unittest with visual code + code-d
On Saturday, 6 June 2020 at 08:42:22 UTC, WebFreak001 wrote: On Saturday, 6 June 2020 at 08:06:02 UTC, Luis wrote: On Friday, 5 June 2020 at 18:13:52 UTC, WebFreak001 wrote: [...] It isn't working correctly on my case : I get this error : Performing "unittest" build using dmd for x86_64. ddiv ~sparseSet: building configuration "unittest"... ../../../.dub/packages/silly-1.0.2/silly/silly.d(15,2): Error: static assert: "Couldn't find 'dub_test_root'. Make sure you are running tests with dub test" dmd failed with exit code 1. The terminal process terminated with exit code: 2 And this works fine if I run a dub test from console. You can change it to { "label": "dub build", // <-- add a good name here "type": "dub", "test": true, "problemMatcher": [ "$dmd" ], "group": "build" } but it will run the unittests then too (not just build them), which will increase the task running time It works! Now, I would try these "natvis"
Metaprogramming with D
We have two (little) student projects, which should use D for meta-programming/code generation. More specifically string mixins and templates. I understand (at least I think so :)) string mixins. The task is to create a small internal DSL, which is capable of printing out D code, which we then will use as a mixin. So basically using CTFE to create code at compile time. (any additional sources/ideas are welcome). The second project considers templates. My idea was to recreate some template expressions, like we all know and love (hate) in C++. However I am not so sure if that is a really good idea. As far as I understood it, that is basically what ranges in D do. So this would just mean "code linear algebra with ranges", which I am sure plenty of D's libraries do already (mir?). (that doesn't mean, it is not a good learning experience for the student). I would love to hear some opinions on that matter.
Should it compile?
Should it compile? ```d import std.algorithm.mutation; void main() { const char a = void; const char b ='b'; moveEmplace(b, a); // mutation.d: Error: cannot modify const expression target assert(a == 'b'); } ``` I think, it should.
Re: How debugg unittest with visual code + code-d
On Saturday, 6 June 2020 at 08:06:02 UTC, Luis wrote: On Friday, 5 June 2020 at 18:13:52 UTC, WebFreak001 wrote: [...] It isn't working correctly on my case : I get this error : Performing "unittest" build using dmd for x86_64. ddiv ~sparseSet: building configuration "unittest"... ../../../.dub/packages/silly-1.0.2/silly/silly.d(15,2): Error: static assert: "Couldn't find 'dub_test_root'. Make sure you are running tests with dub test" dmd failed with exit code 1. The terminal process terminated with exit code: 2 And this works fine if I run a dub test from console. You can change it to { "label": "dub build", // <-- add a good name here "type": "dub", "test": true, "problemMatcher": [ "$dmd" ], "group": "build" } but it will run the unittests then too (not just build them), which will increase the task running time
Re: How debugg unittest with visual code + code-d
On Saturday, 6 June 2020 at 08:06:02 UTC, Luis wrote: On Friday, 5 June 2020 at 18:13:52 UTC, WebFreak001 wrote: To build before running the debugger, add the following task to your task definitions file (Ctrl-Shift-B): { "label": "dub build", // <-- add a good name here "type": "dub", "run": false, "buildType": "unittest", // <-- this makes it build the unittests "problemMatcher": [ "$dmd" ], "group": "build" } It isn't working correctly on my case : I get this error : Performing "unittest" build using dmd for x86_64. ddiv ~sparseSet: building configuration "unittest"... ../../../.dub/packages/silly-1.0.2/silly/silly.d(15,2): Error: static assert: "Couldn't find 'dub_test_root'. Make sure you are running tests with dub test" dmd failed with exit code 1. The terminal process terminated with exit code: 2 And this works fine if I run a dub test from console. In my case, I just execute dub test from VSC terminal, use the auto generated debugger configuration and just set the unittest executable path. This works fine on linux (WSL). Kind regards Andre
Re: How debugg unittest with visual code + code-d
On Friday, 5 June 2020 at 18:13:52 UTC, WebFreak001 wrote: To build before running the debugger, add the following task to your task definitions file (Ctrl-Shift-B): { "label": "dub build", // <-- add a good name here "type": "dub", "run": false, "buildType": "unittest", // <-- this makes it build the unittests "problemMatcher": [ "$dmd" ], "group": "build" } It isn't working correctly on my case : I get this error : Performing "unittest" build using dmd for x86_64. ddiv ~sparseSet: building configuration "unittest"... ../../../.dub/packages/silly-1.0.2/silly/silly.d(15,2): Error: static assert: "Couldn't find 'dub_test_root'. Make sure you are running tests with dub test" dmd failed with exit code 1. The terminal process terminated with exit code: 2 And this works fine if I run a dub test from console.