Re: D is dead
On 8/28/2018 6:39 AM, Iain Buclaw wrote: Template emission strategy is a mess, we're better off just instantiating all templates in all compilation units, and let the compiler decide whatever to discard. Even -allinst does not instantiate enough to allow the compiler to make such decisions that C++ has no problem with (most of the time). Martin and I proposed a simple strategy for that, but Kenji implemented a different algorithm that nobody understands, and has proved inadequate. There are a couple unresolved bug reports on that.
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
H. S. Teoh wrote: > On Tue, Aug 28, 2018 at 10:20:06AM -0700, Manu via Digitalmars-d wrote: > [...] > Actually, I think C++ const is not very useful, because it guarantees > nothing. At the most, it's just a sanity checker to make sure the > programmer didn't accidentally do something dumb. But given an opaque > C++ function that takes const parameters, there is ZERO guarantee that > it doesn't actually modify stuff behind your back, and do so legally > (per spec). No, casting away const on pointers and references is only legal if the object pointed to is actually mutable (not const). Everything else is UB. Casting away const of a function parameter that is not under your control will sooner or later lead to UB. Tobi
Re: Is @safe still a work-in-progress?
On 8/23/2018 6:10 AM, Atila Neves wrote: -- struct S { int x; @safe int* foo() { return } } -- % dmd -o- -dip1000 foo.d % echo $? 0 struct S { int x; @safe int* foo() { return } } int* bar() { S s; return s.foo(); } dmd test -dip1000 test.d(3): Error: returning escapes a reference to parameter this, perhaps annotate with return Oops: -- int* gPtr; void main() { auto s = S(42); gPtr = s.foo; } -- I get: test.d(3): Error: returning escapes a reference to parameter this, perhaps annotate with return -- int[] gSlice; void main() { auto s = S([42]); gSlice = s.foo; } struct S { int[] x; @safe int[] foo() return { return x; } } -- T[] is treated like T* as far as scope, etc., are concerned. You should see identical results. And in a struct, `this` is a `ref`, yet `scope` on a member function applies to `this`. Actually, it applies to fields of `this`.
Re: Is @safe still a work-in-progress?
On Wednesday, 29 August 2018 at 05:04:22 UTC, Walter Bright wrote: On 8/25/2018 4:09 AM, Nicholas Wilson wrote: On Saturday, 25 August 2018 at 02:25:41 UTC, Walter Bright wrote: I'm not hostile to debate. I just don't care for "this is uncharted territory, so let's do nothing" which has been going on for probably 4 years now, coincident with "scope is incomplete, D sux". I.e. lead, follow, or get out of the way :-) Document it Already done: https://issues.dlang.org/show_bug.cgi?id=19097 Bugzilla is not documentation. These are language changes they need to be in release notes and the spec.
Re: Is @safe still a work-in-progress?
On 8/28/2018 6:12 AM, Steven Schveighoffer wrote: So this would mean a member function would have to be refactored into a different function with a different calling syntax. i.e: x.foo(target); would have to be refactored to: target.foo(x); or foo(target, x); Maybe it should be anyway. But in terms of put, strictly speaking, any call of some.pipeline.put(x) is wrong. It should be put(some.pipeline, x), to avoid issues with how put was designed. There are some of those in Phobos, too. It's covered by the proposed addition. I don't know how to prove anything with programming languages. I don't mean prove like mathematical proof. I mean try to consider how this affects all cases instead of just the one case that will make phobos compile. "show" is a better verb than "prove". I don't know how to find all cases, either, except by implementing it.
Re: Is @safe still a work-in-progress?
On 8/25/2018 4:09 AM, Nicholas Wilson wrote: On Saturday, 25 August 2018 at 02:25:41 UTC, Walter Bright wrote: I'm not hostile to debate. I just don't care for "this is uncharted territory, so let's do nothing" which has been going on for probably 4 years now, coincident with "scope is incomplete, D sux". I.e. lead, follow, or get out of the way :-) Document it Already done: https://issues.dlang.org/show_bug.cgi?id=19097
Re: Is @safe still a work-in-progress?
On 8/25/2018 5:42 AM, Chris M. wrote: What about my other point then on the syntax? I think something similar to what I suggested would be a much more flexible solution and is worth considering. Much more work would be needed to make that a proposal.
Re: D now has a dangerous competitor
On Tuesday, 28 August 2018 at 23:27:09 UTC, Nick Sabalausky wrote: On Tuesday, 28 August 2018 at 21:57:28 UTC, solidstate1991 wrote: Thanks to my education, I first wanted to approach every problems in programming from an object-oriented viewpoint, since that was the only one we were taught. Sounds like you were more or less lucky compared to average: For a long while, OOP wasn't just the only thing taught, it was frequent taught specifically to be "the one and only right way." It's not so much OOP itself that's hated: It's the late 90's early 2000's obsession that OOP is the one right way to do EVERYTHING that gets a lot of (much deserved) hate. I used to do a lot of OO myself (in fact, Tango was very heavily rooted in OOP design), but the more I use D2 and other things, the more convinced I am that there are just simply better mechanisms (provided the language in question supports them well enough) to get the benefits offered by traditional inheritance-based OOP, without so much of the now-well-known downsides. I'm 90% convinced that an equivalent of traditional Java-style OOP could be constructed out of these meachanisms without too much trouble, and is effectively a subset of them. If I were a grad student, I would totally do a thesis around that. Honestly C++ did OOP somewhat right, because it wasn't forced upon you, but C++ itself has design issues, that I think D has solved very well. D does OOP better than C++, but D is still missing some very common OOP patterns. See: https://forum.dlang.org/thread/tjqxslxfxjgliyziz...@forum.dlang.org In C#, Java etc. that's a perfectly common pattern. I don't know what C++'s behavior is, but I guess it doesn't matter in C++, because of friends.
[Issue 19203] alias this to a bool behaves both inconsistently and incorrectly with static assert
https://issues.dlang.org/show_bug.cgi?id=19203 --- Comment #1 from Nicholas Wilson --- s/isArrayLike/hasPopBack --
[Issue 19203] New: alias this to a bool behaves both inconsistently and incorrectly with static assert
https://issues.dlang.org/show_bug.cgi?id=19203 Issue ID: 19203 Summary: alias this to a bool behaves both inconsistently and incorrectly with static assert Product: D Version: D2 Hardware: x86 OS: Mac OS X Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: iamthewilsona...@hotmail.com struct BoolWithErr { bool b; string error; alias b this; } struct Foo {} template hasPopBack(T) { static if (!is(typeof(T.init.popBack))) enum hasPopBack = BoolWithErr(false, T.stringof~" does not have popBack"); else enum hasPopBack = BoolWithErr(true,""); } int main() { // Fine: auto a = isArrayLike!Foo && isArrayLike!Foo; // false enum b = isArrayLike!Foo && isArrayLike!Foo; // false pragma(msg, typeof(a)); // bool // Fine: // Error: static assert: b is false static assert(b); // Dubious: alias this b should work // Error: expression isArrayLike!(Foo) of type BoolWithErr does not have a boolean value // while evaluating: static assert(isArrayLike!(Foo)) static assert(isArrayLike!Foo); // Bad: typeof the expression is bool // Error: expression isArrayLike!(Foo) && isArrayLike!Foo of type BoolWithErr does not have a boolean value //while evaluating: static assert(isArrayLike!(Foo) && isArrayLike!Foo) static assert(isArrayLike!Foo && isArrayLike!Foo); return 0; } --
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tue, 28 Aug 2018 at 19:00, Walter Bright via Digitalmars-d wrote: > > There's been some talk of adding a "mutable" qualifier for fields, which would > stop the transitivity of const at that point. But it has problems, such as > what > happens with opaque types. The compiler can no longer check them, and hence > will > have to assume they contain mutable members. Exactly. And you arrive at C++. 'c-const' and 'turtles-const' probably need to be specified differently from the top, not broken along the way with the likes of mutable.
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tue, 28 Aug 2018 at 10:54, H. S. Teoh via Digitalmars-d wrote: > > On Tue, Aug 28, 2018 at 10:20:06AM -0700, Manu via Digitalmars-d wrote: > [...] > > The reality is though, that D's const is not actually very useful, and > > C++'s const is. > > Actually, I think C++ const is not very useful, because it guarantees > nothing. At the most, it's just a sanity checker to make sure the > programmer didn't accidentally do something dumb. I'd rate that as "pretty damn useful"™! > But given an opaque > C++ function that takes const parameters, there is ZERO guarantee that > it doesn't actually modify stuff behind your back, and do so legally > (per spec). Well it can't modify the head-object... that's the point of head-const! > I mean, how many times have you written const_cast<...> > just to get a piece of code to compile? Never in my life. That's a heinous crime. If it were removed from C++ and declared UB, I'd be fine with that. > I know I've been guilty of this > in many places, because it simply isn't worth the effort to track down > all the places of the code that you need to fix to make it > const-correct. So basically, C++ const is nothing more than an > annotation that isn't really enforced. It could be enforced though. const_cast<> doesn't have to exist, and `mutable` doesn't have to exist either. That would strengthen C++'s design to make it more meaningful while retaining a generally useful semantic. That said, D's transitive const is a nice thing to be able to express... I just recognise that it's mostly useless, and from that perspective, I think being able to express the C++ meaning would be useful, and certainly MORE useful. I wonder if there's a design that could allow to express both options selectively? > But you're spot on about D's const, though. While D's const *does* > provide real guarantees (unless you tread into UB territory by casting > it away), that also limits its scope so much that it's rarely useful > outside of rather narrow confines. Yet because it's so strict, using it > requires investing significant effort. So you end up with the > unfortunate situation of "a lot of effort" + "limited usefulness" which > for many people equals "not worth using". And then that case of not being used (even if it could have) blocks use somewhere else, and not(/unable-to)-const spreads like a virus >_< > > D has no way to express head-const, and it turns out it's a > > tremendously useful concept. > > I can live without head-const... but what *really* makes const painful > for me is the lack of head-mutable. I.e., given a const container (which > implies const objects), there is no universal way to obtain a mutable > reference to said const objects, ... I think we're talking about the same thing. In this context, the container is the 'head', and the elements would be mutable beneath that unless declared const themselves. > unless you tread into UB territory by > forcefully casting it away. This makes const so limited in > applicability that, for the most part, I've given up using const at all, > in spite of having tried quite hard to use it as much as possible for > years. Right. This appears to be the accepted recommendation for quite some time, and no change in sight. Tragically, the more people resign to this recommendation (and it's practically official at this stage), the harder it becomes to use even if you want to; any library code that you interact with that didn't use const because 'recommendation' creates interaction blockages for your own code, propagating can't-use-const into your client code, despite your best intentions. D's const is an objective failure. I don't think anyone could argue otherwise with a straight face. It's sad but true; the surface area and complexity of the feature absolutely doesn't justify its limited (and actively waning) usefulness.
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
There's been some talk of adding a "mutable" qualifier for fields, which would stop the transitivity of const at that point. But it has problems, such as what happens with opaque types. The compiler can no longer check them, and hence will have to assume they contain mutable members.
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
Thanks, that's a good explanation of the point of the differences between const and immutable.
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tuesday, 28 August 2018 at 20:32:29 UTC, H. S. Teoh wrote: On Tue, Aug 28, 2018 at 07:39:20PM +, tide via Digitalmars-d wrote: On Tuesday, 28 August 2018 at 17:02:46 UTC, H. S. Teoh wrote: > On Tue, Aug 28, 2018 at 08:18:57AM +, Eugene Wissner via > Digitalmars-d wrote: [...] > > There are still valid use cases where const should be > > "broken". One of them is mutex (another one caching). I > > have very little experiance in multi-threaded programming, > > but what do you think about "mutable" members, despite the > > object is const? > > The problem with compromising const is that it would > invalidate any guarantees const may have provided. Const in > D is not the same as const in languages like C++; const in D > means *physical* const, as in, the data might reside in ROM > where it's physically impossible to modify. Allowing the > user to bypass this means UB if the data exists in ROM. I feel that such a narrow use case, wouldn't you just use something like immutable instead. The problem is that immutable implicitly converts to const. Basically, const means "I guarantee I will never modify this data (though someone else might", and immutable means "nobody will ever modify this data". You cannot allow const to mutate without risking breakage with immutable. If the original data came from a mutable reference, you can probably get away with casting const away. But if it came from an immutable object, casting const away is UB. Allowing const to be "sometimes" modified is also UB. > Plus, the whole point of const in D is that it is > machine-verifiable, i.e., the compiler checks that the code > does not break const in any way and therefore you are > guaranteed (barring compiler bugs) that the data does not > change. If const were not machine-verifiable, it would be > nothing more than programming by convention, since it would > guarantee nothing. Allowing const to be "broken" somewhere > would mean it's no longer machine-verifiable (you need a > human to verify whether the semantics are still correct). This is still not true, it is not machine verifiable as it is. It can be bypassed quite easily, as a const object can be assigned from an non-const one. There's no way to offer that guarantee. You misunderstand. Const means "this code cannot modify this object no matter what". It does not guarantee somebody else can't modify it (you want immutable for that). Both mutable and immutable implicitly convert to const, therefore it is imperative that code that handles const never modifies the data, because you don't know the provenance of the data: it could have come from an immutable object. Allowing const to "sometimes" modify stuff will violate immutable and cause UB. Whether a piece of code modifies the data is certainly machine-verifiable -- but only if there are no backdoors to const. If there are, then the compiler cannot feasibly verify const, since it would need to transitively examine all code called by the code in question, but the source code may not be always available. Even if the data came from a mutable object, it does not make it any less machine-verifiable, since what we're verifying is "this code does not modify this data", not "this data never changes". For the latter, immutable provides that guarantee, not const. It is possible, for example, to obtain a const reference to a mutable object, and have one thread modify the object (via the mutable reference) while another thread reads it (via the const reference). You cannot guarantee that the data itself won't change, but you *can* guarantee that the code holding the const reference (without access to the mutable reference) isn't the one making the changes. T Point being, there is a huge difference between what you were saying, and what you are saying now. "This data never changes" is a much better guarantee and check than "this code does not modify this data". You use const to make sure the data doesn't change, if you can't guarantee it doesn't change from any other code then I wouldn't say it is machine-verifiable. So we would need another qualifier "tantamount" to be implemented then it seems.
[Issue 19202] New: deprecated eponymous template prints no warning
https://issues.dlang.org/show_bug.cgi?id=19202 Issue ID: 19202 Summary: deprecated eponymous template prints no warning Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: regression Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: elpenguin...@gmail.com ``` void main() { auto b = X!(); } template X() { deprecated enum X = true; } ``` Since dmd 2.069, no warning is printed for this example. --
Re: D now has a dangerous competitor
On Tuesday, 28 August 2018 at 21:57:28 UTC, solidstate1991 wrote: Thanks to my education, I first wanted to approach every problems in programming from an object-oriented viewpoint, since that was the only one we were taught. Sounds like you were more or less lucky compared to average: For a long while, OOP wasn't just the only thing taught, it was frequent taught specifically to be "the one and only right way." It's not so much OOP itself that's hated: It's the late 90's early 2000's obsession that OOP is the one right way to do EVERYTHING that gets a lot of (much deserved) hate. I used to do a lot of OO myself (in fact, Tango was very heavily rooted in OOP design), but the more I use D2 and other things, the more convinced I am that there are just simply better mechanisms (provided the language in question supports them well enough) to get the benefits offered by traditional inheritance-based OOP, without so much of the now-well-known downsides. I'm 90% convinced that an equivalent of traditional Java-style OOP could be constructed out of these meachanisms without too much trouble, and is effectively a subset of them. If I were a grad student, I would totally do a thesis around that.
Re: Solving the impossible?
On Tuesday, 28 August 2018 at 20:37:05 UTC, Everlast wrote: Also, the biggest complaint is that when we use [] attached to a type it has a specific meaning as "an array of". e.g., int[] means an array of int's. But int[] a... then changes as we don't have an array of int's any more but simply a sequence of ints. While internally it might not matter it just doesn't jive with normal type syntax IMO. The parameter `int[] a...` is an an array of ints just like any other `int[]` in D. If you don't believe me, see for yourself here: https://run.dlang.io/is/IJdovg I understand that the syntax does not align with your expectations. Instead of complaining about it, I would urge you to set your preconceptions aside and learn D with an open mind. You'll be less frustrated, more productive, and more successful.
Re: D now has a dangerous competitor
On Tuesday, 28 August 2018 at 11:30:20 UTC, JN wrote: On Tuesday, 28 August 2018 at 08:39:20 UTC, bauss wrote: The following language is a dangerous competitor to D. https://github.com/joaomilho/Enterprise I often feel like this kind of 'jokes' are trying too hard. FizzBuzz Enterprise was fun when it first came out, and I know it's popular to hate on OOP programming, especially Java. But the fact is, a very big portion of software was built using OOP, and many of the hated design patterns have a place in programming. Sure, it doesn't provide witty one-liner quicksort examples, but when you have a group of people, having to integrate multiple webservices/databases, these kind of layered code architecture comes in handy. Of course sometimes people go too far, trying to make the code generic and fit every usecase, breaking YAGNI. Most of the hate towards OOP is misdirected. Java will be always slow because it always running in a VM, no structures so you have to rely on reference-type classes for everything. Other times it's on the developer. Thanks to my education, I first wanted to approach every problems in programming from an object-oriented viewpoint, since that was the only one we were taught (and I missed the classes on interfaces due to an incident, so I struggled to keep up). You have to learn where to use what. I personally hate C and C++ precompiler macros more, which made porting LZHAM to D a nightmare sometimes. Some parts of the macros got completely eliminated since Fiber saves most things on the stack.
Re: Can you get typeof(this) in a mixin template - trying to mimic a Kotlin feature here.
On Tuesday, 28 August 2018 at 20:39:16 UTC, aliak wrote: Hi, I'm trying to do something similar to what Kotlin allows with assigning to member variables from a map. The syntax is very readable and looks like: class User(val map: Map) { val name: String by map val age: Int by map } So I'm trying to do something similar in D: mixin template MapMembers(alias aa) { foreach (name; typeof(this).tupleof) { // if name is in aa, then mixin(m = aa[" ~ m ~ "]) ... ish } } struct User { this(Variant[string] aa) { mixin MapMembers!aa; } } Seems I can't do typeof(this) inside the mixin. One workaround is to explicitly pass the type "User" to the template mixin, but it feels like this is something that should work and I'm just unfamiliar with template mixins and their usage. Cheers, - Ali [0] https://kotlinlang.org/docs/reference/delegated-properties.html#storing-properties-in-a-map Isn't the problem, that inside a template a declaration is expected, and not a foreach? This works as expected: ´´´ import std.experimental.all; void main() { writeln("Edit source/app.d to start your project."); } mixin template MapMembers(alias aa) { typeof(this) var; /* foreach (name; typeof(this).tupleof) { // if name is in aa, then mixin(m = aa[" ~ m ~ "]) ... ish } */ } struct User { this(Variant[string] aa) { mixin MapMembers!aa; } } //mixin MapMembers!(Variant[string].init); ´´´
Re: Solving the impossible?
On Tuesday, 28 August 2018 at 19:40:36 UTC, Paul Backus wrote: On Tuesday, 28 August 2018 at 19:09:38 UTC, Everlast wrote: Yeah, I see the link paul posted. The actual syntax seems a bit strange to me... We don't do A[] a So it is not "logical". foo(A...)(A a) but if A is a specific type we must do foo(int[] a ...) The actual syntax then looks like we have an variadic set of parameters of type int[] rather than int. In `foo(A...)(A a)`, a variadic set of template *arguments* is collected into a single template *parameter*, called `A`. In `foo(int[] a ...)`, a variadic set of runtime *arguments* is collected into a single runtime *parameter* called `a`. (If you've used Python, it's also similar to how `*args` and `**kwargs` collect variadic positional and named arguments into a single list or dictionary parameter, respectively.) It really is the same underlying principle in both cases. It just looks different because `foo(A...)(A a)` is a template, and `foo(int[] a...)` isn't, and templates use a different syntax than regular functions. In fact, if you wanted to, you could combine the two and do something like this: // All args must have the same type, // but it can be any type you want. foo(T)(T[] t...) Yes, it is the same underlying principle but it is not visually consistent IMO. e.g., foo(int[] a) a is an array of int foo(int[] a...) suggests a is an array of an array of int. I see ... as a generalization of the parameters simply extending it to an arbitrary number(which cannot be represented except in an arbitrary way). so a... means there is an arbitrary number of a's. int a... means there is an arbitrary number of int. T a... means there is an arbitrary number of T's T[] a... means there is an arbitrary number of T[]'s. For example, to represent an arbitrary number of arrays using the current syntax one must do T[][] a... which looks funky. Now, it's all not a big deal in the sense that it all works out by design, but the question is, is it really needed? It seems that requiring [] just adds extra unnecessary symbols that add no useful information. Also, the biggest complaint is that when we use [] attached to a type it has a specific meaning as "an array of". e.g., int[] means an array of int's. But int[] a... then changes as we don't have an array of int's any more but simply a sequence of ints. While internally it might not matter it just doesn't jive with normal type syntax IMO. int[] a... vs int a... the second one seems better. Simpler, more direct, more obvious, and inline with the standard non variadic syntax. The ellipses pretty much state that we are dealing with an array, no reason to add redundancy. I'm only talking about syntax here and not semantics. Of course, if you see a problem with int a... not being well-formed then that would be a case against it, but I don't think it has that issue.
Can you get typeof(this) in a mixin template - trying to mimic a Kotlin feature here.
Hi, I'm trying to do something similar to what Kotlin allows with assigning to member variables from a map. The syntax is very readable and looks like: class User(val map: Map) { val name: String by map val age: Int by map } So I'm trying to do something similar in D: mixin template MapMembers(alias aa) { foreach (name; typeof(this).tupleof) { // if name is in aa, then mixin(m = aa[" ~ m ~ "]) ... ish } } struct User { this(Variant[string] aa) { mixin MapMembers!aa; } } Seems I can't do typeof(this) inside the mixin. One workaround is to explicitly pass the type "User" to the template mixin, but it feels like this is something that should work and I'm just unfamiliar with template mixins and their usage. Cheers, - Ali [0] https://kotlinlang.org/docs/reference/delegated-properties.html#storing-properties-in-a-map
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tue, Aug 28, 2018 at 06:44:37PM +, aliak via Digitalmars-d wrote: > On Tuesday, 28 August 2018 at 17:53:36 UTC, H. S. Teoh wrote: > > On Tue, Aug 28, 2018 at 10:20:06AM -0700, Manu via > > > D has no way to express head-const, and it turns out it's a > > > tremendously useful concept. > > > > I can live without head-const... but what *really* makes const > > painful for me is the lack of head-mutable. I.e., given a const > > container (which implies const objects), there is no universal way > > to obtain a mutable reference to said const objects, unless you > > tread into UB territory by forcefully casting it away. This makes > > const so limited in applicability that, for the most part, I've > > given up using const at all, in spite of having tried quite hard to > > use it as much as possible for years. > > Simen's opHeadMutable [0] was pretty good solution to this const range > stuff, but for some reason (not specified by anyone in the thread) it > didn't seem to catch on :/ > > [0] https://forum.dlang.org/post/zsaqtmvqmfkzhrmrm...@forum.dlang.org [...] Probably because nobody pushed it hard enough to make it happen. T -- It only takes one twig to burn down a forest.
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tue, Aug 28, 2018 at 07:39:20PM +, tide via Digitalmars-d wrote: > On Tuesday, 28 August 2018 at 17:02:46 UTC, H. S. Teoh wrote: > > On Tue, Aug 28, 2018 at 08:18:57AM +, Eugene Wissner via > > Digitalmars-d wrote: [...] > > > There are still valid use cases where const should be "broken". > > > One of them is mutex (another one caching). I have very little > > > experiance in multi-threaded programming, but what do you think > > > about "mutable" members, despite the object is const? > > > > The problem with compromising const is that it would invalidate any > > guarantees const may have provided. Const in D is not the same as > > const in languages like C++; const in D means *physical* const, as > > in, the data might reside in ROM where it's physically impossible to > > modify. Allowing the user to bypass this means UB if the data > > exists in ROM. > > I feel that such a narrow use case, wouldn't you just use something > like immutable instead. The problem is that immutable implicitly converts to const. Basically, const means "I guarantee I will never modify this data (though someone else might", and immutable means "nobody will ever modify this data". You cannot allow const to mutate without risking breakage with immutable. If the original data came from a mutable reference, you can probably get away with casting const away. But if it came from an immutable object, casting const away is UB. Allowing const to be "sometimes" modified is also UB. > > Plus, the whole point of const in D is that it is > > machine-verifiable, i.e., the compiler checks that the code does not > > break const in any way and therefore you are guaranteed (barring > > compiler bugs) that the data does not change. If const were not > > machine-verifiable, it would be nothing more than programming by > > convention, since it would guarantee nothing. Allowing const to be > > "broken" somewhere would mean it's no longer machine-verifiable (you > > need a human to verify whether the semantics are still correct). > > This is still not true, it is not machine verifiable as it is. It can > be bypassed quite easily, as a const object can be assigned from an > non-const one. There's no way to offer that guarantee. You misunderstand. Const means "this code cannot modify this object no matter what". It does not guarantee somebody else can't modify it (you want immutable for that). Both mutable and immutable implicitly convert to const, therefore it is imperative that code that handles const never modifies the data, because you don't know the provenance of the data: it could have come from an immutable object. Allowing const to "sometimes" modify stuff will violate immutable and cause UB. Whether a piece of code modifies the data is certainly machine-verifiable -- but only if there are no backdoors to const. If there are, then the compiler cannot feasibly verify const, since it would need to transitively examine all code called by the code in question, but the source code may not be always available. Even if the data came from a mutable object, it does not make it any less machine-verifiable, since what we're verifying is "this code does not modify this data", not "this data never changes". For the latter, immutable provides that guarantee, not const. It is possible, for example, to obtain a const reference to a mutable object, and have one thread modify the object (via the mutable reference) while another thread reads it (via the const reference). You cannot guarantee that the data itself won't change, but you *can* guarantee that the code holding the const reference (without access to the mutable reference) isn't the one making the changes. T -- A program should be written to model the concepts of the task it performs rather than the physical world or a process because this maximizes the potential for it to be applied to tasks that are conceptually similar and, more important, to tasks that have not yet been conceived. -- Michael B. Allen
Re: D now has a dangerous competitor
On 08/28/2018 04:39 AM, bauss wrote: The following language is a dangerous competitor to D. https://github.com/joaomilho/Enterprise Truly a visionary for this Millennial age. The cloud-plans for Enterprise Web 3.0 are particularly disruptive. I'm excited just imagining the possibilities it will open to bring onboard a significant plurality of contractors with upper-tier invoice payment structures.
Re: concurrency call to arms
On Tue, 2018-08-28 at 03:36 +, John Belmonte via Digitalmars-d wrote: > On Wednesday, 22 August 2018 at 16:49:01 UTC, Russel Winder wrote: > > Have you tried asyncio in the Python standard library? Is Trio > > better? > > The library that Guido admits is a disaster? > https://twitter.com/gvanrossum/status/938445451908472832 > > Trio and libraries like it have evolved out of frustration with > asyncio. When I originally wrote the comment I was thinking of asyncore, which is even worse than asyncio. […] > > It's far more than "ensuring join". It ensures that tasks > created by children are similarly constrained. It allows the > normal try-catch of exceptions coming from any level of child > tasks. It ensures that when a task has an error, all sibling > tasks are cancelled and the resulting multi-exception is > propagated to the parent. Any fork/join framework will provide such guarantees. > > – except Python is single threaded so the above is time > > division multiplexing of tasks. > > No, tasks can optionally be real threads (obviously constrained > by GIL). Soon they can be tasks from the "multiprocessing" > library as well (separate process, either local or remote). > > These are details of Trio's implementation and Python. As > mentioned, the control structures apply to any concurrency model > (implicit or explicit context switching, OS or light threads, > etc.) But that is the point, this is Python specific, and yet the motivating example is a misunderstanding of how Go is used. This inconsistency seriously undermines the general argument. I have no problem with using with statement and context managers to enforce fork/join abstractions in Python. But to say this is a new general abstraction is false claim. […] > async/await is a means to explicitly mark points of context > switching in API's and code. It applies to threads, coroutines, > remote processing, or anything else which may allow something > else to modify system state while you're waiting. Certainly it is a language structure to support yield to the appropriate scheduler, the question is whether a language structure is required or it can be handled with library features. I suspect language feature makes things easier of implementation. > Local to a single thread, async/await with coroutines happens to > be wonderful because it eliminates a ton of explicit locking, > fretting about race conditions, etc. required of the programmer. > It's a building block-- e.g. you can then combine such threads in > careful ways with message passing within and among CPU cores to > get the best of all worlds. I've never really worried about single threaded concurrency, nor used C#, so I have no actual data to apply to this argument. In a multi- threaded context, you can do all that is needed using processes and channels. Having said this executors in single or multi threaded contexts work fine at the library level without language constructs. > While Go can certainly implement the nursery and cancellation > control structures, there is no turning back on Go's implicit > context switching (i.e. any old function call can cause a context > switch). The human is back to fretting about locks and race > conditions, and unable to prove that even the smallest of > programs is correct. Not if the user sticks to using processes and channels as is the idiom on Go. Go has all the locks stuff, but if you use channels as the means of communication between processes, the programmer never needs explicit locks since everything is handled bu blocking on channels. -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Re: Solving the impossible?
On Tuesday, 28 August 2018 at 19:09:38 UTC, Everlast wrote: Yeah, I see the link paul posted. The actual syntax seems a bit strange to me... We don't do A[] a So it is not "logical". foo(A...)(A a) but if A is a specific type we must do foo(int[] a ...) The actual syntax then looks like we have an variadic set of parameters of type int[] rather than int. In `foo(A...)(A a)`, a variadic set of template *arguments* is collected into a single template *parameter*, called `A`. In `foo(int[] a ...)`, a variadic set of runtime *arguments* is collected into a single runtime *parameter* called `a`. (If you've used Python, it's also similar to how `*args` and `**kwargs` collect variadic positional and named arguments into a single list or dictionary parameter, respectively.) It really is the same underlying principle in both cases. It just looks different because `foo(A...)(A a)` is a template, and `foo(int[] a...)` isn't, and templates use a different syntax than regular functions. In fact, if you wanted to, you could combine the two and do something like this: // All args must have the same type, // but it can be any type you want. foo(T)(T[] t...)
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tuesday, 28 August 2018 at 17:02:46 UTC, H. S. Teoh wrote: On Tue, Aug 28, 2018 at 08:18:57AM +, Eugene Wissner via Digitalmars-d wrote: [...] There are still valid use cases where const should be "broken". One of them is mutex (another one caching). I have very little experiance in multi-threaded programming, but what do you think about "mutable" members, despite the object is const? The problem with compromising const is that it would invalidate any guarantees const may have provided. Const in D is not the same as const in languages like C++; const in D means *physical* const, as in, the data might reside in ROM where it's physically impossible to modify. Allowing the user to bypass this means UB if the data exists in ROM. I feel that such a narrow use case, wouldn't you just use something like immutable instead. Plus, the whole point of const in D is that it is machine-verifiable, i.e., the compiler checks that the code does not break const in any way and therefore you are guaranteed (barring compiler bugs) that the data does not change. If const were not machine-verifiable, it would be nothing more than programming by convention, since it would guarantee nothing. Allowing const to be "broken" somewhere would mean it's no longer machine-verifiable (you need a human to verify whether the semantics are still correct). This is still not true, it is not machine verifiable as it is. It can be bypassed quite easily, as a const object can be assigned from an non-const one. There's no way to offer that guarantee. import std.format : format; struct Type { int value; } void test(const ref Type type, int* ptr) { int first = type.value; *ptr = first + 1; assert(type.value == first, format!"%d != %d"(type.value, first)); } void main() { Type type = Type(10); test(type, ); }
Re: Solving the impossible?
On Tuesday, 28 August 2018 at 19:09:38 UTC, Everlast wrote: On Tuesday, 28 August 2018 at 12:00:50 UTC, bauss wrote: On Sunday, 26 August 2018 at 02:26:58 UTC, Everlast wrote: in fact, I'd rather see void print(T)(T t, int... a) You were actually close. void print(T)(T t, int[] a ...); Yeah, I see the link paul posted. The actual syntax seems a bit strange to me... We don't do A[] a So it is not "logical". foo(A...)(A a) but if A is a specific type we must do foo(int[] a ...) The actual syntax then looks like we have an variadic set of parameters of type int[] rather than int. Yeah I agree with that, but unfortunately it cannot be changed.
Re: Solving the impossible?
On Tuesday, 28 August 2018 at 12:00:50 UTC, bauss wrote: On Sunday, 26 August 2018 at 02:26:58 UTC, Everlast wrote: in fact, I'd rather see void print(T)(T t, int... a) You were actually close. void print(T)(T t, int[] a ...); Yeah, I see the link paul posted. The actual syntax seems a bit strange to me... We don't do A[] a So it is not "logical". foo(A...)(A a) but if A is a specific type we must do foo(int[] a ...) The actual syntax then looks like we have an variadic set of parameters of type int[] rather than int.
Re: Null-Coalescing Operator and Extensions
On Tuesday, 28 August 2018 at 13:27:28 UTC, Simen Kjærås wrote: Now, as has been pointed out, that only work for null-coalescing, not null-propagation. It seems writers of Optional, Variant, SumType, and so on, have decided not to support this out of the box, but rather wrap it separately, like Basile B.'s SafeAccess[1] and aliak's dispatch[2]. There's no real obstacle to wrapping member access directly in Optional!T such that it always return a Optional!(typeof(member)), though. I've been back and forth on this many times with an Optional type. I've come to the conclusion that providing a "safe" opDispatch in the optional type itself is worth if it the Optional type does not have any member functions. Otherwise it'll essentially cripple the user type if it has functions named the same. And since the optional types (presented around the forums) seem to support range access, it basically means you can't have an Optional!Range type - or any T that has a member called empty (which is not uncommon IMO). I can't figure out a way around this :( Cheers, - Ali
[Issue 19201] Error: func called with argument types (ulong) matches both: __c_long and __c_ulong
https://issues.dlang.org/show_bug.cgi?id=19201 github-bugzi...@puremagic.com changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tuesday, 28 August 2018 at 17:53:36 UTC, H. S. Teoh wrote: On Tue, Aug 28, 2018 at 10:20:06AM -0700, Manu via D has no way to express head-const, and it turns out it's a tremendously useful concept. I can live without head-const... but what *really* makes const painful for me is the lack of head-mutable. I.e., given a const container (which implies const objects), there is no universal way to obtain a mutable reference to said const objects, unless you tread into UB territory by forcefully casting it away. This makes const so limited in applicability that, for the most part, I've given up using const at all, in spite of having tried quite hard to use it as much as possible for years. Simen's opHeadMutable [0] was pretty good solution to this const range stuff, but for some reason (not specified by anyone in the thread) it didn't seem to catch on :/ [0] https://forum.dlang.org/post/zsaqtmvqmfkzhrmrm...@forum.dlang.org
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tue, Aug 28, 2018 at 10:20:06AM -0700, Manu via Digitalmars-d wrote: [...] > The reality is though, that D's const is not actually very useful, and > C++'s const is. Actually, I think C++ const is not very useful, because it guarantees nothing. At the most, it's just a sanity checker to make sure the programmer didn't accidentally do something dumb. But given an opaque C++ function that takes const parameters, there is ZERO guarantee that it doesn't actually modify stuff behind your back, and do so legally (per spec). I mean, how many times have you written const_cast<...> just to get a piece of code to compile? I know I've been guilty of this in many places, because it simply isn't worth the effort to track down all the places of the code that you need to fix to make it const-correct. So basically, C++ const is nothing more than an annotation that isn't really enforced. But you're spot on about D's const, though. While D's const *does* provide real guarantees (unless you tread into UB territory by casting it away), that also limits its scope so much that it's rarely useful outside of rather narrow confines. Yet because it's so strict, using it requires investing significant effort. So you end up with the unfortunate situation of "a lot of effort" + "limited usefulness" which for many people equals "not worth using". > D has no way to express head-const, and it turns out it's a > tremendously useful concept. I can live without head-const... but what *really* makes const painful for me is the lack of head-mutable. I.e., given a const container (which implies const objects), there is no universal way to obtain a mutable reference to said const objects, unless you tread into UB territory by forcefully casting it away. This makes const so limited in applicability that, for the most part, I've given up using const at all, in spite of having tried quite hard to use it as much as possible for years. [...] > I've also had occasional success refactoring to support const, but > it's certainly the case that success is not guaranteed. And it's > always time consuming regardless. Yes, it's time-consuming. And takes significant effort. In spite of being rather limited in applicability. In my experience, it's useful for isolated pieces of code near the bottom of the program's call chain, where there is little or no additional dependencies. But it's just too cumbersome to use at any higher level, and a royal pain in generic code (which I'm quite heavy on). It probably *can* be made to work in most cases, but it falls under my umbrella category of "too much effort needed, only marginal benefits, therefore not worth it". T -- A linguistics professor was lecturing to his class one day. "In English," he said, "A double negative forms a positive. In some languages, though, such as Russian, a double negative is still a negative. However, there is no language wherein a double positive can form a negative." A voice from the back of the room piped up, "Yeah, yeah."
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tue, 28 Aug 2018 at 00:55, Walter Bright via Digitalmars-d wrote: > > On 8/26/2018 11:16 PM, Manu wrote: > >> The code looks the same, and in fact, is about 98% the same. > > This code appears to be a mechanical translation. > > It's not. It's by hand. But I had a specific goal of minimizing the diffs, so > that if the translation didn't work, it reduced the number of places to look > for > the mistake. And in fact, this has saved me a LOT of grief :-) > > > > That's not what > > happened in this case; he wrote his game in D from scratch. > > It was just that he arrived at mostly the same place. He was googling > > for styling and sample material, but I suspect the problem was a lack > > of topical material demonstrating how he might write his D code > > differently. > > It takes time to learn how to write idiomatic D effectively. I'm still > learning > how to do it right, too. > > > > It's also the case that the significant difference between C++ and D > > (in my experience) mostly come down to: D has modules, tidier meta, > > UDA's, slices, and ranges/UFCS. In trade, D struggles with const, and > > ref is broken. > > If your code doesn't manifest some gravity towards one of those > > features, it will tend to be quite same-ey, and advantage may not be > > particularly apparent. > > I suspect that is still a bit stuck on looking at individual instruments and > not > seeing the orchestra. > > Let's take the much-maligned D const. It isn't C++ const (let's call that > "head-const", because that's what it is). Head-const for a function parameter > tells us very little about what may happen to it in the function. You can > pass a > head-const reference to a container, and have the function add/change/delete > every element of that container, all without a peep from any C++ tool. Looking > at the function signature, you've really got no clue whatsoever. > > The reason people have trouble with transitive-const is that they are still > programming in C++, where they *do* add/change/delete every member of the > "const" container. We understand... really. I've spent a decade digesting this, and I'm not one of those that has ever really complained about D's const. I've always mostly bought into it philosophically. The reality is though, that D's const is not actually very useful, and C++'s const is. D has no way to express head-const, and it turns out it's a tremendously useful concept. As I said, I tend to create a head-const hack to use in its place, and that gets me out of jail... but it's specified as undefined behaviour, which isn't great. > That includes me. I try to add transitive-const, and it won't compile, > because I > as well am used to replacing the engine and tail lights in my head-const car. > In > order to use transitive-const, it's forcing me to fundamentally re-think how I > organize code into functions. I often walk the same path, but sometimes it doesn't yield success, and in many cases, it just doesn't actually model the problem. If the problem is that I want a const container class; I don't want a function I pass a vector to mutate the container structure, that is, add/remove/reorder/reallocate the array, but I DO intend it to interact with mutable elements. That's a perfectly valid problem structure, and it turns out, it's very common. I would attribute the given element type as const if I wanted the const-ness to propagate to the elements, that's obvious and convenient. It might be that we can sufficiently rearrange all manner of conventional wisdom to interact successfully with D's const, but I've been watching this space for 10 years, and nobody has produced any such evidence, or articles that we can read and understand how to wrangle successful solutions. This particular class of problem reeks of the typical criticism for Rust... that is, I have better things to be doing with my time than trying to find awkward alternative code structures to pacify the const-checker, when in reality, const-container-of-mutable-elements is simply the correct conceptual modeling of the problem. Anyway, I'm not fighting that battle. I have enough of my own. > For example, dmd is full of functions that combine data-gathering with > taking-action. I've been reorganizing to separate data-gathering and > taking-action into separate functions. The former can be transitive-const, > maybe > even pure. And I like the results, the code becomes much easier to understand. I've also had occasional success refactoring to support const, but it's certainly the case that success is not guaranteed. And it's always time consuming regardless.
[Issue 19201] Error: func called with argument types (ulong) matches both: __c_long and __c_ulong
https://issues.dlang.org/show_bug.cgi?id=19201 Iain Buclaw changed: What|Removed |Added Status|NEW |ASSIGNED CC||ibuc...@gdcproject.org Assignee|nob...@puremagic.com|ibuc...@gdcproject.org --- Comment #1 from Iain Buclaw --- https://github.com/dlang/dmd/pull/8632 --
Re: D is dead (was: Dicebot on leaving D: It is anarchy driven development in all its glory.)
On Tuesday, 28 August 2018 at 13:39:40 UTC, Iain Buclaw wrote: On Thursday, 23 August 2018 at 15:35:45 UTC, Joakim wrote: On Thursday, 23 August 2018 at 07:37:07 UTC, Iain Buclaw wrote: On Thursday, 23 August 2018 at 06:58:13 UTC, Joakim wrote: On Thursday, 23 August 2018 at 03:50:44 UTC, Shachar Shemesh wrote: [...] Can you list what you or other Weka devs believe those fatal flaws to be? Because you've not listed any here, which makes you no better than some noob that comes in here, says D has to get better or it will die, then can't articulate what they mean by "better" or worse, mentions something trivial. Of course, you've actually used the language for years, so presumably you've got some real concerns, but do you really think the bug you just posted is "fatal" to the language? If you think there are fatal flaws, you might as well list them, whether technical or the development process, or you will just be ignored like any other noob who talks big and can't back it up. You may be ignored anyway, ;) but at least you'll have made a case that shows you know what you're talking about. I'd define fatal as some that can be fixed, but breaks 100% of everyone's code, even if the change is net positive all round. However how big a problem really is is in the eye of the beholder. An example: Symptom: The compiler can't discard unused symbols at compile time, and so it will spend a lot of time pointlessly optimising code. Problem: D has no notion of symbol visibility. Possible Solution: Make all globals hidden by default unless 'export'. Side effects: Everyone will be spending weeks to months fixing their libraries in order to only mark what should be visible outside the current compilation unit as 'export'. Benefits: Faster compile times, as in, in the most extreme example I've built one project on github with gdc -O2 and build time went from 120 seconds to just 3! So your example of a fatal flaw is that D could be 100X faster at compilation instead of just 10X than most every other native language out there?! C'mon. But that's not true. D isn't a fast language to compile, dmd is just a fast compiler. You may get a little leading edge with codebases that are effectively C. Once you throw templates into the mix though, your problems become exponential. Spending 4 seconds in the front end and codegen, only to wait 2 minutes in the optimizer is horrific. The alternative of discarding what seem to be unused symbols only results in linker error of the obscure edge cases sort. Template emission strategy is a mess, we're better off just instantiating all templates in all compilation units, and let the compiler decide whatever to discard. Even -allinst does not instantiate enough to allow the compiler to make such decisions that C++ has no problem with (most of the time). I think I've hit a variation of this problem before, where pulling in a single selective import in Phobos somewhere meant the entire module was compiled into the executable (though I suppose that could be a linker issue?): https://forum.dlang.org/thread/gmjqfjoemwtvgqrtd...@forum.dlang.org I guess this is why scoped/selective imports didn't help that much in disentangling Phobos. I figured it wasn't a big deal if it was just causing bigger executables, but even though I mentioned compilation speed there, I didn't think of how that's slowing down the compiler too, as you now note. Pruning what's evaluated by the compiler based on scoped/selective imports, rather than apparently including the whole module, and getting D compilers to compile parallelized without separately invoking each module/package, ie a -j flag for the compiler when you invoke it with all your source at once, might be good projects for us to crowdfund, as discussed in this and my earlier Nim thread. Separate parallel compilation works wonders on my octa-core Android/AArch64 phone, where I mostly build D now, would be good to be able to combine that with invoking ldc with all source at once.
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tue, Aug 28, 2018 at 08:18:57AM +, Eugene Wissner via Digitalmars-d wrote: [...] > There are still valid use cases where const should be "broken". One of > them is mutex (another one caching). I have very little experiance in > multi-threaded programming, but what do you think about "mutable" > members, despite the object is const? The problem with compromising const is that it would invalidate any guarantees const may have provided. Const in D is not the same as const in languages like C++; const in D means *physical* const, as in, the data might reside in ROM where it's physically impossible to modify. Allowing the user to bypass this means UB if the data exists in ROM. Plus, the whole point of const in D is that it is machine-verifiable, i.e., the compiler checks that the code does not break const in any way and therefore you are guaranteed (barring compiler bugs) that the data does not change. If const were not machine-verifiable, it would be nothing more than programming by convention, since it would guarantee nothing. Allowing const to be "broken" somewhere would mean it's no longer machine-verifiable (you need a human to verify whether the semantics are still correct). Many of D's const woes can actually be solved if we had a language-supported way of declaring the equivalence between const(U!T) and U!(const(T)), AKA head-mutable. The language already supports a (very) limited set of such conversions, e.g., const(T*) is assignable to const(T)*, because you're just making a copy of the pointer, but the target is still unchangeable. However, because there is no way to specify such a conversion in a user-defined type, that means things like RefCounted, or caches, or mutexes, cannot be made to work without either ugly workarounds or treading into UB territory by casting away const. But if there is a way for a user-defined template U to define a conversion from const(U!T) to U!(const(T)) (the conversion code, of course, would have to be const-correct and verifiable by the compiler), then we could make it so that U!(const(T)) contained a mutable portion (e.g., the refcount, mutex, cache, etc.) and an immutable portion (the reference to the const object). T -- In order to understand recursion you must first understand recursion.
[Issue 19201] New: Error: func called with argument types (ulong) matches both: __c_long and __c_ulong
https://issues.dlang.org/show_bug.cgi?id=19201 Issue ID: 19201 Summary: Error: func called with argument types (ulong) matches both: __c_long and __c_ulong Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: blocker Priority: P1 Component: dmd Assignee: nob...@puremagic.com Reporter: ibuc...@gdcproject.org Bootstrap builds with gdc are broken in master. Minimal version without dependencies. --- enum __c_long : long; enum __c_ulong : ulong; void a(ulong r){} void a(long r){} void b(__c_long r){} void b(__c_ulong r){} void main() { a(0L); b(0L); } --- Minimal version with dependencies. --- import core.stdc.stdint; void a(ulong r){} void a(long r){} void b(uint64_t r){} void b(int64_t r){} void main() { a(0L); b(0L); } --- Places in dmd that don't compile as a result: https://github.com/dlang/dmd/blob/05cdf2f55c9d6379e300382ab7af77837c6f4155/src/dmd/dcast.d#L377 https://github.com/dlang/dmd/blob/05cdf2f55c9d6379e300382ab7af77837c6f4155/src/dmd/dcast.d#L381 https://github.com/dlang/dmd/blob/05cdf2f55c9d6379e300382ab7af77837c6f4155/src/dmd/expressionsem.d#L9319 https://github.com/dlang/dmd/blob/05cdf2f55c9d6379e300382ab7af77837c6f4155/src/dmd/optimize.d#L938 The longdouble type has overrides for intXX_t and uintXX_t to be ABI compatible with C++. --
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Mon, Aug 27, 2018 at 06:11:14PM -0700, Walter Bright via Digitalmars-d wrote: > On 8/27/2018 10:08 AM, H. S. Teoh wrote: > > Const in D makes sense as-is. Though, granted, its infectiousness means > > its scope is actually very narrow, and as a result, we ironically > > can't use it in very many places, and so its touted benefits only > > rarely apply. :-( Which also means that it's taking up a lot of > > language design real estate with not many benefits to show for it. > > D const is of great utility if you're interested in functional > programming. Using it has forced me to rethink how I separate tasks > into functions, and the result is for the better. > > I agree that D const has little utility if you try to program in C++ > style. I am very interested in functional programming, yet ironically, one of D's top functional programming selling points, ranged-based programming, interacts badly with const. Just ask Jonathan about using ranges with const, and you'll see what I mean. :-) The very design of ranges in D requires that the range be mutable. However, because const is infectious, this makes it a royal pain to use in practice. Take, for example, a user-defined container type, let's call it L. For argument's sake, let's say it's a linked list. And let's say the list elements are reference-counted -- we'll write that as RefCounted!Elem even though this argument isn't specific to the current Phobos implementation of RefCounted. As experience has shown in the past, it's usually a good idea to separate the container from the range that iterates over it, so an obvious API choice would be to define, say, an .opSlice method for L that returns a range over its elements. Now, logically speaking, iterating over L shouldn't modify it, so it would make sense that .opSlice should be const. So we have: struct L { private RefCounted!Elem head, tail; auto opSlice() const { ... } } The returned range, however, must be mutable, since otherwise you couldn't use .popFront to iterate over it (and correspondingly, Phobos isInputRange would evaluate to false). But here's the problem: because opSlice is declared const, that means `this` is also const, which means this.head and this.tail are also const. But since this.head is const, that means you couldn't do this: auto opSlice() const { struct Result { RefCounted!(const(Elem)) current; ... // rest of range API void popFront() { current = current.next; // Error: cannot assign const(RefCounted!Elem) to RefCounted!(const(Elem)) } } return Result(head); // <-- Error: cannot assign const(RefCounted!Elem) to RefCounted!(const(Elem)) } This would have worked had we used pointers instead, because the compiler knows that it's OK to assign const(Elem*) to const(Elem)*. However, in this case, the compiler has no way of knowing that it is safe to assign const(RefCounted!Elem) to RefCounted!(const(Elem)). Indeed, they are different types, and the language currently has no way of declaring the head-mutable construct required here. This is only the tip of the iceberg, of course. If you then try to add a method to RefCounted to make it convert const(RefCounted!T) to RefCounted!(const(T)), then you'll be led down a rabbit hole of further problems with const (e.g., how to implement ref-counting with const objects in a way that doesn't violate the type system) until you reach the point where it's impossible to proceed without casting away const somehow. Unfortunately, the spec says that's Undefined Behaviour. So you're on your own. This is just one example among many, that const is hard to use in the general case. It works fairly well for a narrow number of cases, such as for built-in types, but once you start generalizing your code, you'll find brick walls in undesired places, the workarounds for which require so much effort as to offset any benefits that const may have brought. TL;DR: const is beautiful in theory, but hard to use in practice. So hard that it's often not worth the trouble, despite the benefits that it undoubtedly does provide. P.S. If D had the concept of head-mutable, a lot of this pain (though not all) would have been alleviated. T -- "I'm running Windows '98." "Yes." "My computer isn't working now." "Yes, you already said that." -- User-Friendly
Re: D support for ChromeOS
On Tuesday, 28 August 2018 at 12:34:50 UTC, Martin Tschierschke wrote: On Wednesday, 22 August 2018 at 10:28:32 UTC, Joakim wrote: https://play.google.com/store/apps/details?id=com.termux=en $ apt search ldc Sorting... Done Full Text Search... Done ipcalc/stable 0.41 aarch64 Calculates IP broadcast, network, Cisco wildcard mask, and host ranges ldc/stable 1.11.0 aarch64 D programming language compiler, built with LLVM http://termux.net/dists/stable/main/binary-aarch64/ You should post it, as an extra topic on announce: D on Android with Termux LDC now 32 and 64 Bit! ... Thank you - it works! I did, though not as a new topic: https://forum.dlang.org/post/zgjzldisifhkgcgxk...@forum.dlang.org I'm updating the wiki on how to use it and getting rid of the main function requirement, then I'll write up a post for Mike on the D blog.
Re: std.encoding:2554 - Unrecognized Encoding: big5 - Please help!
On Tuesday, 28 August 2018 at 13:38:39 UTC, spikespaz wrote: The problem arises when he types "google.com.hk/search?q={{query}}" (exact string) AFAIK, google has a parameter to output results in utf8.
Weird (buggy) behaviour of "protected static" in classes
Hi all, I have noticed that "protected static" doesn't work currently with classes. In my case, I wanted to use "static immutable", but I have tried regular static members and methods, and the same issue happens. However, the puzzling part is that protected enums (which are a valid workaround for me, perhaps not for others) work. The spec [1] is a bit unclear about how that's supposed to work, although I tend to thing that it allows them: --- protected only applies inside classes (and templates as they can be mixed in) and means that a symbol can only be seen by members of the same module, or by a derived class. If accessing a protected instance member through a derived class member function, that member can only be accessed for the object instance which can be implicitly cast to the same type as ‘this’. protected module members are illegal. --- Is that a bug? I have to say, I think so, since it can also affect other symbols that are defined... for *grandchild* classes! You can see the multiple problems in the snippet [1]: ```dio.d module dio; public class A { public enum int a = 1; protected enum int b = 2; private enum int c = 3; public static immutable int d = 4; protected static immutable int e = 5; private static immutable int f = 6; protected static struct S { } } public class A2 { protected static struct S { } } ``` ```main.d import dio; class B : A { pragma(msg, "The value of A.a is: ", typeof(super).a); pragma(msg, "The value of A.b is: ", typeof(super).b); //pragma(msg, "The value of A.c is: ", typeof(super).c); // Expected failure pragma(msg, "The value of A.d is: ", typeof(super).d); pragma(msg, "The value of A.e is: ", typeof(super).e); // *BUG* Comment this line and *BOTH* errors will go away!! //pragma(msg, "The value of A.f is: ", typeof(super).f); // Expected failure S s; } class C : B { S s; } class B2 : A2 { S s; } class C2 : B2 { S s; } void main() { } ``` The most shocking thing is that it is C's access to A.S that gets affected, I think that must be a compiler bug. Still, it would be nice to confirm that "protected static" is supposed to work as intuitively expected. Best, A. [1]: https://glot.io/snippets/f4a1b3x4sf
Re: std.encoding:2554 - Unrecognized Encoding: big5 - Please help!
We have a reasonably number (but quiet) Chinese user base, we should really support big5 and its extensions out-right.
Re: std.encoding:2554 - Unrecognized Encoding: big5 - Please help!
On 8/28/18 9:38 AM, spikespaz wrote: I have a user who submitted a bug report for one of my projects. The error is in std\encoding.d on line 2554. The problem arises when he types "google.com.hk/search?q={{query}}" (exact string) into this function: https://github.com/spikespaz/search-deflector/blob/master/source/setup.d#L253-L278 Here is the issue on GH: https://github.com/spikespaz/search-deflector/issues/12 I really can't figure this one out and any help would be appreciated. Thanks. The answer is: the encoding "big5" isn't supported by std.encoding. You can add a new subclass and register it, to handle the encoding. Maybe this article can help you write one: https://en.wikipedia.org/wiki/Big5 You want to subclass EncodingScheme. See instructions at the top of https://dlang.org/phobos/std_encoding.html -Steve
Re: std.encoding:2554 - Unrecognized Encoding: big5 - Please help!
https://github.com/dlang/phobos/blob/master/std/net/curl.d#L1197 get!ubyte will disable encoding.
Re: Create constraint for each parameter in template arg pack
On Tuesday, 28 August 2018 at 13:05:15 UTC, bauss wrote: I'm not sure if there is a better way, but isInstanceOf (std.traits) seems to work with a static foreach and a static if. template Qwerty(Values...) { static foreach (value; Values) { static if (!isInstanceOf!(Qaz, value)) { static assert(0, "Values are not Qaz only ..."); } } // ... } Thank you everybody!
Re: std.encoding:2554 - Unrecognized Encoding: big5 - Please help!
On Tuesday, 28 August 2018 at 13:38:39 UTC, spikespaz wrote: I have a user who submitted a bug report for one of my projects. The error is in std\encoding.d on line 2554. The problem arises when he types "google.com.hk/search?q={{query}}" (exact string) into this function: https://github.com/spikespaz/search-deflector/blob/master/source/setup.d#L253-L278 Here is the issue on GH: https://github.com/spikespaz/search-deflector/issues/12 I really can't figure this one out and any help would be appreciated. Thanks. To add to the parent, I've recompiled with debugging and this is the full traceback. As I suspected, it's an error with curl: 0x7FF77A162F4D in std.encoding.EncodingScheme std.encoding.EncodingScheme.create(immutable(char)[]) 0x7FF77A14300A in std.net.curl._decodeContent!char._decodeContent at C:\D\ldc2\import\std\net\curl.d(1213) 0x7FF77A143610 in std.net.curl._basicHTTP!char._basicHTTP at C:\Users\spike\Documents\github.com\spikespaz\search-deflector\source\common.d(1078) 0x7FF77A142C97 in std.net.curl.get!(std.net.curl.HTTP, char).get at C:\Users\spike\Documents\github.com\spikespaz\search-deflector\source\common.d(562) 0x7FF77A1411E0 in std.net.curl.get!(std.net.curl.AutoProtocol, char).get at C:\D\ldc2\import\std\net\curl.d(574) 0x7FF77A146635 in setup.getCustomEngine at C:\Users\spike\Documents\github.com\spikespaz\search-deflector\source\setup.d(264) 0x7FF77A145C8E in setup.setup at C:\Users\spike\Documents\github.com\spikespaz\search-deflector\source\setup.d(44) 0x7FF77A145AD0 in D main at C:\Users\spike\Documents\github.com\spikespaz\search-deflector\source\setup.d(26) 0x7FF77A1AAD8D in void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll() 0x7FF77A1AAC3A in d_run_main 0x7FF77A1C9658 in __scrt_common_main_seh at f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl(283) 0x7FFEC50687E4 in BaseThreadInitThunk 0x7FFEC701B311 in RtlUserThreadStart
Re: std.encoding:2554 - Unrecognized Encoding: big5 - Please help!
import std.stdio : stdout, writeln; writeln(__MODULE__, ":", __LINE__); stdout.flush; Trace it that way. The flush is important.
std.encoding:2554 - Unrecognized Encoding: big5 - Please help!
I have a user who submitted a bug report for one of my projects. The error is in std\encoding.d on line 2554. The problem arises when he types "google.com.hk/search?q={{query}}" (exact string) into this function: https://github.com/spikespaz/search-deflector/blob/master/source/setup.d#L253-L278 Here is the issue on GH: https://github.com/spikespaz/search-deflector/issues/12 I really can't figure this one out and any help would be appreciated. Thanks.
Re: D is dead (was: Dicebot on leaving D: It is anarchy driven development in all its glory.)
On Thursday, 23 August 2018 at 15:35:45 UTC, Joakim wrote: On Thursday, 23 August 2018 at 07:37:07 UTC, Iain Buclaw wrote: On Thursday, 23 August 2018 at 06:58:13 UTC, Joakim wrote: On Thursday, 23 August 2018 at 03:50:44 UTC, Shachar Shemesh wrote: [...] Can you list what you or other Weka devs believe those fatal flaws to be? Because you've not listed any here, which makes you no better than some noob that comes in here, says D has to get better or it will die, then can't articulate what they mean by "better" or worse, mentions something trivial. Of course, you've actually used the language for years, so presumably you've got some real concerns, but do you really think the bug you just posted is "fatal" to the language? If you think there are fatal flaws, you might as well list them, whether technical or the development process, or you will just be ignored like any other noob who talks big and can't back it up. You may be ignored anyway, ;) but at least you'll have made a case that shows you know what you're talking about. I'd define fatal as some that can be fixed, but breaks 100% of everyone's code, even if the change is net positive all round. However how big a problem really is is in the eye of the beholder. An example: Symptom: The compiler can't discard unused symbols at compile time, and so it will spend a lot of time pointlessly optimising code. Problem: D has no notion of symbol visibility. Possible Solution: Make all globals hidden by default unless 'export'. Side effects: Everyone will be spending weeks to months fixing their libraries in order to only mark what should be visible outside the current compilation unit as 'export'. Benefits: Faster compile times, as in, in the most extreme example I've built one project on github with gdc -O2 and build time went from 120 seconds to just 3! So your example of a fatal flaw is that D could be 100X faster at compilation instead of just 10X than most every other native language out there?! C'mon. But that's not true. D isn't a fast language to compile, dmd is just a fast compiler. You may get a little leading edge with codebases that are effectively C. Once you throw templates into the mix though, your problems become exponential. Spending 4 seconds in the front end and codegen, only to wait 2 minutes in the optimizer is horrific. The alternative of discarding what seem to be unused symbols only results in linker error of the obscure edge cases sort. Template emission strategy is a mess, we're better off just instantiating all templates in all compilation units, and let the compiler decide whatever to discard. Even -allinst does not instantiate enough to allow the compiler to make such decisions that C++ has no problem with (most of the time).
Re: Null-Coalescing Operator and Extensions
On Monday, 27 August 2018 at 14:59:20 UTC, SG wrote: On Monday, 27 August 2018 at 07:59:17 UTC, Simen Kjærås wrote: That's the null propagation operator (?.). What SG asked for is the null-coalescing operator (??). Of course, this can also be implemented in D (albeit with a slight more horrible syntax): Exactly, and I know it is an example, but it doesn't work for Variant. I was trying something like below, I need to find a way to test for all Nullable types out there, right now only works for Nullable!int. Sadly, Variant's operator overloading is problematic - there seems to be no way to write a struct such that its operator overloading is preferred over Variant's, and Variant's fails to compile. (issue 19200: https://issues.dlang.org/show_bug.cgi?id=19200) Once that issue has been fixed, this should work: // Support aliak's optional, if available: static if (__traits(compiles, {import optional;})) import optional; struct NullCoalesce { static auto opBinaryRight(string op : "|", T)(T lhs) { return NullCoalesceImpl!T(lhs); } } struct NullCoalesceImpl(T) { T value; auto opBinary(string op : "|", R)(lazy R rhs) { static if (is(typeof(value.peek!R))) { if (auto tmp = value.peek!R) return *tmp; } else static if (is(typeof(value.isNull))) { if (!value.isNull) return value.get; } else static if (is(typeof(value.unwrap))) { if (auto tmp = value.unwrap) return *tmp; } else static if (is(typeof(value == null))) { if (value != null) return value; } else { static assert(false, "Cannot perform null-coalescing on non-nullable type "~T.stringof~"."); } return rhs; } } alias NullCoalesce _; unittest { import std.variant; import std.typecons; int* a = null; auto b = new int; assert((a |_| b) == b); a = new int; assert((a |_| b) == a); Variant c; assert((c |_| 3) == 3); c = 4; assert((c |_| 3) == 4); Nullable!int d; assert((d |_| 3) == 3); d = 4; assert((d |_| 3) == 4); static if (is(typeof(Optional!int))) { Optional!int e; assert((e |_| 3) == 3); e = 4; assert((e |_| 3) == 4); } } Now, as has been pointed out, that only work for null-coalescing, not null-propagation. It seems writers of Optional, Variant, SumType, and so on, have decided not to support this out of the box, but rather wrap it separately, like Basile B.'s SafeAccess[1] and aliak's dispatch[2]. There's no real obstacle to wrapping member access directly in Optional!T such that it always return a Optional!(typeof(member)), though. I've written an Optional somewhere that does safe access out of the box, but it seems to be on my work computer, not this one. -- Simen [1]: https://github.com/BBasile/iz/blob/master/import/iz/sugar.d#L1658 [2]: https://code.dlang.org/packages/optional
Re: Create constraint for each parameter in template arg pack
On Tuesday, 28 August 2018 at 12:28:19 UTC, Andrey wrote: Hello, Let we have two variadic templates: template Qwerty(Values...) {} template Qaz(alias type, Data...) {} Now I want to add a constraint to "Qwerty" so that each type in "Values" pack must be a "Qaz" template. I don't care about values of "type" or "Data" in "Qaz". How to do it in D? Generic solution: template Qwerty(Values...) if(allSatisfy!(isInstanceOf!Qaz, Values)){ } class Qaz(alias type, Data...) {} import std.meta : allSatisfy; public import std.traits : isInstanceOf; template isInstanceOf(alias T){ import std.traits : impl = isInstanceOf; static enum isInstanceOf(alias X) = impl!(T, X); static enum isInstanceOf(X) = impl!(T, X); }
Re: Is @safe still a work-in-progress?
On 8/24/18 10:25 PM, Walter Bright wrote: On 8/23/2018 6:32 AM, Steven Schveighoffer wrote: Furthermore any member function (or UFCS function for that matter) REQUIRES the first parameter to be the aggregate. How do you make a member function that stuffs the return into a different parameter properly typecheck? What I propose is that the function interface be refactored so it does fit into these patterns. Is that an unreasonable requirement? I don't know. But it doesn't seem to be, as I haven't run into it yet. So this would mean a member function would have to be refactored into a different function with a different calling syntax. i.e: x.foo(target); would have to be refactored to: target.foo(x); or foo(target, x); Aside from the adjustment in name that is necessary to make this read correctly, that may cause other problems (sometimes non-member functions aren't available if it's a template instantiation). Phobos doesn't do this by accident. It's how constructors work (see above) and how pipeline programming works. Constructors I agree are reasonable to consider `this` to be the return value. On that point, I would say we should definitely go ahead with making that rule, and I think it will lead to no confusion whatsoever. pipeline programming depends on returning something other than `void`, so I don't see how this applies. grep Phobos for instances of put() and see its signature. It's part of pipeline programming, and it's all over the place. I stand partly corrected! Indeed you can put a void-returning function at the *end* of a pipeline call, I hadn't thought of that. But in terms of put, strictly speaking, any call of some.pipeline.put(x) is wrong. It should be put(some.pipeline, x), to avoid issues with how put was designed. It would restrict your legitimate calls. Maybe that's a good thing. Having multiple simultaneous routes of data out of a function is not good practice (note that it is impossible with functional programming). If you absolutely must have it, the exit routes can be aggregated into a struct, then pass that struct as the first argument. Maybe it's better to designate one sink, and have that be the result. I know that after inout was implemented, there were definitely cases where one wanted to have multiple inout routes (i.e. independent traces between multiple parameters for copying mutability). It may be the same for this, I don't know. I want to stress that it may be a valid solution, but we should strive to prove the solutions are the best possible rather than just use duct-tape methodology. I don't know how to prove anything with programming languages. I don't mean prove like mathematical proof. I mean try to consider how this affects all cases instead of just the one case that will make phobos compile. "show" is a better verb than "prove". It should even be considered that perhaps there are better solutions even than the approach dip1000 has taken. People have hypothesized that for several years, and so far none have been forthcoming beyond a few hand-wavy generalities. I'm just saying if dip1000 cannot fix all the problems, that instead of adding weird exceptions, or the classic "you're just doing it wrong", maybe we should reconsider the approach. Another case which was brought up and pretty much ignored was this one: https://forum.dlang.org/post/qkrdpmdqaxjadgvso...@forum.dlang.org I also want to point out that the attitude of 'we could just fix it, but nobody will pull my request' is unhelpful. We want to make sure we have the best solution possible, don't take criticism as meaningless petty bickering. People are genuinely trying to make sure D is improved. Hostility towards reviews or debate doesn't foster that. I'm not hostile to debate. I just don't care for "this is uncharted territory, so let's do nothing" which has been going on for probably 4 years now, coincident with "scope is incomplete, D sux". I.e. lead, follow, or get out of the way :-) I'm opting for the latter, as the idea of band-aid PRs to get Phobos compiling with dip1000 just to see if dip1000 is going to work seems like the wrong approach to me. The consequence of this is that getting out of the way means your PRs don't get pulled. -Steve
Re: C++ Expected converted to idiomatic D
On Tuesday, 28 August 2018 at 10:18:29 UTC, John Colvin wrote: I get the feeling from the talk that Andrei has some opinions about how it should be done that aren't completely in line with what has been proposed for the C++ standard. Anyhow my implementation at https://github.com/nordlow/phobos-next/blob/master/src/expected.d should match his C++ code in the lecture, AFAICT. My code doesn't depend on other modules an compiles very fast (~46 ms in my machine) (with DMD -debug -unittest).
Re: Create constraint for each parameter in template arg pack
On Tuesday, 28 August 2018 at 13:05:15 UTC, bauss wrote: On Tuesday, 28 August 2018 at 12:28:19 UTC, Andrey wrote: Hello, Let we have two variadic templates: template Qwerty(Values...) {} template Qaz(alias type, Data...) {} Now I want to add a constraint to "Qwerty" so that each type in "Values" pack must be a "Qaz" template. I don't care about values of "type" or "Data" in "Qaz". How to do it in D? I'm not sure if there is a better way, but isInstanceOf (std.traits) seems to work with a static foreach and a static if. template Qwerty(Values...) { static foreach (value; Values) { static if (!isInstanceOf!(Qaz, value)) { static assert(0, "Values are not Qaz only ..."); } } // ... } https://dlang.org/phobos/std_traits.html#TemplateOf maybe...
Re: D is dead
On Thursday, 23 August 2018 at 09:29:30 UTC, Nicholas Wilson wrote: On Thursday, 23 August 2018 at 07:00:01 UTC, Iain Buclaw wrote: On Thursday, 23 August 2018 at 06:34:04 UTC, Shachar Shemesh wrote: On 23/08/18 09:17, Jacob Carlborg wrote: I don't see why we just can't add support for scoped lazy parameters. It's already in the language just with a different syntax (delegates). That would probably be an easy fix (last famous words :)). I guess it would be better if it could be inferred. Here's the interesting question, though: is this *going* to happen? We've known about this problem for ages now. No movement. It's on my todo list, however I've instead been doomed to work on higher priority things. More generally though, some time should be spent on trying out things in the spirit of "will it blend" just to see what happens. Putting effort towards having a more homogeneous environment in the language should in the long run pay its dividends. Is there even any way to escape a lazy? If no, then lazy is identical to scope lazy. E.g. https://run.dlang.io/is fails to compile Link not found. I assume you tried something like returning a delegate that references a lazy parameter?
Re: Create constraint for each parameter in template arg pack
On Tuesday, 28 August 2018 at 12:28:19 UTC, Andrey wrote: Hello, Let we have two variadic templates: template Qwerty(Values...) {} template Qaz(alias type, Data...) {} Now I want to add a constraint to "Qwerty" so that each type in "Values" pack must be a "Qaz" template. I don't care about values of "type" or "Data" in "Qaz". How to do it in D? I'm not sure if there is a better way, but isInstanceOf (std.traits) seems to work with a static foreach and a static if. template Qwerty(Values...) { static foreach (value; Values) { static if (!isInstanceOf!(Qaz, value)) { static assert(0, "Values are not Qaz only ..."); } } // ... }
Re: Create constraint for each parameter in template arg pack
On Tuesday, 28 August 2018 at 12:28:19 UTC, Andrey wrote: Hello, Let we have two variadic templates: template Qwerty(Values...) {} template Qaz(alias type, Data...) {} Now I want to add a constraint to "Qwerty" so that each type in "Values" pack must be a "Qaz" template. I don't care about values of "type" or "Data" in "Qaz". How to do it in D? import std.meta : allSatisfy; template Qwerty(Values...) if(allSatisfy!(isQaz, Values)){ } template Qaz(alias type, Data...) {} enum isQaz(alias Q : Qaz!Args, Args...) = true; enum isQaz(Args...) = false; alias Foo = Qwerty!(Qaz!(i => i), Qaz!(i => i), Qaz!(i => i));
[Issue 19200] New: Variant operators don't overload correctly
https://issues.dlang.org/show_bug.cgi?id=19200 Issue ID: 19200 Summary: Variant operators don't overload correctly Product: D Version: D2 Hardware: x86 OS: Windows Status: NEW Severity: normal Priority: P1 Component: phobos Assignee: nob...@puremagic.com Reporter: simen.kja...@gmail.com There are issues when using Variant with types that have their own overloaded operators: struct S { static int opBinaryRight(string op : "|", T)(T rhs) { return 3; } } unittest { import std.variant; S s; Variant v; auto b = v | s; } std\variant.d(1004): Error: no property min for type S In addition, Variant's operator overloads are of the old kind (opAdd, opMul, and so on). These should be updated anyway. --
Re: Is @safe still a work-in-progress?
On 8/24/18 10:28 PM, Walter Bright wrote: On 8/23/2018 8:14 AM, Steven Schveighoffer wrote: If I had to design a specific way to allow the common case to be easy, but still provide a mechanism for the uncommon cases, I would say: 1. define a compiler-recognized attribute (e.g. @__sink). 2. If @__sink is applied to any parameter, that is effectively the return value. 3. In the absence of a @__sink designation on non-void-returning functions, it applies to the return value. 4. In the absence of a @__sink designation on void returning functions, it applies to the first parameter. 5. Inference of @__sink happens even on non-templates. 6. If @__sink is attributed on multiple parameters, you assume all return parameters are assigned to all @__sink parameters for the purposes of verifying lifetimes are not exceeded. 'ref' is already @__sink. No, otherwise we wouldn't need the patch you are pushing. -Steve
Re: Pass Socket to new thread
Thanks for all your answers. I'll have a look at the design and use casting if necessary.
Re: D support for ChromeOS
On Wednesday, 22 August 2018 at 10:28:32 UTC, Joakim wrote: https://play.google.com/store/apps/details?id=com.termux=en $ apt search ldc Sorting... Done Full Text Search... Done ipcalc/stable 0.41 aarch64 Calculates IP broadcast, network, Cisco wildcard mask, and host ranges ldc/stable 1.11.0 aarch64 D programming language compiler, built with LLVM http://termux.net/dists/stable/main/binary-aarch64/ You should post it, as an extra topic on announce: D on Android with Termux LDC now 32 and 64 Bit! ... Thank you - it works!
Create constraint for each parameter in template arg pack
Hello, Let we have two variadic templates: template Qwerty(Values...) {} template Qaz(alias type, Data...) {} Now I want to add a constraint to "Qwerty" so that each type in "Values" pack must be a "Qaz" template. I don't care about values of "type" or "Data" in "Qaz". How to do it in D?
Re: Solving the impossible?
On Sunday, 26 August 2018 at 02:26:58 UTC, Everlast wrote: in fact, I'd rather see void print(T)(T t, int... a) You were actually close. void print(T)(T t, int[] a ...);
Re: Pass Socket to new thread
On Tuesday, 28 August 2018 at 10:48:20 UTC, Ivo wrote: I'm writing a basic server program and I want to handle each connection received in a new thread. So here is the code I'm trying to produce: while(true) { auto client = socket.accept(); spawn( , client); } void handleConnection(Socket client) { //do stuff like receive and send } I get the error that I cannot pass "client" to "spawn" since it is not a "shared" or "immutable" object. So I need to create an "immutable" (or "shared") copy of the socket in order to pass it to the "handleConnection" function. However doing so would prevent me from sending/receiving data. That is "client.receive" and "client.send" do not work if "client" is "shared" or "immutable". Any suggestions to solve my problem? Thanks. What you should do instead is using a non-blocking socket in a single thread and only if necessary use a thread-pool design to split multiple sockets into multiple threads, but each thread should still be shared by multiple sockets. Using fibers can help you do that without reinventing the wheel. Usually it's __never__ a good idea to spawn a thread per connection. In fact it'll only come with synchronization issues in the end and then you end up putting mutexes everywhere, which is just going to put your performance downhill. Especially with sockets and threading you want the design to be correct from the beginning, because once your application starts to depend on your design, then it's going to be hard to re-implement or replace the current system to do it the "right way".
Re: Pass Socket to new thread
while(true) { auto client = socket.accept(); spawn(, cast(shared)client); } void handleConnection(shared Socket sclient) { Socket client=cast()sclient; //do stuff like receive and send }
Re: "The D Way" to run a sequence of executables?
Maybe http://libpipeline.nongnu.org/ can be an inspiration.
Re: D now has a dangerous competitor
On Tuesday, 28 August 2018 at 08:39:20 UTC, bauss wrote: The following language is a dangerous competitor to D. https://github.com/joaomilho/Enterprise I often feel like this kind of 'jokes' are trying too hard. FizzBuzz Enterprise was fun when it first came out, and I know it's popular to hate on OOP programming, especially Java. But the fact is, a very big portion of software was built using OOP, and many of the hated design patterns have a place in programming. Sure, it doesn't provide witty one-liner quicksort examples, but when you have a group of people, having to integrate multiple webservices/databases, these kind of layered code architecture comes in handy. Of course sometimes people go too far, trying to make the code generic and fit every usecase, breaking YAGNI.
Pass Socket to new thread
I'm writing a basic server program and I want to handle each connection received in a new thread. So here is the code I'm trying to produce: while(true) { auto client = socket.accept(); spawn( , client); } void handleConnection(Socket client) { //do stuff like receive and send } I get the error that I cannot pass "client" to "spawn" since it is not a "shared" or "immutable" object. So I need to create an "immutable" (or "shared") copy of the socket in order to pass it to the "handleConnection" function. However doing so would prevent me from sending/receiving data. That is "client.receive" and "client.send" do not work if "client" is "shared" or "immutable". Any suggestions to solve my problem? Thanks.
Re: C++ Expected converted to idiomatic D
On Thursday, 16 August 2018 at 20:37:33 UTC, Per Nordlöw wrote: In https://www.youtube.com/watch?v=nVzgkepAg5Y Andrei describes his proposal for STL `Expected` planned to be included in C++20. Have anybody converted the C++ proposal to idiomatic D, yet? Hopefully without the pointer-legacy which unfortunately was allowed into `std:optional`. Andrei claims we should it as return types for non-throwing variants of parse() and to() in the works at https://github.com/dlang/phobos/pull/6665 I get the feeling from the talk that Andrei has some opinions about how it should be done that aren't completely in line with what has been proposed for the C++ standard.
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tuesday, 28 August 2018 at 08:44:26 UTC, Chris wrote: Last but not least, if it's true that the D Foundation has raised only 3.2K, then there's something seriously wrong. The Foundation has significantly more than 3.2k. The Open Collective account is relatively new and is but one option. People also donate via PayPal and other means [1], with several monthly contributors. The Foundation is paying two full-time developers, pays me for part-time work, pays out bounties for guest posts on the D Blog, pays out bounties for specific coding tasks, contributes to the funding of DConf, and more. Soon there will be more fundraising drives for targeted initiatives, like the test drive we did with the VS Code plugin, to make up for the lack of donations of time. Some of them will be for paying people to fix onerous issues in Bugzilla. It's a long-term project for me. [1] https://dlang.org/foundation/donate.html
Re: D is dead
On 8/27/2018 7:02 AM, Don wrote: I can explain this, since I did the original implementation. [...] Thank you, Don. And you do have my mad respect for figuring out Windows SEH.
Re: D now has a dangerous competitor
On Tuesday, 28 August 2018 at 08:39:20 UTC, bauss wrote: The following language is a dangerous competitor to D. https://github.com/joaomilho/Enterprise Thats very funny, but I found Rockstar even funnier.
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tuesday, 28 August 2018 at 08:44:26 UTC, Chris wrote: When people choose a programming language, there are several boxes that have to be ticked, like for example: - what's the future of language X? (guarantees, stability) - how easy is it to get going (from "Hello world" to a complete tool chain) - will it run on ARM? - will it be a good choice for the Web (e.g. webasm)? - how good is it at data processing / number grinding - etc. I don't know if all their claims are 100% true, but let that sink in for a while: https://julialang.org/.
Re: GDC with D frontend 2.081.2
On Tue, Aug 28, 2018 at 8:40 AM Eugene Wissner via Digitalmars-d-announce < digitalmars-d-announce@puremagic.com> wrote: > On Tuesday, 28 August 2018 at 06:18:28 UTC, Daniel Kozak wrote: > > On Mon, Aug 27, 2018 at 7:55 PM Eugene Wissner via > > Digitalmars-d-announce < digitalmars-d-announce@puremagic.com> > > wrote: > > > >> On Monday, 27 August 2018 at 17:23:04 UTC, Arun Chandrasekaran > >> wrote: > >> > 1. It would be good to print the DMD frontend version with > >> > `gdc --version`. It is helpful in reporting bugs. LDC does > >> > this. > >> > > >> Unfortunately it doesn't seem to be possible. GCC doesn't > >> allow to change --version output: > >> https://bugzilla.gdcproject.org/show_bug.cgi?id=89 > >> > >> > > This is not true, right now on archlinux if you type gdc > > --version it will display d frontend version > > https://bugzilla.gdcproject.org/show_bug.cgi?id=89#c1 > > Is it set with --with-pkgversion? The same information will be > displayed for gcc and g++ then. It is not always desirable if you > ship the compiler as a whole (with libtool etc). > Yes and no. It is set with --with-pkgversion but it is only for gdc.
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tuesday, 28 August 2018 at 07:30:01 UTC, Walter Bright wrote: On 8/27/2018 2:14 AM, Chris wrote: bad feeling about the way things are going atm. I can quote you a lng list of problems that are obvious only in hindsight, by world leading development teams. Start by watching the documentary series "Aviation Disasters", look at Challenger, Deepwater Horizon, Fukushima, Apollo 1, Apollo 13, the World Trade Centers, etc. Of course, there are a number of them in C, C++, Java, Javascript, basically every language I've worked with. I'll guarantee every non-trivial project you've worked on has problems that are obvious only in hindsight, too. If you wait till it's perfect, you'll never ship, and yet it'll *still* have problems. I'm not making excuses for mistakes - just don't have unworkable requirements. This is all good and well and I know that anyone who develops software shoots him/herself in the foot sooner or later. But this is not the same situation. If you have to ship something till date X, then you are under pressure and naturally make mistakes that are obvious only on hindsight. But D is not under pressure to include new features so frequently. There's absolutely no reason to rush into something that eats up a lot of your time (better spent on more urgent problems) and by so doing produce possible breakages. The end of the day is, does D get the job done for you better than other languages? That's a decision only you can make. It has done a better job until recently. The problem are not things like @safe, `const` and whatnot, the problem are very practical issues such as fear of breakage / time spent fixing things and running the code on ARM, integration into other technologies (webasm). Since the D Foundation was founded I really thought that part of the effort would go into stabilizing the language and developing better tools for various aspects of programming (not just language features). Programming is so much more than just language features, and languages that offer the "so much more" part are usually the ones people adopt. But somehow D still seems to be in its hobby hacker days. Features are first and foremost, everything else comes second. But features get "ripped" by other programming languages and they can pick and choose, because they know what really worked in D, while D has to struggle with the things that didn't work or only half worked. Laeeth was talking about being analytical about the whole thing. Why not find out what features are really being used? I.e. does the majority really need - for practical purposes - partially constructed objects? When people choose a programming language, there are several boxes that have to be ticked, like for example: - what's the future of language X? (guarantees, stability) - how easy is it to get going (from "Hello world" to a complete tool chain) - will it run on ARM? - will it be a good choice for the Web (e.g. webasm)? - how good is it at data processing / number grinding - etc. I think the D Foundation should focus on the more "trivial" things too. If a company is asked to develop a data grinding web application along with a smart phone app - will it choose D? If a company offers localization services and translations - will it choose D (autodecode)? The D community / leadership is acting as if they had all the time in the world. But other languages are moving fast and they learn from D what _not_ to do. Last but not least, if it's true that the D Foundation has raised only 3.2K, then there's something seriously wrong.
Re: Null-Coalescing Operator and Extensions
On Saturday, 25 August 2018 at 13:33:58 UTC, SG wrote: 1) I program in C# and I'm wondering if there is something like ?? (Null-Coalescing Operator) in D? (I remember some proposals in the past). Another example: https://github.com/aliak00/optional/blob/master/source/optional/optional.d#L340
D now has a dangerous competitor
The following language is a dangerous competitor to D. https://github.com/joaomilho/Enterprise
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On Tuesday, 28 August 2018 at 07:53:34 UTC, Walter Bright wrote: Let's take the much-maligned D const. It isn't C++ const (let's call that "head-const", because that's what it is). Head-const for a function parameter tells us very little about what may happen to it in the function. You can pass a head-const reference to a container, and have the function add/change/delete every element of that container, all without a peep from any C++ tool. Looking at the function signature, you've really got no clue whatsoever. The reason people have trouble with transitive-const is that they are still programming in C++, where they *do* add/change/delete every member of the "const" container. That includes me. I try to add transitive-const, and it won't compile, because I as well am used to replacing the engine and tail lights in my head-const car. In order to use transitive-const, it's forcing me to fundamentally re-think how I organize code into functions. For example, dmd is full of functions that combine data-gathering with taking-action. I've been reorganizing to separate data-gathering and taking-action into separate functions. The former can be transitive-const, maybe even pure. And I like the results, the code becomes much easier to understand. There are still valid use cases where const should be "broken". One of them is mutex (another one caching). I have very little experiance in multi-threaded programming, but what do you think about "mutable" members, despite the object is const?
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On 8/26/2018 11:16 PM, Manu wrote: The code looks the same, and in fact, is about 98% the same. This code appears to be a mechanical translation. It's not. It's by hand. But I had a specific goal of minimizing the diffs, so that if the translation didn't work, it reduced the number of places to look for the mistake. And in fact, this has saved me a LOT of grief :-) That's not what happened in this case; he wrote his game in D from scratch. It was just that he arrived at mostly the same place. He was googling for styling and sample material, but I suspect the problem was a lack of topical material demonstrating how he might write his D code differently. It takes time to learn how to write idiomatic D effectively. I'm still learning how to do it right, too. It's also the case that the significant difference between C++ and D (in my experience) mostly come down to: D has modules, tidier meta, UDA's, slices, and ranges/UFCS. In trade, D struggles with const, and ref is broken. If your code doesn't manifest some gravity towards one of those features, it will tend to be quite same-ey, and advantage may not be particularly apparent. I suspect that is still a bit stuck on looking at individual instruments and not seeing the orchestra. Let's take the much-maligned D const. It isn't C++ const (let's call that "head-const", because that's what it is). Head-const for a function parameter tells us very little about what may happen to it in the function. You can pass a head-const reference to a container, and have the function add/change/delete every element of that container, all without a peep from any C++ tool. Looking at the function signature, you've really got no clue whatsoever. The reason people have trouble with transitive-const is that they are still programming in C++, where they *do* add/change/delete every member of the "const" container. That includes me. I try to add transitive-const, and it won't compile, because I as well am used to replacing the engine and tail lights in my head-const car. In order to use transitive-const, it's forcing me to fundamentally re-think how I organize code into functions. For example, dmd is full of functions that combine data-gathering with taking-action. I've been reorganizing to separate data-gathering and taking-action into separate functions. The former can be transitive-const, maybe even pure. And I like the results, the code becomes much easier to understand.
Re: tupleof function parameters?
On Tuesday, 28 August 2018 at 06:20:37 UTC, Sebastiaan Koppe wrote: On Tuesday, 28 August 2018 at 06:11:35 UTC, Jon Degenhardt wrote: The goal is to write the argument list once and use it to create both the function and the Tuple alias. That way I could create a large number of these function / arglist tuple pairs with less brittleness. --Jon I would probably use a combination of std.traits.Parameters and std.traits.ParameterIdentifierTuple. Parameters returns a tuple of types and ParameterIdentifierTuple returns a tuple of strings. Maybe you'll need to implement a staticZip to interleave both tuples to get the result you want. (although I remember seeing one somewhere). There's one in here -> https://code.dlang.org/packages/bolts And the docs have a link to the particular forum post you're thinking of as well for details.
Re: Dicebot on leaving D: It is anarchy driven development in all its glory.
On 8/27/2018 2:14 AM, Chris wrote: On Sunday, 26 August 2018 at 22:44:05 UTC, Walter Bright wrote: Because nobody thought about that issue before. A lot of things only become apparent in hindsight. QED. With this approach you do more harm than good. I have a bad feeling about the way things are going atm. I can quote you a lng list of problems that are obvious only in hindsight, by world leading development teams. Start by watching the documentary series "Aviation Disasters", look at Challenger, Deepwater Horizon, Fukushima, Apollo 1, Apollo 13, the World Trade Centers, etc. Of course, there are a number of them in C, C++, Java, Javascript, basically every language I've worked with. I'll guarantee every non-trivial project you've worked on has problems that are obvious only in hindsight, too. If you wait till it's perfect, you'll never ship, and yet it'll *still* have problems. I'm not making excuses for mistakes - just don't have unworkable requirements. The end of the day is, does D get the job done for you better than other languages? That's a decision only you can make.
[Issue 18104] Alias example compiles where it states that it should be illegal
https://issues.dlang.org/show_bug.cgi?id=18104 github-bugzi...@puremagic.com changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --
[Issue 18104] Alias example compiles where it states that it should be illegal
https://issues.dlang.org/show_bug.cgi?id=18104 --- Comment #1 from github-bugzi...@puremagic.com --- Commits pushed to master at https://github.com/dlang/dlang.org https://github.com/dlang/dlang.org/commit/9ad4c395470befec8293593fc8dfbdc906cfb56f Fix Issue 18104: improve example showing that aliases cannot be used for expressions https://github.com/dlang/dlang.org/commit/92ff7aa56b7897d8545fe4f2882cc3165c338d3e Merge pull request #2457 from ghost91-/fix-issue-18104 Fix Issue 18104: improve example showing that aliases cannot be used … merged-on-behalf-of: Petar Kirov --
Re: Looking for a mentor for SAoC
On Monday, 27 August 2018 at 21:32:10 UTC, David Nadlinger wrote: On Monday, 27 August 2018 at 20:47:08 UTC, Stefam Koch wrote: generating it is not the problem but linking it on windows currently requires the MS linker. Is that true, though? DMD ships with LLD these days. — David Really ... I am so out of touch these days.
Re: tupleof function parameters?
On Tuesday, 28 August 2018 at 06:20:37 UTC, Sebastiaan Koppe wrote: On Tuesday, 28 August 2018 at 06:11:35 UTC, Jon Degenhardt wrote: The goal is to write the argument list once and use it to create both the function and the Tuple alias. That way I could create a large number of these function / arglist tuple pairs with less brittleness. --Jon I would probably use a combination of std.traits.Parameters and std.traits.ParameterIdentifierTuple. Parameters returns a tuple of types and ParameterIdentifierTuple returns a tuple of strings. Maybe you'll need to implement a staticZip to interleave both tuples to get the result you want. (although I remember seeing one somewhere). Alex, Sebastiaan - Thanks much, this looks like it should get me what I'm looking for. --Jon
Re: Looking for a mentor for SAoC
On 28/08/2018 9:32 AM, David Nadlinger wrote: On Monday, 27 August 2018 at 20:47:08 UTC, Stefam Koch wrote: generating it is not the problem but linking it on windows currently requires the MS linker. Is that true, though? DMD ships with LLD these days. — David And is 100% experimental on both LLD and on the D front.
Re: Is there a simple way to check if value is null for every case?
On Monday, 27 August 2018 at 21:48:04 UTC, Alex wrote: On Monday, 27 August 2018 at 19:36:29 UTC, aliak wrote: Then Nullable!(int*) would be the same as int*. Or even better maybe is to give a compiler error when you try and stuff a nullable type inside a Nullable. Because ... why? Isn't it arguable, whether this is desired? I mean, in the present state you can separate the cases, whether the Nullable is set or not. This is a feature. If Nullable!(int*) behaves like int*, it would be somewhat more straight forward, which is maybe also a feature. But you loose something you can do right now... Certainly arguable :) I'm unsure about of what you lose is worth having, is the problem. And I have trouble thinking of a use case? If we implement opEquals(typeof(null)) as is now, then this code: Nullable!(int*) n = null; assert(n != null); passes. And if we have no opEquals then we can't test for native null on a 'null'able type O_o Another options is: bool opEquals(typeof(null)) { enum isNullInvalid = is(T == class) || is(T == interface) || isSomeFunction!T; static if (isNullInvalid) return isNull || data is null else return isNull; } I also did a quick search on google "allintext: "nullable" site:github.com filetype:d" and there were 0 instances of T* (just looked thorugh search results didn't click in).
Re: GDC with D frontend 2.081.2
On Tuesday, 28 August 2018 at 06:18:28 UTC, Daniel Kozak wrote: On Mon, Aug 27, 2018 at 7:55 PM Eugene Wissner via Digitalmars-d-announce < digitalmars-d-announce@puremagic.com> wrote: On Monday, 27 August 2018 at 17:23:04 UTC, Arun Chandrasekaran wrote: > 1. It would be good to print the DMD frontend version with > `gdc --version`. It is helpful in reporting bugs. LDC does > this. > Unfortunately it doesn't seem to be possible. GCC doesn't allow to change --version output: https://bugzilla.gdcproject.org/show_bug.cgi?id=89 This is not true, right now on archlinux if you type gdc --version it will display d frontend version https://bugzilla.gdcproject.org/show_bug.cgi?id=89#c1 Is it set with --with-pkgversion? The same information will be displayed for gcc and g++ then. It is not always desirable if you ship the compiler as a whole (with libtool etc).
Re: tupleof function parameters?
On Tuesday, 28 August 2018 at 06:11:35 UTC, Jon Degenhardt wrote: The goal is to write the argument list once and use it to create both the function and the Tuple alias. That way I could create a large number of these function / arglist tuple pairs with less brittleness. --Jon I would probably use a combination of std.traits.Parameters and std.traits.ParameterIdentifierTuple. Parameters returns a tuple of types and ParameterIdentifierTuple returns a tuple of strings. Maybe you'll need to implement a staticZip to interleave both tuples to get the result you want. (although I remember seeing one somewhere).
Re: tupleof function parameters?
On Tuesday, 28 August 2018 at 06:11:35 UTC, Jon Degenhardt wrote: I'd like to create a Tuple alias representing a function's parameter list. Is there a way to do this? [...] Are you aware of https://dlang.org/phobos/std_traits.html#Parameters
Re: GDC with D frontend 2.081.2
On Mon, Aug 27, 2018 at 7:55 PM Eugene Wissner via Digitalmars-d-announce < digitalmars-d-announce@puremagic.com> wrote: > On Monday, 27 August 2018 at 17:23:04 UTC, Arun Chandrasekaran > wrote: > > 1. It would be good to print the DMD frontend version with `gdc > > --version`. It is helpful in reporting bugs. LDC does this. > > > Unfortunately it doesn't seem to be possible. GCC doesn't allow > to change --version output: > https://bugzilla.gdcproject.org/show_bug.cgi?id=89 > > This is not true, right now on archlinux if you type gdc --version it will display d frontend version https://bugzilla.gdcproject.org/show_bug.cgi?id=89#c1
tupleof function parameters?
I'd like to create a Tuple alias representing a function's parameter list. Is there a way to do this? Here's an example creating a Tuple alias for a function's parameters by hand: import std.typecons: Tuple; bool fn(string op, int v1, int v2) { switch (op) { default: return false; case "<": return v1 < v2; case ">": return v1 > v2; } } alias fnArgs = Tuple!(string, "op", int, "v1", int, "v2"); unittest { auto args = fnArgs("<", 3, 5); assert(fn(args[])); } This is quite useful. I'm wondering if there is a way to create the 'fnArgs' alias from the definition of 'fn' without needing to manually write out the '(string, "op", int, "v1", int, "v2")' sequence by hand. Something like a 'tupleof' operation on the function parameter list. Or conversely, define the tuple and use it when defining the function. The goal is to write the argument list once and use it to create both the function and the Tuple alias. That way I could create a large number of these function / arglist tuple pairs with less brittleness. --Jon