Re: Remember the Vasa! by Bjarne Stroustrup
On Tuesday, 29 May 2018 at 05:11:27 UTC, Dmitry Olshansky wrote: D is probably at the edge of what I can tollerate complexity-wise. And we’ll get to simplify a few things soon I believe. There is the core of the problem. Because you want to understand it all, therefore it must be simplified. This is not something that nature imposes on itself. It's entirely a product of the human mind. Why constrain ourselves in this way? Let it go, and let it grow ;-)
Re: Remember the Vasa! by Bjarne Stroustrup
On Tuesday, 29 May 2018 at 03:56:05 UTC, Dmitry Olshansky wrote: It seems C++ is following the road of PL/I, which is growing language way beyond the point anyone can understand or implement all of it. A key line from this paper We now have about 150 cooks; that’s not a good way to get a tasty and balanced meal. I don't think Bjarne is against adding feature to C++, or even constantly adding feature he even admits to support some of the features he mention in his list I think he is worried about 1. the huge number of features being targeted at once 2. the features coming from different independent teams, making them less likely to be coherent This is very different from "lets not grow C++ ever" D need to add features constantly, but coherently, D is very far from having 150 cooks I wish D had that many cooks :)
Re: Remember the Vasa! by Bjarne Stroustrup
On Tuesday, 29 May 2018 at 04:41:33 UTC, Komplex wrote: On Tuesday, 29 May 2018 at 03:56:05 UTC, Dmitry Olshansky wrote: It seems C++ is following the road of PL/I, which is growing language way beyond the point anyone can understand or implement all of it. but that happened to the linux kernel too, long ago? Not really. First - Linux (for the scale) is architectured wuite well. Second - language are way more composable and complex beasts then systems. I bet I can understand most of Linux kernel in a couple of years (w/o drivers and arch specifics beyond x86). Abstraction and components/interfaces is time-proven technique that actually works for the most part. In contradt I will likely never understand or have a good picture of C++20 as a (semi-)coherent whole, not that I really wanted to. D is probably at the edge of what I can tollerate complexity-wise. And we’ll get to simplify a few things soon I believe. and yet...it's everywhere..and increasingly so... It has evolved a lot. Yet I believe we can get better things done w/o years upon years of churn. But that’s just a point of view. we need to move away from this concept that we need to understand it all, or otherwise.. it must be bad.
Re: Remember the Vasa! by Bjarne Stroustrup
On Tuesday, May 29, 2018 03:43:00 TheMightWarship via Digitalmars-d wrote: > On Tuesday, 29 May 2018 at 01:46:47 UTC, Walter Bright wrote: > > A cautionary tale we should all keep in mind. > > > > http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0977r0.pdf > > > > https://www.reddit.com/r/programming/comments/8mq10v/bjarne_stroustroup_ > > remeber_the_vasa_critique_of/ > > > > https://news.ycombinator.com/item?id=17172057 > > Bjarne opens with: "Many/most people in WG21 are working > independently towards non-shared goals." > > I presume, this is essentially a criticism?? > > If so, I reject that as criticism. There has to be room for > allowing people to puruse their individual goals too, and a > programming langauge should allow that as well. I don't think that it's really a criticism of folks having individual goals. The overall criticism seems to be that while those involved may have varying goals, the resulting language needs to be reasonably coherent and usable by the lay programmer. So, ultimately, when new language features are introduced, you need to examine how they fit in with everything else (both what's already in the language and what's being proposed) and potentially adjust what's being proposed to make it all fit together better. Right now, they're getting a bunch of indpendent proposals that don't take each other into account at all, and it sounds like a lot of them aren't even talking about how this will help or hurt the average C++ programmer. It's more like they're just trying to get their pet feature into the language. So, Stroustrup thinks that they should be trying to make everything fit together better and aim it at how it affects the average C++ programmer who's just trying to get their job done rather than trying to get every stray thing into the language that seems like it would be valuable. He even talks about how the Vasa could have succeeded if a bit more work had been put into making sure how all of the adjustments to the vessel worked together. It didn't need to give up on everything that was done to improve it. Rather, it needed to be more coherent in its parts. C++ is suffering from a major case of being designed by committee. - Jonathan M Davis
Re: Why 'getSymbolsByUDA' filters private members?
On Tuesday, 29 May 2018 at 02:46:03 UTC, Jonathan M Davis wrote: On Monday, May 28, 2018 05:43:23 Simen Kjærås via Digitalmars-d-learn wrote: On Sunday, 27 May 2018 at 17:42:15 UTC, Sobaya wrote: > I'd like to get symbols that have an UDA. > > But when the member is private, it is not obtained. > > And I found a comment saying "Filtering inaccessible > members" in the source. > > Why is it necessary to filter out private members? Since the members are private, they're not visible to code in other modules. getSymbolsByUDA is in std.traits, which is another module, so code in it can't interact with the private members. There is definitely an argument to be made for allowing reflection access to private members from other modules, but the buck has to stop somewhere, and this is a complex problem. If 'private' is to respected at all, clearly we can't have a different module call our private methods, or read our private fields. That means something as simple as a wrapper around a function can't work. The symbols are visible. They're just not accessible. As I understand it, it's already been agreed that it should be possible to look at them with introspection and get stuff like UDAs from them. It's just that the implementation hasn't caught up yet. So, right now, if you try to introspect on a private symbol in another module (even if you don't try to actually use it for anything), you get a compiler error, and that really does need to be fixed. Actually using any such symbols should continue to be illegal though. getSymbolsByUDA is an area where there's been a lot of discussion on this, because it keeps biting folks. - Jonathan M Davis The idea [1] was rather to remove the protection when using __traits(allMembers|getMembers|...) and let people decide if they follow the language rules or not using __traits(getProtection,...) in their reflection code. Problem is that the current way it works can lead to unfair situations where self- introspection fails because the helper template used to make the introspection is located in another module. On the other hand if you copy the helper template where it has to be used, the errors disappear. [1] https://github.com/dlang/DIPs/pull/39
Re: using wkhtmltopdf with D
On Tuesday, 29 May 2018 at 04:49:34 UTC, Nicholas Wilson wrote: On Tuesday, 29 May 2018 at 01:43:17 UTC, Mike Parker wrote: In pdf.h, that CAPI macro is used in every function declaration. That means that on Windows, all of the functions have the __stdcall calling convention (which, in D, would be extern(Windows)) and the standard cdecl calling convetion on other platforms (extern(C) in D). In the D binding, we see that all of the functions are declared as extern(C) (line 4 of pdf.d). That means on Windows, the calling convention on the D side is incorrect. What you need to do is to change that extern(C) delcaration in pdf.d to extern(System). This will translate to extern(Windows) on Windows and extern(C) elsewhere to match the C headers. this is represented by extern(System) in D which does the conditional extern(C) vs extern(Windows) for you. Apparently I can't read.
Re: using wkhtmltopdf with D
On Tuesday, 29 May 2018 at 01:43:17 UTC, Mike Parker wrote: In pdf.h, that CAPI macro is used in every function declaration. That means that on Windows, all of the functions have the __stdcall calling convention (which, in D, would be extern(Windows)) and the standard cdecl calling convetion on other platforms (extern(C) in D). In the D binding, we see that all of the functions are declared as extern(C) (line 4 of pdf.d). That means on Windows, the calling convention on the D side is incorrect. What you need to do is to change that extern(C) delcaration in pdf.d to extern(System). This will translate to extern(Windows) on Windows and extern(C) elsewhere to match the C headers. this is represented by extern(System) in D which does the conditional extern(C) vs extern(Windows) for you.
Re: Remember the Vasa! by Bjarne Stroustrup
On Tuesday, 29 May 2018 at 03:56:05 UTC, Dmitry Olshansky wrote: It seems C++ is following the road of PL/I, which is growing language way beyond the point anyone can understand or implement all of it. but that happened to the linux kernel too, long ago? and yet...it's everywhere..and increasingly so... we need to move away from this concept that we need to understand it all, or otherwise.. it must be bad.
Re: Remember the Vasa! by Bjarne Stroustrup
On Tuesday, 29 May 2018 at 03:56:05 UTC, Dmitry Olshansky wrote: On Tuesday, 29 May 2018 at 01:46:47 UTC, Walter Bright wrote: A cautionary tale we should all keep in mind. http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0977r0.pdf https://www.reddit.com/r/programming/comments/8mq10v/bjarne_stroustroup_remeber_the_vasa_critique_of/ https://news.ycombinator.com/item?id=17172057 It seems C++ is following the road of PL/I, which is growing language way beyond the point anyone can understand or implement all of it. This is ultimately a matter of 'architecture', rather than being a problem of a 'growing langauge'. A good architecture could allow growth/complexity to arise in a manageable way. When you have languages that are so low level, you simply cannot create good architecture, beyone a certain point (either from the users point of view, or the implementers). What we need, is better architecture in langauge design. This, ultimately, means we need to move away from the von Neumann machine, because that is really what's holding us back, from developing good architecture (for managing the inevitable complexity that arises from change). Nature shows us the way - we just don't bother to look.
Re: Remember the Vasa! by Bjarne Stroustrup
On Tuesday, 29 May 2018 at 01:46:47 UTC, Walter Bright wrote: A cautionary tale we should all keep in mind. http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0977r0.pdf https://www.reddit.com/r/programming/comments/8mq10v/bjarne_stroustroup_remeber_the_vasa_critique_of/ https://news.ycombinator.com/item?id=17172057 It seems C++ is following the road of PL/I, which is growing language way beyond the point anyone can understand or implement all of it.
[Issue 18905] [Reg 2.079] C++ classes can no longer be used with -betterC
https://issues.dlang.org/show_bug.cgi?id=18905 --- Comment #3 from Walter Bright --- https://github.com/dlang/dmd/pull/8304 --
Re: Remember the Vasa! by Bjarne Stroustrup
On Tuesday, 29 May 2018 at 01:46:47 UTC, Walter Bright wrote: A cautionary tale we should all keep in mind. http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0977r0.pdf https://www.reddit.com/r/programming/comments/8mq10v/bjarne_stroustroup_remeber_the_vasa_critique_of/ https://news.ycombinator.com/item?id=17172057 Bjarne opens with: "Many/most people in WG21 are working independently towards non-shared goals." I presume, this is essentially a criticism?? If so, I reject that as criticism. There has to be room for allowing people to puruse their individual goals too, and a programming langauge should allow that as well. The idea that less is more? Well, take a look at golang. Less means less, not more. When I go out to do a job, a take only those tools I'll need for the job. I'm not expected to take every tool ever created, and know how to use each of those tools. I take, and use, the tools I need for that particular job. A programming langauge should not restrict the availability of tools, unless is want to be the tool for a particular job. New features, that people want, are essentially 'tools' that they want. (and typically, tools they already have in one or more other langauges). Lets not contain complexity, by preventing it from every occurring - otherwise, nothing would exist.
Re: Why 'getSymbolsByUDA' filters private members?
On Monday, May 28, 2018 05:43:23 Simen Kjærås via Digitalmars-d-learn wrote: > On Sunday, 27 May 2018 at 17:42:15 UTC, Sobaya wrote: > > I'd like to get symbols that have an UDA. > > > > But when the member is private, it is not obtained. > > > > And I found a comment saying "Filtering inaccessible members" > > in the source. > > > > Why is it necessary to filter out private members? > > Since the members are private, they're not visible to code in > other modules. getSymbolsByUDA is in std.traits, which is another > module, so code in it can't interact with the private members. > > There is definitely an argument to be made for allowing > reflection access to private members from other modules, but the > buck has to stop somewhere, and this is a complex problem. If > 'private' is to respected at all, clearly we can't have a > different module call our private methods, or read our private > fields. That means something as simple as a wrapper around a > function can't work. The symbols are visible. They're just not accessible. As I understand it, it's already been agreed that it should be possible to look at them with introspection and get stuff like UDAs from them. It's just that the implementation hasn't caught up yet. So, right now, if you try to introspect on a private symbol in another module (even if you don't try to actually use it for anything), you get a compiler error, and that really does need to be fixed. Actually using any such symbols should continue to be illegal though. getSymbolsByUDA is an area where there's been a lot of discussion on this, because it keeps biting folks. - Jonathan M Davis
Re: Remember the Vasa! by Bjarne Stroustrup
On 5/28/2018 6:54 PM, 12345swordy wrote: No doubt that all this complexity is partially due to having a religious like zeal when it comes to preserving backwards compatibility. I mean create a new official file extension, so that it can make much needed breaking changes on it. For all the faults that D has, it is not afraid deprecate language features if it turns out to be a really bad idea. If I was going to make a proposal to the C++ Standards committee, it would be to deprecate the preprocessor. D has by now shown that all of it that matters can be done with language features in a straightforward, hygienic manner. Here's the D subthread: https://www.reddit.com/r/programming/comments/8mq10v/bjarne_stroustroup_remeber_the_vasa_critique_of/dzpwz76/
Re: Remember the Vasa! by Bjarne Stroustrup
On Tuesday, 29 May 2018 at 01:46:47 UTC, Walter Bright wrote: A cautionary tale we should all keep in mind. http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0977r0.pdf https://www.reddit.com/r/programming/comments/8mq10v/bjarne_stroustroup_remeber_the_vasa_critique_of/ https://news.ycombinator.com/item?id=17172057 No doubt that all this complexity is partially due to having a religious like zeal when it comes to preserving backwards compatibility. I mean create a new official file extension, so that it can make much needed breaking changes on it. For all the faults that D has, it is not afraid deprecate language features if it turns out to be a really bad idea.
Remember the Vasa! by Bjarne Stroustrup
A cautionary tale we should all keep in mind. http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p0977r0.pdf https://www.reddit.com/r/programming/comments/8mq10v/bjarne_stroustroup_remeber_the_vasa_critique_of/ https://news.ycombinator.com/item?id=17172057
Re: using wkhtmltopdf with D
On Monday, 28 May 2018 at 21:05:00 UTC, Dr.No wrote: On Monday, 28 May 2018 at 02:10:48 UTC, sarn wrote: On Monday, 28 May 2018 at 01:28:10 UTC, Dr.No wrote: What's likely the reason of the crash? mismatch between D and C memory alignment? From an ABI point of view, the raw pointers won't care about the memory structure they point to. The function call is the only thing that depends on the binary interface. If you translate the code into C, does it work? Yep, the C version work just fine. This sort of issue is most often caused by a mistake in the bindings: incorrect calling convention, wrong parameter/return types, incorrect number of parameters, etc. In this case, if we look in pdf.h we can see it includes "dllbegin.inc'. There, you'll find the following: #if defined _WIN32 #define CALLTYPE __stdcall #else #define CALLTYPE #endif #ifdef __cplusplus #define CAPI(type) extern "C" DLL_PUBLIC type CALLTYPE #else #define CAPI(type) DLL_PUBLIC type CALLTYPE #endif https://github.com/clowder/wkhtmltopdf/blob/master/src/lib/dllbegin.inc#L43 In pdf.h, that CAPI macro is used in every function declaration. That means that on Windows, all of the functions have the __stdcall calling convention (which, in D, would be extern(Windows)) and the standard cdecl calling convetion on other platforms (extern(C) in D). In the D binding, we see that all of the functions are declared as extern(C) (line 4 of pdf.d). That means on Windows, the calling convention on the D side is incorrect. What you need to do is to change that extern(C) delcaration in pdf.d to extern(System). This will translate to extern(Windows) on Windows and extern(C) elsewhere to match the C headers.
Re: Conditionally set nothrow: for a block of code.
On Thursday, 24 May 2018 at 18:51:31 UTC, Mike Franklin wrote: I'm trying to find a way to declare a block of code `nothrow:` when compiling with -betterC, but not `nothrow` when not compiling with -betterC. The solution is needed for this PR: https://github.com/dlang/druntime/pull/2184/files#r188627707 Walter came up with a solution to this; put the code that is conditionally `nothrow` in a template and mix it in in the appropriate branch. void test() { } mixin template code() { extern(C) void main() { test(); // This should throw an error in -betterC because `main` is // `nothrow` but `test` isn't. It doesn't work } } version(D_BetterC) { nothrow: mixin code; } else { mixin code; } Thanks, Walter. Mike
Re: What is special about an immutable array of class objects, and why can I not .dup ?
On 5/28/18 9:51 AM, James Blachly wrote: Why are the class objects special in this case, and why does `immutable(C)[]` not help? I believed that this defined a dynamic array `c` which was itself mutable, the elements of which were immutable. To build on what others have said, the key thing you are missing is that every instance of C is a *reference*. So you essentially have an array of pointers. If you dup the array, you are not duplicating the class instances, each element of the array still points at the same instances! So naturally, you can't have both a mutable and immutable reference to the same instance. This is easily demonstrated: auto c = [new C(), new C()]; c[0].x = 5; auto c2 = c.dup; c2[0].x = 6; writeln(c[0].x); // 6 Contrast that with the struct and int arrays, where the *entire contents* are copied. Hope that helps. -Steve
Re: SecureD Futures (v2.0)
On Monday, 28 May 2018 at 07:52:43 UTC, Adam Wilson wrote: I understand that. Sorry, not for nothing, but you obviously don't. For starters, if you were familiar with the key derivation tools available 24hrs ago, you wouldn't have come up with PBKDF2 on PBKDF2. I suggest slowing down a little, and asking people on a crypto forum if you're still not sure. If you explain your problem from the start, they might even have some better ideas. When that RFC (correctly) recommends using a salt, it's talking about HKDF-Extract, which is a tool for taking a large amount of mostly-random data and turning it into an appropriate KDK. That's not the problem you have here. The problem you have is generating keys for different purposes from a KDK. That's a problem HKDF-Expand addresses, and it doesn't use a salt. Let me ask the question a different way. What is the reason NOT to use 2 different salts for the MAC and KEY generation steps? You might choose to not use extra salts for the same reason you've already chosen to not encrypt three times, or add extra HMACs for each individual block of ciphertext: it's not solving any problems.
[Issue 18871] DMD "illegal hardware instruction" crash
https://issues.dlang.org/show_bug.cgi?id=18871 Mike Franklin changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #7 from Mike Franklin --- (In reply to Walter Bright from comment #6) > (In reply to Mike Franklin from comment #2) > > Attempted fix: https://github.com/dlang/dmd/pull/8260 > > This was pulled. Does it fix it? Yes, it appears to fix error. --
[Issue 18871] DMD "illegal hardware instruction" crash
https://issues.dlang.org/show_bug.cgi?id=18871 Walter Bright changed: What|Removed |Added CC||bugzi...@digitalmars.com --- Comment #6 from Walter Bright --- (In reply to Mike Franklin from comment #2) > Attempted fix: https://github.com/dlang/dmd/pull/8260 This was pulled. Does it fix it? --
[Issue 18880] [REG2.079] Miscompilation of unittests when two are mixed-in on one line
https://issues.dlang.org/show_bug.cgi?id=18880 Walter Bright changed: What|Removed |Added CC||bugzi...@digitalmars.com --- Comment #4 from Walter Bright --- (In reply to johanengelen from comment #3) > https://github.com/dlang/dmd/pull/8255 This was merged. Does it fix the issue? --
Re: D's Destructors are What Scott Meyers Warned Us About
On Monday, 28 May 2018 at 22:37:01 UTC, sarn wrote: On Monday, 28 May 2018 at 20:13:47 UTC, 12345swordy wrote: [...] Code using destroy() can still use destroy(). Otherwise, __vdtor would be callable in the same way that __dtor and __xdtor are. [...] Interesting... You don't mind me asking your assistance on writing DIP on this? I have one set up already, and I needed help as 1.) This is my first time writing a DIP 2.) I don't know what main course of action to take regarding this issue.
Re: How do I break from loop when using parallel()?
On Monday, 28 May 2018 at 21:04:21 UTC, Dr.No wrote: import std.parallelism : parallel; foreach(t; parallel(arr)) { if(!doSomething(t)) { return false; } } It reuturns the run time error: std.parallelism.ParallelForeachError@(0): Cannot break from a parallel foreach loop using break, return, labeled break/continue or goto statements. What's the proper way to break from loop? By the time you try to break out of the loop, you've already executed the loop body for later elements in the collection. So if you could do that, it would give the wrong impression. The loop body executes on several threads at once. The `return false` statement might be executing on a different thread, and `return` only returns on the same thread. If you want to do this sort of thing (exit on first error, for instance), you can manually use TaskPool, schedule tasks on it, and use an atomic variable to exit early on each task if necessary.
Re: How do I break from loop when using parallel()?
On Monday, 28 May 2018 at 21:04:21 UTC, Dr.No wrote: import std.parallelism : parallel; foreach(t; parallel(arr)) { if(!doSomething(t)) { return false; } } It reuturns the run time error: std.parallelism.ParallelForeachError@(0): Cannot break from a parallel foreach loop using break, return, labeled break/continue or goto statements. What's the proper way to break from loop? you can't break out because other tasks would still continue to finish while the loop is breaking. So either you could use `throw` to error out or you could simply create a `bool isDone;` and at the start of the loop do `if (isDone) continue;` to make all next tasks finish quickly (though CPU usage will be very high for a moment, depending on the list size) If you want total control and break manually (with an uncertainty of a few iterations) you can probably create a custom taskPool and use the .stop member function on it. See https://dlang.org/phobos/std_parallelism.html
Re: D's Destructors are What Scott Meyers Warned Us About
On Monday, 28 May 2018 at 20:13:47 UTC, 12345swordy wrote: How is __vdtor is going to be called, via destroy or via directly? Code using destroy() can still use destroy(). Otherwise, __vdtor would be callable in the same way that __dtor and __xdtor are. The plan is to have a better, safer, less problematic (with attributes) solution to what __dtor and __xdtor do with classes, so that longer term we can deprecate and remove the old way. The issue that I see that your going to create a "BaseObject" for every attribute or combination of said attributes. Which creates way too much code bloat. Even more so with the possibility of adding more attributes in the future. So, I won't say the problem doesn't exist, but it's nowhere near as bad as that. The idea isn't to have a BaseObject for every possible combination of attributes. The BaseObject UDA is just a solution to the problem destructors have with inheritance+attributes. Once you have a base class marked BaseObject, you can derive from it and add whatever combination of attributes you like. The BaseObject-marked class can have as much functionality as needed, except it can't have a non-trivial destructor. That's okay for the immediate problems of implementing ProtoObject and __vdtor, and making safe containers, and improving C++ interop and -betterC code. If needed in future, destructor support could be added in the existing language by exploiting attribute inference, but maybe by that time it would be better to make language changes and turn BaseObject into a no-op. It doesn't matter. I just think it's better to have a viable migration plan that doesn't start with "let's make all these language changes first".
[Issue 18884] getSymbolsByUDA fails on AliasSeq members
https://issues.dlang.org/show_bug.cgi?id=18884 Walter Bright changed: What|Removed |Added CC||bugzi...@digitalmars.com --- Comment #2 from Walter Bright --- (In reply to Simen Kjaeraas from comment #1) > PR: > https://github.com/dlang/phobos/pull/6518 This has been pulled. Has this issue been resolved? --
Re: Build interface from abstract class
this might help you, https://dpaste.dzfl.pl/2cf844a11e3f you can use them to generate the functions as strings.
How do I break from loop when using parallel()?
import std.parallelism : parallel; foreach(t; parallel(arr)) { if(!doSomething(t)) { return false; } } It reuturns the run time error: std.parallelism.ParallelForeachError@(0): Cannot break from a parallel foreach loop using break, return, labeled break/continue or goto statements. What's the proper way to break from loop?
Re: using wkhtmltopdf with D
On Monday, 28 May 2018 at 02:10:48 UTC, sarn wrote: On Monday, 28 May 2018 at 01:28:10 UTC, Dr.No wrote: What's likely the reason of the crash? mismatch between D and C memory alignment? From an ABI point of view, the raw pointers won't care about the memory structure they point to. The function call is the only thing that depends on the binary interface. If you translate the code into C, does it work? Yep, the C version work just fine.
Re: Build interface from abstract class
On Monday, 28 May 2018 at 11:51:20 UTC, Simen Kjærås wrote: On Monday, 28 May 2018 at 09:59:50 UTC, DigitalDesigns wrote: Implementing interfaces can be a pain but are necessary. I like to use abstract classes and provide a base implementation. It would be cool if I could use D's awesome meta features to extract the interface from the abstract class then build it. This requires some funky stuff which I'm not sure D can do Creating an interface based on a class is no big deal in D: interface Interface(T) { import std.traits; static foreach (fn; __traits(allMembers, T)) static foreach (overload; MemberFunctionsTuple!(T, fn)) mixin("ReturnType!overload "~fn~"(Parameters!overload);"); } class A { void fun() {} } alias IA = Interface!A; However, you run into a problem when A is expected to implement IA: in order to figure out which functions should be in the interface, we need to know which functions are in A. And in order to figure out which functions are in A, we need to know which functions are in IA. It's a loop with no real solution. In this specific case, one could consider only members of A, ignoring any interfaces or base classes. This isn't currently possible, but it's not an entirely unreasonable enhancement request. -- Simen I do not think this is a problem in D. Infinite recursion can always be terminated with appropriate means. 1. Use attributes. methods in class A should be marked as being for the interface. When added to the interface they will not have the attribute so will not be picked up again. 2. Your method of function creation does not pick up attributes and other factors so it is weak. Case 1 should be easy to deal with. Case 2, I am not so sure how to build the signature exactly as it is expressed. This is, of course, just a copy an paste mechanism but it would require D to provide us the signature in some way. Maybe an easy and direct way would be to pass __FILE__ and __LINE__ and extract the line? This seems a bit risky and slow. Case 1 Will not work if UDA's are required to be exactly the same between interface and class. I do not know if D enforces that but if it does it seems a bit overkill. Here is my solution that does not solve problem 2: import std.stdio; template InterfaceFromClass(alias T, string id) { auto InterfaceFromClass() { string s; import std.traits; foreach (member; __traits(allMembers, T)) { static foreach (overload; MemberFunctionsTuple!(T, member)) { enum attr = __traits(getAttributes, overload); static if (__traits(getProtection, __traits(getMember, T, member)) == "public") { mixin(`enum attrs = __traits(getAttributes, T.` ~ member ~ `);`); foreach(a; attrs) static if (is(typeof(a) == string) && a.length > 0 && a == "InterfaceMembers") { s ~= (ReturnType!overload).stringof ~" "~member~""~(Parameters!overload).stringof~";"; } } } } return "interface "~id~"\n{\n "~s~"\n}"; } } Which you can see it at work here: https://dpaste.dzfl.pl/f49be5dd7daa
Re: D's Destructors are What Scott Meyers Warned Us About
On Monday, 28 May 2018 at 04:26:02 UTC, sarn wrote: On Sunday, 27 May 2018 at 22:27:52 UTC, sarn wrote: I've been thinking this through a bit, and here's what I've got so far: Here's a tweak that should be implementable without any language changes: Instead of trying to detect an empty destructor, we use a UDA on the class --- call it BaseObject or something. A BaseObject-marked class is meant to be something like Andre's ProtoObject, or a custom alternative base. It must not define a destructor or include members with destructors (could relax this in future but works for now), and must only inherit from other BaseObject-marked classes. With that, __vdtor could be implemented using a template mixin. For a BaseObject class, that would generate an empty virtual __vdtor. For other classes, it would call __xdtor and then (non-virtually) call __vdtor for the superclass as long as it's not a BaseObject class. Can anyone see something I've missed? I think it works with the current type system, makes Andre's ProtoObject possible while supporting subclassing with @nogc or whatever, and gives us safe class destructors that could be compatible with C++. How is __vdtor is going to be called, via destroy or via directly? The issue that I see that your going to create a "BaseObject" for every attribute or combination of said attributes. Which creates way too much code bloat. Even more so with the possibility of adding more attributes in the future.
Re: Tiny D suitable for embedded JIT
On Wednesday, 23 May 2018 at 18:49:05 UTC, Dibyendu Majumdar wrote: Now that D has a better C option I was wondering if it is possible to create a small subset of D that can be used as embedded JIT library. I would like to trim the language to a small subset of D/C - only primitive types and pointers - and remove everything else. The idea is to have a high level assembly language that is suitable for use as JIT backend by other projects. I wanted to know if this is a feasible project - using DMD as the starting point. Should I even think about trying to do this? The ultimate goal is to have JIT library that is small, has fast compilation, and generates reasonable code (i.e. some form of global register allocation). The options I am looking at are a) start from scratch, b) hack LLVM, or c) hack DMD. Regards Dibyendu You may like the project of a compiler I am doing https://github.com/MrSmith33/tiny_jit TLDR: fully in D. No dependencies. Currently for amd64 + Win64 calling convension. P.S. Sorry for late response.
Re: Close Threads
On 05/28/2018 11:47 AM, candle wrote: Hey Folks. I have a question about threading and how to close threads i don't need anymore. In the following code, i build 3 threads with spawn from the concurrency module. if one thread found the number, all others thread must stop search. but i have a big logical problem in my mind. i hope someone can help me to find a solution. Happy Greetings and here is the code: https://pastebin.com/vQRediG6 The problem is, the threads are all in their while loops, never checking 'finish' message. You need to move the 'receive(bool finish)' checking inside the while loop but you must replace it with receiveTimeout with 0 duration, otherwise your receive call will block until a message arrives: receiveTimeout(0.msecs, (bool finish) { if(finish == true){ return; } }); Ali
Re: Close Threads
sorry about my double post, but: the receive in the search function, was first under (in) the (guess =! searchFor) block, but it was the same effect. for testing i have these writeln("test1 and 2"). writeln(guess) i have never seen. is receive a loop itself ?
[Issue 18868] Separate compilation generates two static this functions, runs it twice
https://issues.dlang.org/show_bug.cgi?id=18868 --- Comment #3 from github-bugzi...@puremagic.com --- Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/849155631cba3017566d3160cf15cb40584abf10 fix Issue 18868 - nondeterministic static ctor/dtor Instead of using a counter to create unique static ctor and dtor function identifiers, use the deterministic line+column location that is also used for unittests. The further disambiguate mixin instantiations on the exact same location, use a local counter. https://github.com/dlang/dmd/commit/cf19b78d47572e1c6d1a79687ea592b051552e93 Merge pull request #8255 from JohanEngelen/fix18868 fix Issue 18868 - nondeterministic static ctor/dtor merged-on-behalf-of: Jacob Carlborg --
[Issue 18868] Separate compilation generates two static this functions, runs it twice
https://issues.dlang.org/show_bug.cgi?id=18868 github-bugzi...@puremagic.com changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --
Close Threads
Hey Folks. I have a question about threading and how to close threads i don't need anymore. In the following code, i build 3 threads with spawn from the concurrency module. if one thread found the number, all others thread must stop search. but i have a big logical problem in my mind. i hope someone can help me to find a solution. Happy Greetings and here is the code: https://pastebin.com/vQRediG6
[Issue 18892] Wrong type in error message for static members and alias this
https://issues.dlang.org/show_bug.cgi?id=18892 github-bugzi...@puremagic.com changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --
[Issue 18892] Wrong type in error message for static members and alias this
https://issues.dlang.org/show_bug.cgi?id=18892 --- Comment #3 from github-bugzi...@puremagic.com --- Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/6171f9e6980347b8678926034fb5757e513f0206 Fix Issue 18892 - Wrong type in error message for static members and alias this https://github.com/dlang/dmd/commit/35f614c7d3e1ab72879a5c4d40eb64584095d6f4 Merge pull request #8303 from JinShil/fix_18892 Fix Issue 18892 - Wrong type in error message for static members and alias this merged-on-behalf-of: Razvan Nitu--
Re: What is special about an immutable array of class objects, and why can I not .dup ?
On Monday, 28 May 2018 at 13:51:49 UTC, James Blachly wrote: Consider the below: ``` class C { int x; } struct S { int x; } void main() { immutable C[] c = [ new C(), new C()]; immutable S[] s = [ S(), S() ]; immutable int[] i = [ 1, 2 ]; auto x = c.dup; auto y = s.dup; auto z = i.dup; } ``` This fails to compile with a `.dup` template matching error at line `auto x = c.dup;`. However, calling `.idup` works just fine. The immutable struct array and int array of course `.dup` just fine. I would have guessed that changing the definition of `C[]` to `immutable(C)[]` would have also helped, but it did not. Why are the class objects special in this case, and why does `immutable(C)[]` not help? I believed that this defined a dynamic array `c` which was itself mutable, the elements of which were immutable. Thanks for insights. I'm going to make a wild guess that .dup is a shallow copy and if the class has any members that are reference types only references to them are copied. Which means that by creating a mutable duplicate of the class you essentially have a mutable reference to said member. Even though in your example that isn't the case, then that's the only reason I can think of the restriction making sense.
Re: What is special about an immutable array of class objects, and why can I not .dup ?
On Monday, May 28, 2018 13:51:49 James Blachly via Digitalmars-d-learn wrote: > Consider the below: > > ``` > class C > { > int x; > } > > struct S > { > int x; > } > > > void main() > { > immutable C[] c = [ new C(), new C()]; > immutable S[] s = [ S(), S() ]; > immutable int[] i = [ 1, 2 ]; > > auto x = c.dup; > auto y = s.dup; > auto z = i.dup; > > } > ``` > > This fails to compile with a `.dup` template matching error at > line `auto x = c.dup;`. However, calling `.idup` works just fine. > The immutable struct array and int array of course `.dup` just > fine. > > I would have guessed that changing the definition of `C[]` to > `immutable(C)[]` would have also helped, but it did not. > > Why are the class objects special in this case, and why does > `immutable(C)[]` not help? I believed that this defined a > dynamic array `c` which was itself mutable, the elements of which > were immutable. > > Thanks for insights. dup makes the entire thing mutable, and the compiler can't safely convert immutable class references to mutable ones. And when you think about it, the immutability of the array itself really isn't the key thing here anyway. All you have to do to get a mutable one is to slice it - slicing gives you a tail-const/tail-immutable dynamic array pointing to the same data. So, ultimately, what you're doing with dup vs idup is deciding what the mutability of the elements is. dup makes them mutable, and idup makes them immutable. In the case of primitive types or structs which don't have postblit constructors, that's usually trivial, but it doesn't work with class references. For them, you're stuck with the same level of mutablity, because there is no easy conversion for them between mutable and immmutable. - Jonathan M Davis
What is special about an immutable array of class objects, and why can I not .dup ?
Consider the below: ``` class C { int x; } struct S { int x; } void main() { immutable C[] c = [ new C(), new C()]; immutable S[] s = [ S(), S() ]; immutable int[] i = [ 1, 2 ]; auto x = c.dup; auto y = s.dup; auto z = i.dup; } ``` This fails to compile with a `.dup` template matching error at line `auto x = c.dup;`. However, calling `.idup` works just fine. The immutable struct array and int array of course `.dup` just fine. I would have guessed that changing the definition of `C[]` to `immutable(C)[]` would have also helped, but it did not. Why are the class objects special in this case, and why does `immutable(C)[]` not help? I believed that this defined a dynamic array `c` which was itself mutable, the elements of which were immutable. Thanks for insights.
[Issue 18892] Wrong type in error message for static members and alias this
https://issues.dlang.org/show_bug.cgi?id=18892 Mike Franklinchanged: What|Removed |Added Keywords||pull CC||slavo5...@yahoo.com --- Comment #2 from Mike Franklin --- Alternative PR: https://github.com/dlang/dmd/pull/8303 --
[Issue 18866] Overload from opDispatch ignored in WithStatement
https://issues.dlang.org/show_bug.cgi?id=18866 --- Comment #4 from Simen Kjaeraas--- > there would be absolutely no way of calling fun1() from within the > WithStatement body Sure there would. Assuming the same code as in comment 0, you would call the global fun2 using .fun2();. You can test this by duplicating the line that calls fun2 and adding a period - it will print 'global'. There's no reason to assume that wouldn't work if an overload was available via opDispatch. --
[Issue 18866] Overload from opDispatch ignored in WithStatement
https://issues.dlang.org/show_bug.cgi?id=18866 RazvanNchanged: What|Removed |Added CC||razvan.nitu1...@gmail.com --- Comment #3 from RazvanN --- I'm not sure if this bug report is valid. The current behavior might be a future. If this "bug" would be fixed there would be absolutely no way of calling fun1() from within the WithStatement body and that IMHO is an arbitrary limitation. As things stand now, the compiler first tries to resolve fun1 as a member of S1 and if that's not possible it goes up the enclosing scope. If the chain of scopes is over and fun1 still wasn't resolved then opDispatch is called. In my opinion this makes a lot more sense then calling opDispatch for every method that is not defined in the struct. --
Re: Build interface from abstract class
On Monday, 28 May 2018 at 09:59:50 UTC, DigitalDesigns wrote: Implementing interfaces can be a pain but are necessary. I like to use abstract classes and provide a base implementation. It would be cool if I could use D's awesome meta features to extract the interface from the abstract class then build it. This requires some funky stuff which I'm not sure D can do Creating an interface based on a class is no big deal in D: interface Interface(T) { import std.traits; static foreach (fn; __traits(allMembers, T)) static foreach (overload; MemberFunctionsTuple!(T, fn)) mixin("ReturnType!overload "~fn~"(Parameters!overload);"); } class A { void fun() {} } alias IA = Interface!A; However, you run into a problem when A is expected to implement IA: in order to figure out which functions should be in the interface, we need to know which functions are in A. And in order to figure out which functions are in A, we need to know which functions are in IA. It's a loop with no real solution. In this specific case, one could consider only members of A, ignoring any interfaces or base classes. This isn't currently possible, but it's not an entirely unreasonable enhancement request. -- Simen
Re: What's the purpose of the 'in' keyword ?
On Sunday, 27 May 2018 at 16:00:15 UTC, Jonathan M Davis wrote: On Sunday, May 27, 2018 16:28:56 Russel Winder via Digitalmars-d-learn wrote: [...] Honestly, I'd suggest that folks never use in at this point. There's zero benefit to it. In principle, in was supposed to be const scope, but scope has never really done anything for anything other than delegates, so there has been no reason to use it over const. However, many folks seem to like it based on the idea that it was the opposite of out - and some folks used it based n what they expected scope to end up meaning whenever it finally got implemented for more than just delegates. Either way, it didn't actually buy them anything as long as scope has done nothing. [...] I really find these type of descriptions to be really useful and insightful. Going through the D textbooks can leave someone a little confused on when to use what and where? D has so many keywords and as a beginner it can be overwhelming. Thank you for your insights.
Comparing the c ffi overhead on various programming languages
Might be interesting to checkout to find some optimization potential: https://github.com/dyu/ffi-overhead -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Re: Comparing the c ffi overhead on various programming languages
On 28/05/2018 10:16 PM, Robert M. Münch wrote: Might be interesting to checkout to find some optimization potential: https://github.com/dyu/ffi-overhead https://github.com/dyu/ffi-overhead/issues/5
[Issue 3680] default struct constructor should not be removed
https://issues.dlang.org/show_bug.cgi?id=3680 RazvanNchanged: What|Removed |Added Status|NEW |RESOLVED CC||razvan.nitu1...@gmail.com Resolution|--- |FIXED --- Comment #9 from RazvanN --- This has been fixed. Both lines in test case 1) compile now and for test case 2) a deprecation is issued. I am referring to the test cases in the original bug report. Closing as fixed. --
Build interface from abstract class
Implementing interfaces can be a pain but are necessary. I like to use abstract classes and provide a base implementation. It would be cool if I could use D's awesome meta features to extract the interface from the abstract class then build it. This requires some funky stuff which I'm not sure D can do mixin(InterfaceFromAbstractClass!(MyAbstraction, "MyInterface")); interface MyInterface2 : MyInterface { final static void baz() { } } abstract class MyAbstraction : MyInterface2 { @InterfaceMembers { void foo() { }; } } InterfaceFromAbstractClass will get all the @InterfaceMembers members and declare them in an interface MyInterface. This avoids all the duplicate code that interfaces has to create. Is this possible in D?
[Issue 15125] Explicit pure needed even though pure: at the top of the file
https://issues.dlang.org/show_bug.cgi?id=15125 RazvanNchanged: What|Removed |Added CC||razvan.nitu1...@gmail.com --- Comment #1 from RazvanN --- Although I cannot find any documentation about it, from what my experience using pure:, safe:, extern(something):, nogc:, nothrow: works only for top-level declaration (does not include the inner scopes of aggregateDeclarations). In your specific case pure and safe are applied to the MyExceptionClass but since safe and pure do not make sense for classes, they are silently ignored (not propagated to member functions). I have no idea if this is the intended behavior or not, but in my opinion, dmd's policy to silently ignore attributes when they do not make sense is not a good one. Other notable cases: extern(C) class A {} // compiler accepts it and ignores extern(C) pure class A {} // again no problem, but pure is not propagated to A's // methods @safe class A {} // ditto The explanation for this is that you can use `$attribute`: at the top of the module and only the declarations that make sense in conjunction with that attribute will be affected and changing this to actually issuing an error for those that don't would break too much code. I tried doing this for `extern(C) class` and look at the result [1]. In conclusion, this will most likely be closed as WONTFIX. [1] https://github.com/dlang/dmd/pull/7229 --
Re: SecureD Futures (v2.0)
On 05/28/2018 12:14 AM, sarn wrote: On Monday, 28 May 2018 at 06:22:02 UTC, Adam Wilson wrote: On 05/27/2018 08:52 PM, sarn wrote: On Monday, 28 May 2018 at 02:25:20 UTC, Adam Wilson wrote: I like it. But it does require more space. We need three salts and three lengths in the header. One for the PBKDF2 KDK, one for the MAC key, and one for the encryption key. HKDF-Expand doesn't need a salt. You just need one salt to make the KDK (whether you use PBKDF2 or HKDF-Extract for that) and no extra salts for deriving the encryption and MAC key. Strictly speaking, it's is Optional but Strongly Recommended per RFC5869-3.1 There's HKDF-Expand and there's HKDF-Extract. HKDF-Extract takes an optional salt and HKDF-Expand doesn't use a salt at all (take a closer look at that RFC). That OpenSSL routine is the combination of the two, so that's why it takes the salt. I understand that. But the way I read the first paragraph of 3.1 is that yes, it can work without a Salt, but HKDF, in general, is strongly suggested to be used with a salt. If we are really concerned about bytes we could reuse the salt for all three steps (KDK/MAC/KEY), but TBH, I'm not worried about disk usage. Let me ask the question a different way. What is the reason NOT to use 2 different salts for the MAC and KEY generation steps? -- Adam Wilson IRC: LightBender import quiet.dlang.dev;
Re: Conditionally set nothrow: for a block of code.
On Thursday, 24 May 2018 at 18:51:31 UTC, Mike Franklin wrote: I'm trying to find a way to declare a block of code `nothrow:` when compiling with -betterC, but not `nothrow` when not compiling with -betterC. [...] Not one now but, DIP 1012 will allow this as nothrow will become a regular enum attribute.
Re: SecureD Futures (v2.0)
On Monday, 28 May 2018 at 06:22:02 UTC, Adam Wilson wrote: On 05/27/2018 08:52 PM, sarn wrote: On Monday, 28 May 2018 at 02:25:20 UTC, Adam Wilson wrote: I like it. But it does require more space. We need three salts and three lengths in the header. One for the PBKDF2 KDK, one for the MAC key, and one for the encryption key. HKDF-Expand doesn't need a salt. You just need one salt to make the KDK (whether you use PBKDF2 or HKDF-Extract for that) and no extra salts for deriving the encryption and MAC key. Strictly speaking, it's is Optional but Strongly Recommended per RFC5869-3.1 There's HKDF-Expand and there's HKDF-Extract. HKDF-Extract takes an optional salt and HKDF-Expand doesn't use a salt at all (take a closer look at that RFC). That OpenSSL routine is the combination of the two, so that's why it takes the salt.
Re: SecureD Futures (v2.0)
On 05/27/2018 08:52 PM, sarn wrote: On Monday, 28 May 2018 at 02:25:20 UTC, Adam Wilson wrote: I like it. But it does require more space. We need three salts and three lengths in the header. One for the PBKDF2 KDK, one for the MAC key, and one for the encryption key. HKDF-Expand doesn't need a salt. You just need one salt to make the KDK (whether you use PBKDF2 or HKDF-Extract for that) and no extra salts for deriving the encryption and MAC key. Strictly speaking, it's is Optional but Strongly Recommended per RFC5869-3.1 The use case here is that this data is going into storage and that storage is cheap. We don't have to be strict on our byte budget. :) https://tools.ietf.org/html/rfc5869 https://www.openssl.org/docs/man1.1.0/crypto/EVP_PKEY_CTX_set_hkdf_md.html SecureD is supposed to be "Crypto done right." So I might as well do it right and follow the RFC. -- Adam Wilson IRC: LightBender import quiet.dlang.dev;
Re: Clash When Using Function as Template Value-Parameters?
On Sunday, 27 May 2018 at 20:38:25 UTC, Daniel Kozak wrote: I would rewrite it to something like this: template BTree(ValueT, KeyT = ValueT,alias KeyF = unaryFun!"cast(const)a") { class BTree { This is roughly what I originally had, but it creates a number of problems that I wanted to get around. Changing KeyF back to an alias means that any function that uses it can no longer be const, pure, @nogc, or nothrow. Essentially the parameter is just anything the user provides. If I use a template value-parameter, then it forces any lambda the user passes in to either match the type I enter in (with const, pure, etc.) or the program to fail to compile. That is, I don't want the user to pass in any function, but only functions with the desired attributes. I.e., I wouldn't want them to pass in for KeyF something like "a.data--". Listing out the full type does indeed work correctly with various examples, and letting the user pass in something like `a => a._id` does compile, but the only problem is that when there are two such template instances in the same program. Logically `BTree!(MyStruct, int, a => a.id)`, `BTree!(AnotherStruct, char, a => a.name[0])`, `BTree!int` and `BTree!char` should all be totally independent. But for reasons unknown, the individual parameters seems to be swapped and and confused during compilation. In the error above I listed. The function parameter from `BTree!char` is being used to create a compile error against `BTree!int`, which is very odd. Each of these classes compile and run just fine individually, the compilation only breaks when both exist.