is ==
Why does D complain when using == to compare with null? Is there really any technical reason? if one just defines == null to is null then there should be no problem. It seems like a pedantic move by who ever implemented it and I'm hoping there is actually a good technical reason for it.
==, is
quick question: are the following rewrites always valid: e1 != e2 -> !(e1 == e2) e1 !is e2-> !(e1 is e2) e1 !in e2-> !(e1 in e2) ?
is is cast on hash required
Is there a way around the cast below to see if ci is i? If not, is there already a standard template method that does DeepUnqual. Finally, if not a workaround is this safe? Thanks Dan -- import std.traits; void main() { const(int[string]) ci; int[string] i; // FAILS TO COMPILE if(ci is i) { } if(cast(DeepUnqual!(typeof(ci)))ci is cast(DeepUnqual!(typeof(i)))i) { } } template DeepUnqual(T) { static if(isAssociativeArray!T) { alias Unqual!(Unqual!(ValueType!T)[Unqual!(KeyType!T)]) DeepUnqual; } else static if(isDynamicArray!T) { alias Unqual!(Unqual!(ArrayElementType!T)[]) DeepUnqual; } else static if(isPointer!T) { alias Unqual!(PointerTarget!T) * DeepUnqual; } else { alias Unqual!T DeepUnqual; } }
What is PostgreSQL driver is most stable?
I need to develop App that should work on Linux and Windows. It need PostgreSQL driver. I tried Vadim's ddbc for PostgreSQL but it's fail on x64 version of PostgreSQL and possible will not on x64 PG on Linux (I can't test it now). Could anybody advice me good driver without problems? I seen some pg-wrapers on code.dlang.ru, but do not have test all of them.
Is it std.regex, or is it me.
Given the following, where X and Y mark the spot: X epochRegex = regex("([0-9])+:"); Y aEpochCapture = matchFirst(aVersionString, epochRegex); Y bEpochCapture = matchFirst(bVersionString, epochRegex); If X or Y are const or immutable the code fails to compile. Only if both X and Y are auto does this code compile. So question to the audience: how do you do single assignment programming in D? Is it, in fact, impossible to program with bindings rather than variables in D? And yes this does seem to be a violation of the Principle of Least Surprise. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Is is a Bug or just me?
Hi d community, I got a strange behavior since dmd 2.090 (dmd 2.089 is the last working version). See this reduced code: https://run.dlang.io/is/yoyHXC I would expect that foo() returns 2. My guess in foo is: The return value of val is saved locally as a ref int and then the destructor of S is called (set the local cache to 0). Now the ref value is dereferenced and returned. Now I am unsure if this is a bug or an undefined behavior that I don't know. If this is a bug, then I don't know how to call it for the bug tracker. I hope you can help me with this problem. PS: This is only tested on my Linux system and on run.dlang.io. - foerdi
Re: is is cast on hash required
Dan: Is there a way around the cast below to see if ci is i? I have added a related bug report: http://d.puremagic.com/issues/show_bug.cgi?id=9031 Bye, bearophile
double.init is real.nan, is it a bug?
Hi all, I think this is a bug, but if not I'm very confused and would like some clarification. When checking double values that could be nan or unassigned I have to check both double.init and double.nan. But double.init IS double.nan. --- void main() { // passes but I believe it is checked during compile assert(double.init is double.nan); double val; std.stdio.writeln( to!string(val) ); // writes "nan" to console assert(val is double.init); // passes assert(val is double.nan); // << FAILS (unexpectedly for me anyway) } --- Why does assert(val is double.nan) fail? Given: a) double.init is double.nan b) val is double.init c) to!string(val) sees val as a nan I also found this confusing: --- void main() { assert(double.init is double.nan); // passes expected assert(double.init is float.init); // passes, unexpected assert(double.init is real.init); // passes, unexpected assert(double.init is real.nan); // passes, unexpected assert(double.init is float.nan); // passes, unexpected } --- I don't think these should be passing...should they?? I'm on fedora 19, dmd 2.063.2 extracted from the ZIP Thanks
is(T : long) vs is(T == long)
What is the difference between this: template isNumerik(T){ enum bool isNumerik = is(T : long) || is(T : real); } and this: template isNumerik(T){ enum bool isNumerik = is(T == long) || is(T == real); } They both work and I can't find anywhere in the book where it talks about the :
Re: is ==
On Friday, 18 May 2018 at 23:53:12 UTC, IntegratedDimensions wrote: Why does D complain when using == to compare with null? Is there really any technical reason? if one just defines == null to is null then there should be no problem. It seems like a pedantic move by who ever implemented it and I'm hoping there is actually a good technical reason for it. D only complains of this when you use ref types (classes or AAs). For e.g: --- test.d void main() { int * p; assert (p == null && p is null); class C { int x; } C c; assert (c is null); assert (c == null); //error, c is a reference, so there is confusion between opEquals and null check } ---
Re: is ==
On Friday, 18 May 2018 at 23:58:18 UTC, Uknown wrote: On Friday, 18 May 2018 at 23:53:12 UTC, IntegratedDimensions wrote: Why does D complain when using == to compare with null? Is there really any technical reason? if one just defines == null to is null then there should be no problem. It seems like a pedantic move by who ever implemented it and I'm hoping there is actually a good technical reason for it. D only complains of this when you use ref types (classes or AAs). For e.g: --- test.d void main() { int * p; assert (p == null && p is null); class C { int x; } C c; assert (c is null); assert (c == null); //error, c is a reference, so there is confusion between opEquals and null check } --- or pointers.
Re: is ==
On Friday, 18 May 2018 at 23:53:12 UTC, IntegratedDimensions wrote: Why does D complain when using == to compare with null? Is there really any technical reason? if one just defines == null to is null then there should be no problem. It seems like a pedantic move by who ever implemented it and I'm hoping there is actually a good technical reason for it. tldr: this error is outdated. In the days of yore, "obj == null" would call "obj.opEquals(null)". Attempting to call a virtual method on a null object is a quick path to a segmentation fault. So "obj == null" would either yield false or crash your program. Except it's worse than that; your opEquals method had to explicitly check for null. So if your class had a custom equality function, "obj == null" was probably going to segfault no matter what. Because of this common source of errors, in DMD 2.012 (2008), we got an error only for the case of comparing with a literal null. (The compiler isn't a mind-reader; it doesn't know whether that variable will be null when that line of code executes.) This still sucked, so in 2015 we got a runtime function to handle object equality: https://github.com/dlang/druntime/blob/dff824eda422b1fcdde5f2fe53120fcd71733aaa/src/object.d#L140 But we haven't removed the error message. It *is* faster to call "foo is null" than "foo == null", but I don't think that's particularly worth a compiler error. The compiler could just convert it to "is null" automatically in that case. One casualty of the current state of affairs is that no object may compare equal to null.
Re: is ==
On Friday, May 18, 2018 23:53:12 IntegratedDimensions via Digitalmars-d- learn wrote: > Why does D complain when using == to compare with null? Is there > really any technical reason? if one just defines == null to is > null then there should be no problem. It seems like a pedantic > move by who ever implemented it and I'm hoping there is actually > a good technical reason for it. Because == is pretty much never what you want to do with null. How much it matters depends on the types involved, but if you really want to check for null, is is definitely the right thing to use. In the case of pointers and references, is checks that they're pointing to the same thing. So, foo is null directly checks whether the reference or pointer is null. On the other hand, if you use ==, it's calling some form of opEquals. For pointers, that should generate identical code, but for class references, it means calling the free function opEquals. That function will check whether the references are null before calling opEquals on either of the class objects, but it does add unnecessary overhead (which, as I understand it, the compiler is unfortunately not currently able to optimize away) and provides no benefit over checking with is. Now, where is vs == _really_ matters (but unfortunately, the compiler does not complain about) is with dynamic arrays. If you do arr is null then the compiler will check whether the array's ptr is null. So, something like "" is null would be false. However, if you use ==, then it compares the length of the array and then only compares the ptrs if the length is non-zero. So, "" == null is true. So, with dynamic arrays, using == with null is a huge code smell. It _may_ be exactly what the programmer intends, but the odds are pretty high that they just don't properly understand the difference between is and ==, and they meant to be checking whether the array was actually null but just ended up checking whether its length was zero (which won't matter for some code but will cause subtle bugs in any code that treats null as special - e.g. if that is used to indicate that the array had not been given a value). Now, because of how == treats null like empty, it _is_ a bit risky to try and treat null as special with arrays, but anyone wanting to be clear in their code should either be checking null with is (in which case, they clearly care about null and not empty), or if they care about length == 0, they should either be calling empty on the array or explicitly checking the array's length, since that's what they care about. Much as having == work with null arrays avoids issues with segfaults due to an array be unitialized as well as avoids needing to give memory to an array just to have it be empty, you pretty much never actually care whether an array == null. You either care that its ptr is null (in which case, is checks that), or you care about whether its length is 0 (in which case empty or directly checking length checks that). arr == null is just unclear and likely buggy. So really, there are _zero_ advantages to comparing null with ==. Using == with null risks adding extra overhead, and it often makes the code less clear. On the other hand, using is makes it crystal clear what you mean and then does exactly what you mean - check whether the variable is actually null. So, maybe the compiler is being a bit pedantic by insisting that you use is rather than ==, but you really should be using is and not == when checking for null. - Jonathan M Davis
Re: is ==
On Saturday, May 19, 2018 01:27:59 Neia Neutuladh via Digitalmars-d-learn wrote: > On Friday, 18 May 2018 at 23:53:12 UTC, IntegratedDimensions > > wrote: > > Why does D complain when using == to compare with null? Is > > there really any technical reason? if one just defines == null > > to is null then there should be no problem. It seems like a > > pedantic move by who ever implemented it and I'm hoping there > > is actually a good technical reason for it. > > tldr: this error is outdated. > > In the days of yore, "obj == null" would call > "obj.opEquals(null)". Attempting to call a virtual method on a > null object is a quick path to a segmentation fault. So "obj == > null" would either yield false or crash your program. > > Except it's worse than that; your opEquals method had to > explicitly check for null. So if your class had a custom equality > function, "obj == null" was probably going to segfault no matter > what. > > Because of this common source of errors, in DMD 2.012 (2008), we > got an error only for the case of comparing with a literal null. > (The compiler isn't a mind-reader; it doesn't know whether that > variable will be null when that line of code executes.) > > This still sucked, so in 2015 we got a runtime function to handle > object equality: > https://github.com/dlang/druntime/blob/dff824eda422b1fcdde5f2fe53120fcd717 > 33aaa/src/object.d#L140 > > But we haven't removed the error message. Actually, that runtime function has existed since before TDPL came out in 2010. It even shows the implementation of the free function opEquals (which at the time was in object_.d rather than object.d). I'm not even sure that the error message was added before the free function version of opEquals was. Maybe when that error message was first introduced, it avoided a segfault, but if so, it has been a _long_ time since that was the case. > It *is* faster to call "foo is null" than "foo == null", but I > don't think that's particularly worth a compiler error. The > compiler could just convert it to "is null" automatically in that > case. > > One casualty of the current state of affairs is that no object > may compare equal to null. Honestly, while the compiler probably should just convert obj == null to obj is null, there really still isn't really a good reason to ever use == with null. It's _never_ better than using is, and in some cases, it's worse. Of course, the most notable case where using == with null is a terrible idea is dynamic arrays, and that's the case where the compiler _doesn't_ complain. Using == with null and arrays is always unclear about the programmer's intent and almost certainly wasn't what the programmer intended. If the programmer cares about null, they should use is. If they care about lengnth, then that's what they should check. Checking null with == is just a huge code smell. So, perhaps the compiler is being pedantic, but it's still telling you the right thing. It's just insisting about it in the case where it matters less while not complaining aobut it in the case where it really matters, which is dumb. So IMHO, if anything, adding an error message for the array case would make more sense than getting rid of the error with pointers and references. - Jonathan M Davis
Re: is ==
On Saturday, 19 May 2018 at 01:48:38 UTC, Jonathan M Davis wrote: Actually, that runtime function has existed since before TDPL came out in 2010. It even shows the implementation of the free function opEquals (which at the time was in object_.d rather than object.d). I'm not even sure that the error message was added before the free function version of opEquals was. Maybe when that error message was first introduced, it avoided a segfault, but if so, it has been a _long_ time since that was the case. Good catch. I overly trusted git blame. The opEquals(Object, Object) function was added in February 2010, while the error message was added in March 2008. Of course, the most notable case where using == with null is a terrible idea is dynamic arrays, and that's the case where the compiler _doesn't_ complain. Using == with null and arrays is always unclear about the programmer's intent and almost certainly wasn't what the programmer intended. If the programmer cares about null, they should use is. If they care about lengnth, then that's what they should check. Checking null with == is just a huge code smell. I feel like the array == null version is more explicit about not allocating memory. However, I'm paranoid about whether that's going to check the pointer instead, so I mostly use array.length == 0 instead.
Re: is ==
On Saturday, May 19, 2018 03:32:53 Neia Neutuladh via Digitalmars-d-learn wrote: > > Of course, the most notable case where using == with null is a > > terrible idea is dynamic arrays, and that's the case where the > > compiler _doesn't_ complain. Using == with null and arrays is > > always unclear about the programmer's intent and almost > > certainly wasn't what the programmer intended. If the > > programmer cares about null, they should use is. If they care > > about lengnth, then that's what they should check. Checking > > null with == is just a huge code smell. > > I feel like the array == null version is more explicit about not > allocating memory. However, I'm paranoid about whether that's > going to check the pointer instead, so I mostly use array.length > == 0 instead. I'm not sure what memory allocations you're worried about. Neither "" nor [] allocates memory, but regardless, if you're looking to check whether arr.ptr is null, then that's effectively what you get with arr is null - though IIRC, it still checks length in that case. It's just that the type system guarantees that a null dynamic array has a length of 0. You'd have to do some pretty screwy @system casting to have a null dynamic array with a length other than 0. But you can always do arr.ptr is null Regardless, if you're checking for null, then is does the job, and if what you care about is whether the array is empty, then that's what arr.length == 0 and arr.empty do. arr == null is just risking confusion, because there's no way to know if the programmer meant arr is null or arr.empty Regardless, it's absolutely guaranteed that arr == null is going to avoid checking the value of ptr just like arr == arr2 won't check ptr if length == 0. == only cares that both arrays have the same number of elements and that they're equal with ==. If length is 0, there's no need to check the elements to verify that, and if the lengths don't match, there's no need to check the elements. If you actually used enough screwed up casts to get two dynamic arrays whose ptr values were null, and they had different lengths, you still wouldn't get a crash. The _only_ way to get a segfault from using == with a null dynamic array is if you did enough screwy @system casts to have two dynamic arrays with the same non-zero length, and one of them had a null ptr. It wouldn't even crash if they were both null, because it's going to check the ptrs before comparing the elements. Regardless, in no real program do you have to worry about segfaulting with == and dynamic arrays, and you don't have to worry about == ever allocating. The closest that you'd get to that would be if you compared against a non-null array literal. e.g. arr == [1, 2, 3] and if the compiler is smart enough, not even that should allocate (though I don't remember if it's that smart at the moment). Ultimately, the question of is vs == comes down to clarity of the programmer's intent. - Jonathan M Davis
Re: is ==
On Saturday, 19 May 2018 at 04:30:24 UTC, Jonathan M Davis wrote: On Saturday, May 19, 2018 03:32:53 Neia Neutuladh via Digitalmars-d-learn wrote: > Of course, the most notable case where using == with null is > a terrible idea is dynamic arrays, and that's the case where > the compiler _doesn't_ complain. Using == with null and > arrays is always unclear about the programmer's intent and > almost certainly wasn't what the programmer intended. If the > programmer cares about null, they should use is. If they > care about lengnth, then that's what they should check. > Checking null with == is just a huge code smell. I feel like the array == null version is more explicit about not allocating memory. However, I'm paranoid about whether that's going to check the pointer instead, so I mostly use array.length == 0 instead. I'm not sure what memory allocations you're worried about. Neither "" nor [] allocates memory "" is syntax for compile-time constants and shouldn't ever allocate. [] is a specific case of [values...]; the general case allocates, but this one case does not. null is not even a compile-time constant; it's a value baked into the language and is guaranteed not to allocate. but regardless, if you're looking to check whether arr.ptr is null, then that's effectively what you get with arr is null I don't think I've ever wanted to distinguish a zero-length slice of an array from a null array. Regardless, if you're checking for null, then is does the job, and if what you care about is whether the array is empty, then that's what arr.length == 0 and arr.empty do. As I already said, I use "array.length == 0". "array.empty" is part of that newfangled range business.
Re: is ==
On Saturday, 19 May 2018 at 01:31:38 UTC, Jonathan M Davis wrote: On Friday, May 18, 2018 23:53:12 IntegratedDimensions via Digitalmars-d- learn wrote: Why does D complain when using == to compare with null? Is there really any technical reason? if one just defines == null to is null then there should be no problem. It seems like a pedantic move by who ever implemented it and I'm hoping there is actually a good technical reason for it. Because == is pretty much never what you want to do with null. How much it matters depends on the types involved, but if you really want to check for null, is is definitely the right thing to use. In the case of pointers and references, is checks that they're pointing to the same thing. So, foo is null directly checks whether the reference or pointer is null. On the other hand, if you use ==, it's calling some form of opEquals. For pointers, that should generate identical code, but for class references, it means calling the free function opEquals. That function will check whether the references are null before calling opEquals on either of the class objects, but it does add unnecessary overhead (which, as I understand it, the compiler is unfortunately not currently able to optimize away) and provides no benefit over checking with is. Now, where is vs == _really_ matters (but unfortunately, the compiler does not complain about) is with dynamic arrays. If you do arr is null then the compiler will check whether the array's ptr is null. So, something like "" is null would be false. However, if you use ==, then it compares the length of the array and then only compares the ptrs if the length is non-zero. So, "" == null is true. So, with dynamic arrays, using == with null is a huge code smell. It _may_ be exactly what the programmer intends, but the odds are pretty high that they just don't properly understand the difference between is and ==, and they meant to be checking whether the array was actually null but just ended up checking whether its length was zero (which won't matter for some code but will cause subtle bugs in any code that treats null as special - e.g. if that is used to indicate that the array had not been given a value). Now, because of how == treats null like empty, it _is_ a bit risky to try and treat null as special with arrays, but anyone wanting to be clear in their code should either be checking null with is (in which case, they clearly care about null and not empty), or if they care about length == 0, they should either be calling empty on the array or explicitly checking the array's length, since that's what they care about. Much as having == work with null arrays avoids issues with segfaults due to an array be unitialized as well as avoids needing to give memory to an array just to have it be empty, you pretty much never actually care whether an array == null. You either care that its ptr is null (in which case, is checks that), or you care about whether its length is 0 (in which case empty or directly checking length checks that). arr == null is just unclear and likely buggy. So really, there are _zero_ advantages to comparing null with ==. Using == with null risks adding extra overhead, and it often makes the code less clear. On the other hand, using is makes it crystal clear what you mean and then does exactly what you mean - check whether the variable is actually null. So, maybe the compiler is being a bit pedantic by insisting that you use is rather than ==, but you really should be using is and not == when checking for null. - Jonathan M Davis I don't see your point. You claim that one should never use == null for whatever reason and that it is "wrong". So, why are you allowing wrong things in a language that can easily be fixed? Just reinterpret == null as is null and be done with it! This fixes the wrong and everyone can live happily ever after. Your logic is the same how people "ban" certain words like faggot. They don't like them for some reason, decide that no one should use it any more, and create a new word that essentially means the same thing... and it results in a loop where that new word then eventually gets "banned". == vs is might not be quite as extreme, maybe is will be the final "word". But if == null is banned by the compiler why the hell not just reinterpret to mean is null internally and be done with it and allow the syntax since it is so common? The only pitfalls is pasting code from other languages that might have a different interpretation, but those problems always exist since the languages are different. Your reasons for arrays is not good enough. First, not all types are arrays so you are banning a whole class of valid types for one case. That case, you say, is almost never meant anyways(that is, using == null is
Re: is ==
On Saturday, May 19, 2018 17:50:50 IntegratedDimensions via Digitalmars-d- learn wrote: > So, ultimately what I feels like is that you are actually arguing > for == null to be interpreted as is null but you don't realize it > yet. Not really, no. Having foo == null be rewritten to foo is null in the non-dynamic array cases should be fine except for the fact that it's then a terrible habit to be in when you then have to deal with dynamic arrays. Using foo == null with dyanmic arrays is an enormous code smell, because the odds are extemely high that the programmer thinks that they're checking if the dynamic array is null when that's not what they're doing at all. IMHO, it should definitely be an error to use == with null and dynamic arrays because it is such a big code smell. Either the code should be using is to check whether the array is null, or it should be checking length. It should never be using == with null. But unfortunately, the compiler is completely backwards about this and treats it as an error with pointers and references but allows it with dynamic arrays. If the compiler were improved to just replace == with is in the cases that it currently treats as illegal, then that would be fine if it then treated it as illegal with dynamic arrays. But as it stands, it is still more efficient to use is with call references, so encouraging the programmer to use is is benefical, and it encourages the programmer to get in the habit of not using == with null, since it's a terrible habit to be in with dynamic arrays. But actually making it illegal for dynamic arrays would be a much better approach. If it were up to me, it would just be illgal to use == with null in general, because that's really the way it should be with dynamic arrays, and then the language would be consistent about it. But instead, the compiler screams in the case that matters far less and allows it in the case that is clearly bad. So, it's inconsistent in a dumb way. At least if it were inconsistent by allowing it for pointers and references while disallowing it for arrays, it would be prventing it in the case that truly matters, but instead, what we have is just dumb. - Jonathan M Davis
Re: is ==
On Saturday, May 19, 2018 17:13:36 Neia Neutuladh via Digitalmars-d-learn wrote: > I don't think I've ever wanted to distinguish a zero-length slice > of an array from a null array. It's safer if you don't, because it's so easy to end up with a dynamic array that is empty instead of null, and stuff like == doesn't care about the difference. But there is code that's written that cares (e.g. IIRC, std.experimental.allocator does in some cases). if(arr) is equivalent to if(cast(bool)arr) and casting a dynamic array to bool is equivalent to arr !is null which means that if(arr) means if(arr !is null) whereas it's not uncommon for folks to think that it means if(arr.length != 0) Similarly, assert(arr); is ultimately equivalent to asser(arr !is null); which suprises many folks and is rarely what folks want. So, there was a push at one point to make it illegal to use a dynamic array in an if statment or assertion directly, and it did briefly make it into the compiler. However, a few folks (Andrei and Vladimir in particular IIRC), had used arrays in if statments directly quite a bit, knowing full well what it meant. So, their code was right (albeit potentially confusing), and they pushed back. So, the change was reverted, and we're still stuck with the error-prone situation that we've had. So, most of us would argue that it's risky to treat null dynamic arrays as special and that it should be done with caution, but programmers who know what they're definitely do it. Unfortunately, when you read code that's writen that way, it's usually hard to tell whether it was written with that undertanding or not, and a stray == in the code could easily break it. > As I already said, I use "array.length == 0". "array.empty" is > part of that newfangled range business. LOL. Well, if you stay away from ranges, you're losing out on a lot of benefits - including large portions of the standard library, but checking for length works fine if you're dealing with code that's just using dynamic arrays and not ranges. The key thing is to avoid arr == null, because that's were the bugs lie. - Jonathan M Davis
Re: is ==
On Sunday, 20 May 2018 at 00:19:28 UTC, Jonathan M Davis wrote: On Saturday, May 19, 2018 17:50:50 IntegratedDimensions via Digitalmars-d- learn wrote: So, ultimately what I feels like is that you are actually arguing for == null to be interpreted as is null but you don't realize it yet. Not really, no. Having foo == null be rewritten to foo is null in the non-dynamic array cases should be fine except for the fact that it's then a terrible habit to be in when you then have to deal with dynamic arrays. Using foo == null with dyanmic arrays is an enormous code smell, because the odds are extemely high that the programmer thinks that they're checking if the dynamic array is null when that's not what they're doing at all. IMHO, it should definitely be an error to use == with null and dynamic arrays because it is such a big code smell. Either the code should be using is to check whether the array is null, or it should be checking length. It should never be using == with null. But unfortunately, the compiler is completely backwards about this and treats it as an error with pointers and references but allows it with dynamic arrays. If the compiler were improved to just replace == with is in the cases that it currently treats as illegal, then that would be fine if it then treated it as illegal with dynamic arrays. But as it stands, it is still more efficient to use is with call references, so encouraging the programmer to use is is benefical, and it encourages the programmer to get in the habit of not using == with null, since it's a terrible habit to be in with dynamic arrays. But actually making it illegal for dynamic arrays would be a much better approach. If it were up to me, it would just be illgal to use == with null in general, because that's really the way it should be with dynamic arrays, and then the language would be consistent about it. But instead, the compiler screams in the case that matters far less and allows it in the case that is clearly bad. So, it's inconsistent in a dumb way. At least if it were inconsistent by allowing it for pointers and references while disallowing it for arrays, it would be prventing it in the case that truly matters, but instead, what we have is just dumb. - Jonathan M Davis Let D be a dynamic array, O a pointer or object: | Conceptually | in D D == null Invalid Valid D is null Valid Valid O == null Valid Invalid O is null Valid Valid Right? So what you are saying is you want to create 2 more invalids in the table to satisfy some weird logic which requires the programmer to remember special cases rather than make them all valid and easy to remember even though it can be done and make sense. In fact, the 2nd invalid makes sense and should be allowed so really you want to create 3 invalids for the price of one. Simply require == null as is null and be done with it. You can't police programmers minds and get them to program correctly. If you had a kid, do you box them up in a bubble room and not let them play because they might hurt themselves? How people learn is by making mistakes. It is better to provide a logical foundation that is consistent rather than produce corner cases to handle some corner case that was created to handle another corner case because someone handled a corner case.
Re: is ==
On Sunday, May 20, 2018 01:51:50 IntegratedDimensions via Digitalmars-d- learn wrote: > Simply require == null as is null and be done with it. That would be flat out wrong for dynamic arrays, because then auto result = arr == null and int[] nullArr; auto result = arr == nullArr; would have different semantics. The way that dynamic arrays are designed to work even if they're null mucks with this considerably here. > You can't police programmers minds and get them to program correctly. That's true, but making things that are highly likely to be wrong illegal prevents bugs. e.g. while(cond); is illegal in D precisely because it's error-prone. There are cases where doing something like that would be perfectly correct. e.g. while(++a != b); but you can do the exact same thing with empty parens while(++a != b) {} and all of those bugs with accidentally closing a loop with a semicolon go away, and you don't lose any expressiveness. The compiler just forces you to write it in a way that's far less error-prone. Making it illegal to compare the null literal with == also prevents bug, and you don't lose any expressiveness doing it either. It's the same kind of logic. Making error-prone constructs illegal when there's a simple equivalent that isn't error-prone is good language design, because it prevents bugs without actually restricting the programmer. It's when the language starts disallowing things that aren't error-prone and/or don't have simple equivalents that you start running into problems with the compiler getting in your way and treating you like a kid. For simple stuff like this, it ultimately saves you time and effort without getting in your way. At most, you occasionally have to replace foo == null with foo is null or foo.length != 0, and it potentially saves you hours of effort tracking down a subtle bug. - Jonathan M Davis
Re: is ==
On Sunday, 20 May 2018 at 02:09:47 UTC, Jonathan M Davis wrote: On Sunday, May 20, 2018 01:51:50 IntegratedDimensions via Digitalmars-d- learn wrote: Simply require == null as is null and be done with it. That would be flat out wrong for dynamic arrays, because then auto result = arr == null and int[] nullArr; auto result = arr == nullArr; would have different semantics. The way that dynamic arrays are designed to work even if they're null mucks with this considerably here. Do you not see they are different? You think arr == nullArr and arr == null are suppose to necessarily be the same semantics? That is patently false! You should rethink your position on that because it is wrong. null is a keyword in D and has a very special meaning and hence that meaning MUST be taken in to account. There is no harm in making them different. Your logic thinks that that they should be the same but if you are wrong then your whole argument is wrong. for example, Object o = null; then o == null should not be true even though "null == null" in some sense. == null is a test of validity. One never checks if null == null and it is a meaningless case so allowing it as a possibility is meaningless. You are treating null as if it is on the same level as objects and arrays and it is not. By doing so you lose the power of it being singled out as a keyword. You can't police programmers minds and get them to program correctly. That's true, but making things that are highly likely to be wrong illegal prevents bugs. e.g. Not necessarily because you just create more bugs by doing that. Your son, the bubble boy, then does not develop an immune system that he should of developed by you trying to protect them from hurting himself. You should get out of the business of trying to prevent things that you don't even know are going to happen. It is a bad mindset to be in because, for all you know, those things will never happen. Time is better spent than trying to police everyone from doing anything wrong. 1. You can't do it. 2. You make things worse in the long run because who's policing you to keep you from screwing up? Do you know how many "bugs" are produced by people who are fixing "bugs"? We can surely bet more than zero. while(cond); is illegal in D precisely because it's error-prone. There are cases where doing something like that would be perfectly correct. e.g. while(++a != b); but you can do the exact same thing with empty parens while(++a != b) {} and all of those bugs with accidentally closing a loop with a semicolon go away, and you don't lose any expressiveness. The compiler just forces you to write it in a way that's far less error-prone. This is a different problem and therefor not applicable. Making it illegal to compare the null literal with == also prevents bug, and you don't lose any expressiveness doing it either. It's the same kind of logic. Making error-prone constructs illegal when there's a simple equivalent that isn't error-prone is good language design, because it prevents bugs without actually restricting the programmer. It's when the language starts disallowing things that aren't error-prone and/or don't have simple equivalents that you start running into problems with the compiler getting in your way and treating you like a kid. For simple stuff like this, it ultimately saves you time and effort without getting in your way. At most, you occasionally have to replace foo == null with foo is null or foo.length != 0, and it potentially saves you hours of effort tracking down a subtle bug. - Jonathan M Davis You certainly do lose expressiveness. You loose elegance because you cannot express logically related things in a logically related way. The problem is the WHOLE reason it is error prone is from who ever decided the dynamic array syntax of == null would not compare it the same way it does everything else. Basically someone thought they were going to be fancy and treat == null as the same as an allocated 0 length array. That was the problem from the get go. == null should have a very specific and consistent meaning and someone decided to change that in an irregular and inconsistent meaning and now we have less elegance in the language than we could. The reason why you are saying it is buggy is PRECISELY because of what was done wrong. Programmers assume that == null means the same thing it does everywhere else, but LO AND BEHOLD! Not in that one special case and if they don't know about that special case they hit the "bug". See, what you call bugs is really the programmers failing to know the special case that was created. The special case that really had no reason to be a special case. So, in fact, who ever decided on the rules here created more problems than they solv
Re: is ==
Furthermore: https://issues.dlang.org/show_bug.cgi?id=3889 Shows real problems. You argue from the side that the bug already exists so we must work around it because we can't go back and "fix things". Who says? D has had breaking changes in the past so it is not a deal breaker. It is also a relatively easy transition because == null is very easy to find and fix. With the mentality that one must always deal with introduced logic bugs that, if fixed, will break old code is insane. The whole point of fixing bugs is to make things work *correctly*. The fact is someone decided it was a good idea to conflate null with some dynamic array BS and that is where all the problems come from. It should have never been done and this issue will persist until someone gets the balls to fix it. After all, how do you know it won't actually make a lot of "buggy" code better?
Re: is ==
On 5/18/18 9:48 PM, Jonathan M Davis wrote: On Saturday, May 19, 2018 01:27:59 Neia Neutuladh via Digitalmars-d-learn wrote: On Friday, 18 May 2018 at 23:53:12 UTC, IntegratedDimensions wrote: Why does D complain when using == to compare with null? Is there really any technical reason? if one just defines == null to is null then there should be no problem. It seems like a pedantic move by who ever implemented it and I'm hoping there is actually a good technical reason for it. tldr: this error is outdated. In the days of yore, "obj == null" would call "obj.opEquals(null)". Attempting to call a virtual method on a null object is a quick path to a segmentation fault. So "obj == null" would either yield false or crash your program. I remember this, and I remember arguing for the current behavior many times (after having many many crashes) :) https://forum.dlang.org/post/fqlgah$15v2$1...@digitalmars.com Read that thread if you want to see the rationale. However, I'd argue it's still good to keep the error as there is literally no point to not using == null on class references vs. is null. You now would get the same result, but it's faster/cleaner. Actually, that runtime function has existed since before TDPL came out in 2010. It even shows the implementation of the free function opEquals (which at the time was in object_.d rather than object.d). I'm not even sure that the error message was added before the free function version of opEquals was. Maybe when that error message was first introduced, it avoided a segfault, but if so, it has been a _long_ time since that was the case. Some things in TDPL were forward-thinking. I remember Andrei fleshing out some of how the languages SHOULD behave in the forums or mailing lists for the purposes of writing TDPL even though it didn't yet behave that way. In fact, I'm almost positive the new object comparison function came as a result of TDPL (but I'm not 100% sure). Some of TDPL still has never been implemented. Long story short, don't date the existence of features in TDPL based on the publication :) In this case, for fun (what is wrong with me), I looked up the exact date it got added, and it was Feb 2010: https://github.com/dlang/druntime/commit/2dac6aa262309e75ad9b524cb4d1c3c1f0ecc2ae. TDPL came out in June 2010, so this feature does predate TDPL by a bit. In fact, through this exercise, I just noticed that the reason it returns auto instead of bool is to make sure it gets into the now defunct "generated" object.di file (https://github.com/dlang/druntime/pull/2190). It *is* faster to call "foo is null" than "foo == null", but I don't think that's particularly worth a compiler error. The compiler could just convert it to "is null" automatically in that case. It's not worth a compiler error if we didn't already have it, but I don't know that it's worth taking out. It's really what you should be doing, it's just that the penalty for not doing it isn't as severe as it used to be. One casualty of the current state of affairs is that no object may compare equal to null. And let's keep it that way! Of course, the most notable case where using == with null is a terrible idea is dynamic arrays, and that's the case where the compiler _doesn't_ complain. I use arr == null all the time. I'm perfectly fine with that, and understand what it means. Using == with null and arrays is always unclear about the programmer's intent and almost certainly wasn't what the programmer intended. I beg to differ. If the programmer cares about null, they should use is. If they care about lengnth, then that's what they should check. Checking null with == is just a huge code smell. IMO, doing anything based on the pointer of an array being null is a huge code smell. In which case, == null is perfectly acceptable. I'm comparing my array to an empty array. What is confusing about that? I actually hate using the pointer in any aspect -- an array is semantically equivalent to its elements, it's not important where it's allocated. The only place D forces me to care about the pointer is when I'm dealing with ranges. So, perhaps the compiler is being pedantic, but it's still telling you the right thing. It's just insisting about it in the case where it matters less while not complaining aobut it in the case where it really matters, which is dumb. So IMHO, if anything, adding an error message for the array case would make more sense than getting rid of the error with pointers and references. I hope this never happens. -Steve
Re: is ==
On Monday, May 21, 2018 10:01:15 Steven Schveighoffer via Digitalmars-d- learn wrote: > On 5/18/18 9:48 PM, Jonathan M Davis wrote: > > Of > > course, the most notable case where using == with null is a terrible > > idea is dynamic arrays, and that's the case where the compiler > > _doesn't_ complain. > I use arr == null all the time. I'm perfectly fine with that, and > understand what it means. > > > Using == with null and arrays is always unclear about the programmer's > > intent and almost certainly wasn't what the programmer intended. > > I beg to differ. > > > If the > > programmer cares about null, they should use is. If they care about > > lengnth, then that's what they should check. Checking null with == is > > just a huge code smell. > > IMO, doing anything based on the pointer of an array being null is a > huge code smell. In which case, == null is perfectly acceptable. I'm > comparing my array to an empty array. What is confusing about that? > > I actually hate using the pointer in any aspect -- an array is > semantically equivalent to its elements, it's not important where it's > allocated. The only place D forces me to care about the pointer is when > I'm dealing with ranges. The core problem here is that no one reading a piece of code has any way of knowing whether the programmer knew what they were doing or not when using == null with an array, and the vast majority of newbies are not going to have understood the semantics properly. If I know that someone like you or Andrei wrote the code, then the odds are good that what the code does is exactly what you intended. But for the average D programmer? I don't think that it makes any sense to assume that, especially since anyone coming from another language is going to assume that == null is checking for null, when it's not. It's the same reason that if(arr) was temporarily out of the language. The odds are very high that the programmer using it is using it wrong. Andrei and Vladimir were using it correctly in their code, so they didn't like the fact that it had then become illegal, but while knew what they were doing and were using it correctly, plenty of other folks have been inserting bugs whenever they do that, and if I see if(arr) or assert(arr) in code, I'm going to consider it to be code smell just as much as I consider arr == null to be code smell. And yes, trying to treat the ptr as being null as special with a dynamic array is risky, and most code shouldn't be doing it, but you're almost forced to in some cases when interacting with C code, and clearly there are folks that do (e.g. Andrei and Vladimir). But even if we could unequivocably say that no one should be doing it, you still have no way of knowing whether someone is attempting it or not when they do arr == null, and since caring whether an array is null or not is a very typical thing to do in other languages where there is a very clear distinction between a null array and an empty one, plenty of folks come to D expecting to be able to do the same. And they're going to write arr == null or arr != null, and any time I see code like that, I'm going to have sit down and figure out whether they really meant arr is null, or whether they meant arr.length == 0, whereas if they had just written arr is null or arr.length == 0 (or arr.empty), their intent would have been perfectly clear. As such, I would strongly advise D programmers to use arr.empty or arr.length == 0 instead of arr == null, even if they know what they're doing, just like I would advise them to not treat null as special for arrays unless they really need to. At this point, I'm honestly inclined to think that we never should have allowed null for arrays. We should have taken the abstraction a bit further and disallowed using null to represent dynamic arrays. It would then presumably still work to do arr.ptr is null, but arr is null wouldn't work, because null wouldn't be an array, and arr == null definitely wouldn't work. Then we could just use [] for empty arrays everywhere, and there would be no confusion, leaving null for actual pointers. And it would almost certinly kill off all of the cases where null was treated as special for dynamic arrays except maybe for when dealing with C code, but in that case, they'd have to use ptr directly. However, at this point, I expect that that's all water under the bridge, and we're stuck with it. - Jonathan M Davis
Re: is ==
On 5/21/18 2:05 PM, Jonathan M Davis wrote: The core problem here is that no one reading a piece of code has any way of knowing whether the programmer knew what they were doing or not when using == null with an array, and the vast majority of newbies are not going to have understood the semantics properly. If I know that someone like you or Andrei wrote the code, then the odds are good that what the code does is exactly what you intended. But for the average D programmer? I don't think that it makes any sense to assume that, especially since anyone coming from another language is going to assume that == null is checking for null, when it's not. For me, the code smell is using arr is null (is it really necessary to check for a null pointer here?), for which I always have to look at more context to see if it's *really* right. Even people who write == null may want to check for null thinking that it's how you check an array is empty, not realizing that it *doesn't* check for a null pointer, *AND* it still does exactly what they need it to do ;) It's the same reason that if(arr) was temporarily out of the language. It's similar, but I consider it a different reason. While the intent of == null may not be crystal clear, 99% of people don't care about the pointer, they just care whether it's empty. So the default case is usually good enough, even if you don't know the true details. Whereas, if(arr) is checking that the pointer is null as well as the length is 0. Most people aren't expecting that, and those who are are like Andrei and Vladimir -- they know the quirks of the language here. For the longest time I thought it was just checking the pointer! I think aside from the clout of the ones who wanted it, the biggest reason that change was reverted was that it became really difficult to use an array inside a conditional. One-liners had to be extracted out, temporary variables defined. At this point, I'm honestly inclined to think that we never should have allowed null for arrays. We should have taken the abstraction a bit further and disallowed using null to represent dynamic arrays. It would then presumably still work to do arr.ptr is null, but arr is null wouldn't work, because null wouldn't be an array, and arr == null definitely wouldn't work. Then we could just use [] for empty arrays everywhere, and there would be no confusion, leaving null for actual pointers. And it would almost certinly kill off all of the cases where null was treated as special for dynamic arrays except maybe for when dealing with C code, but in that case, they'd have to use ptr directly. However, at this point, I expect that that's all water under the bridge, and we're stuck with it. If we never had null be the default value for an array, and used [] instead, I would be actually OK with that. I also feel one of the confusing things for people coming to the language is that arrays are NOT exactly reference types, even though null can be used as a value for assignment or comparison. But it still wouldn't change what most people write or mean, they just would write == [] instead of == null. I don't see how this would solve any of your concerns. -Steve
Re: is ==
On Monday, May 21, 2018 14:40:24 Steven Schveighoffer via Digitalmars-d- learn wrote: > On 5/21/18 2:05 PM, Jonathan M Davis wrote: > > The core problem here is that no one reading a piece of code has any way > > of knowing whether the programmer knew what they were doing or not when > > using == null with an array, and the vast majority of newbies are not > > going to have understood the semantics properly. If I know that someone > > like you or Andrei wrote the code, then the odds are good that what the > > code does is exactly what you intended. But for the average D > > programmer? I don't think that it makes any sense to assume that, > > especially since anyone coming from another language is going to assume > > that == null is checking for null, when it's not. > > For me, the code smell is using arr is null (is it really necessary to > check for a null pointer here?), for which I always have to look at more > context to see if it's *really* right. Really? I would never expect anyone to use is unless they really cared about whether array was null. I'd be concerned about whether the code in general was right, because treating null as special gets tricky, but that particular line wouldn't concern me. > Even people who write == null may want to check for null thinking that > it's how you check an array is empty, not realizing that it *doesn't* > check for a null pointer, *AND* it still does exactly what they need it > to do ;) You honestly expect someone first coming to D expect to check whether an array is empty by checking null? That's a bizarre quirk of D that I have never seen anyhwere else. I would never expect anyone to purposefully use == null to check for empty unless they were very familiar with D, and even then, I'd normally expect them to ask what they really mean, which is whether the array is empty. > > It's the same reason that > > > > if(arr) > > > > was temporarily out of the language. > > It's similar, but I consider it a different reason. While the intent of > == null may not be crystal clear, 99% of people don't care about the > pointer, they just care whether it's empty. So the default case is > usually good enough, even if you don't know the true details. I think that that's the key point of disagreement here. I would never consider the intent of == null to be crystal clear based solely on the code, because it is so common outside of D to use == null to actually check for null, and there are better ways in D to check for empty if that's what you really mean. My immediate expectation on seeing arr == null is that the programmer does not properly understand arrays in D. If I knew that someone like you wrote the code, I'd probably decide that you knew what you were doing and didn't make a mistake, but I'm not going to assume that in general, and honestly, I would consider it bad coding practice (though we obviously disagree on that point). I would consider the if(arr) and arr == null cases to be exactly the same. They both are red flags that the person in question does not understand how arrays in D work. Yes, someone who knows what they're doing may get it right, but I'd consider both to be code smells and I wouldn't purposefully do either in my own code. If I found either in my own code, I would expect that I'd just found a careless bug. > > At this point, I'm honestly inclined to think that we never should have > > allowed null for arrays. We should have taken the abstraction a bit > > further and disallowed using null to represent dynamic arrays. It would > > then presumably still work to do arr.ptr is null, but arr is null > > wouldn't work, because null wouldn't be an array, and arr == null > > definitely wouldn't work. Then we could just use [] for empty arrays > > everywhere, and there would be no confusion, leaving null for actual > > pointers. And it would almost certinly kill off all of the cases where > > null was treated as special for dynamic arrays except maybe for when > > dealing with C code, but in that case, they'd have to use ptr directly. > > However, at this point, I expect that that's all water under the > > bridge, and we're stuck with it. > > If we never had null be the default value for an array, and used [] > instead, I would be actually OK with that. I also feel one of the > confusing things for people coming to the language is that arrays are > NOT exactly reference types, even though null can be used as a value for > assignment or comparison. > > But it still wouldn't change what most people write or mean, they just > would write == [] instead of == null. I don't s
Re: is ==
On 5/21/18 3:20 PM, Jonathan M Davis wrote: On Monday, May 21, 2018 14:40:24 Steven Schveighoffer via Digitalmars-d- learn wrote: For me, the code smell is using arr is null (is it really necessary to check for a null pointer here?), for which I always have to look at more context to see if it's *really* right. Really? I would never expect anyone to use is unless they really cared about whether array was null. I'd be concerned about whether the code in general was right, because treating null as special gets tricky, but that particular line wouldn't concern me. Don't get me wrong, they probably *do* mean to check if it's null. But do they *need* to check? I'll borrow from your example below: if(arr != null && arr == arr2) Replace this with: if(arr !is null && arr == arr2) Does this look any better? I don't think so, it means the person didn't understand what an array actually is. Even though the second actually has some semantic meaning (the first is a no-op), it's likely not what the author intended. In most cases, when they check for null, they just want to check to see if the array is unset. The semantic meaning of this is usually that it's empty, they don't really care if it's actually null or not. In which case, checking for exact nullness is actually more expensive, and prone to problems. This comes from many languages where an array is an object type that defaults to null, and we reinforce that misconception by allowing null as a valid array literal. Even people who write == null may want to check for null thinking that it's how you check an array is empty, not realizing that it *doesn't* check for a null pointer, *AND* it still does exactly what they need it to do ;) You honestly expect someone first coming to D expect to check whether an array is empty by checking null? That's a bizarre quirk of D that I have never seen anyhwere else. I would never expect anyone to purposefully use == null to check for empty unless they were very familiar with D, and even then, I'd normally expect them to ask what they really mean, which is whether the array is empty. Reread what I said again. They *think* they need to check if it's null (it being the mythical Array object type that the language no doubt lowers to, just like it does in Java or C# or Swift or...), but really, they only need to check if it's empty. Which happens to be all they really need. For instance: int[] arr; if (cond) { ... arr = new int[5]; ... } if (arr == null) Now, you can certainly replace arr == null with arr is null, and the code works fine -- identically, even though it's more expensive. But to me, the arr is null is a red flag. Does the person know that they are checking for the ACTUAL value null? You still have to read the code to figure it out! I would say most times it's a bug waiting to happen. I can't imagine you just see "arr is null" and move on believing the author knew what they were doing. It's the same reason that if(arr) was temporarily out of the language. It's similar, but I consider it a different reason. While the intent of == null may not be crystal clear, 99% of people don't care about the pointer, they just care whether it's empty. So the default case is usually good enough, even if you don't know the true details. I think that that's the key point of disagreement here. I would never consider the intent of == null to be crystal clear based solely on the code, because it is so common outside of D to use == null to actually check for null, and there are better ways in D to check for empty if that's what you really mean. My immediate expectation on seeing arr == null is that the programmer does not properly understand arrays in D. If I knew that someone like you wrote the code, I'd probably decide that you knew what you were doing and didn't make a mistake, but I'm not going to assume that in general, and honestly, I would consider it bad coding practice (though we obviously disagree on that point). The fundamental reason why == null is generally OK is because generally the person doesn't distinguish between nullness and non-null but empty. Believe it or not, this is my position as well. Either works fine for their code, and in fact, when you analyze the code, checking for emptiness is really what they mean. Consider that new T[0] returns a null array. What happens if it returned a non-null array? Only code that uses "is null" would break. Code that uses == null would work fine. I would consider the if(arr) and arr == null cases to be exactly the same. They both are red flags that the person in question does not understand how arrays in D work. Yes, someone who knows what they're doing may get it right, but I'd consider both to be co
What is :-) ?
If I run this code ```d import std.stdio; void main(){ auto next = Counter(10); next().writeln; next().writeln; next().writeln; // What is "next" function? writeln( "'next' is ", next ); // What is "Counter" function? This fails // writeln( "'Counter' is ", Counter ); } auto Counter(int nextValue) => () => nextValue++; ``` Executing this code results in: ``` 10 11 12 'next' is int delegate() pure nothrow @nogc @safe ``` Now, I uncomment the ```writeln( "'Counter' is ", Counter );``` line and compiler says ``` /home/antonio/Devel/topbrokers/whatsapp-srv/admin/x.d(12): Error: function `x.Counter(int nextValue)` is not callable using argument types `()` /home/antonio/Devel/topbrokers/whatsapp-srv/admin/x.d(12): too few arguments, expected 1, got 0 ``` I understand the problem with UFCS (``next`` is not using UFCS because it is a delegate defined in the own main() function, and ``Counter``` without () is treated as a function call because it is UFCS eligible ) - What is the way to do ```writeln``` work with ```Counter``` function the same way it works with ```next``` function?
Re: ==, is
On Mon, 15 Nov 2010 14:06:34 -0500, Ellery Newcomer wrote: quick question: are the following rewrites always valid: e1 != e2 -> !(e1 == e2) e1 !is e2-> !(e1 is e2) e1 !in e2-> !(e1 in e2) I believe this is in fact what the compiler does (rewriting). -Steve
Re: ==, is
parser definitely does it for !in, but it doesn't for the other ones, and I didn't want to go digging all over the place for it. Also, spec says yes for !in, but is silent for the other ones On 11/15/2010 01:08 PM, Steven Schveighoffer wrote: On Mon, 15 Nov 2010 14:06:34 -0500, Ellery Newcomer wrote: quick question: are the following rewrites always valid: e1 != e2 -> !(e1 == e2) e1 !is e2 -> !(e1 is e2) e1 !in e2 -> !(e1 in e2) I believe this is in fact what the compiler does (rewriting). -Steve
Re: ==, is
On Mon, 15 Nov 2010 14:36:33 -0500, Ellery Newcomer wrote: parser definitely does it for !in, but it doesn't for the other ones, and I didn't want to go digging all over the place for it. Also, spec says yes for !in, but is silent for the other ones http://www.digitalmars.com/d/2.0/operatoroverloading.html#equals As far as is, it doesn't explicitly say that rewriting is done, but, it does spell out that to do the opposite, use !is. Maybe the spec should be updated to explicitly say x !is y is the same as !(x is y). http://www.digitalmars.com/d/2.0/expression.html#IdentityExpression On 11/15/2010 01:08 PM, Steven Schveighoffer wrote: On Mon, 15 Nov 2010 14:06:34 -0500, Ellery Newcomer wrote: quick question: are the following rewrites always valid: e1 != e2 -> !(e1 == e2) e1 !is e2 -> !(e1 is e2) e1 !in e2 -> !(e1 in e2) I believe this is in fact what the compiler does (rewriting). -Steve
Re: ==, is
On Monday 15 November 2010 11:47:11 Steven Schveighoffer wrote: > On Mon, 15 Nov 2010 14:36:33 -0500, Ellery Newcomer > > wrote: > > parser definitely does it for !in, but it doesn't for the other ones, > > and I didn't want to go digging all over the place for it. > > > > Also, spec says yes for !in, but is silent for the other ones > > http://www.digitalmars.com/d/2.0/operatoroverloading.html#equals > > As far as is, it doesn't explicitly say that rewriting is done, but, it > does spell out that to do the opposite, use !is. Maybe the spec should be > updated to explicitly say x !is y is the same as !(x is y). Honestly, I don't see how it could be otherwise. I would have just assumed that they were identical. - Jonathan M Davis
Re: ==, is
a while ago, I assumed that e1 += e2 gets rewritten as e1 = e1 + e2 Yeah. It doesn't. It doesn't even behave the same wrt erroneously typed arguments On 11/15/2010 02:35 PM, Jonathan M Davis wrote: As far as is, it doesn't explicitly say that rewriting is done, but, it does spell out that to do the opposite, use !is. Maybe the spec should be updated to explicitly say x !is y is the same as !(x is y). Honestly, I don't see how it could be otherwise. I would have just assumed that they were identical. - Jonathan M Davis
Re: ==, is
On Monday 15 November 2010 12:40:43 Ellery Newcomer wrote: > a while ago, I assumed that > > e1 += e2 > > gets rewritten as > > e1 = e1 + e2 > > Yeah. It doesn't. It doesn't even behave the same wrt erroneously typed > arguments Well, that would potentially be two different set of operator overloads (+= vs = and/or +), so they definitely can't act the same, though I can see why you'd think so at first glance. None of the operators that you specificy have that problem. Still, it pays to be careful. It can be easy to make erroneous assumptions. - Jonathan M Davis
Re: ==, is
On Mon, 15 Nov 2010 15:40:43 -0500, Ellery Newcomer wrote: a while ago, I assumed that e1 += e2 gets rewritten as e1 = e1 + e2 Yeah. It doesn't. It doesn't even behave the same wrt erroneously typed arguments I understand the care taken, but the spec gives reasons to believe otherwise: There is opAdd and opAddAssign There are opEquals and opIn, but no opNotEquals and opNotIn. If you can override the operators independently, naturally you should not expect that one is rewritten, otherwise why have the independent operators? Likewise, if there is no overload for the opposite, then it must be a rewriting function. 'is' is sorta different because you can't override it either way. -Steve
is pointer
(I am looking for rough corners in D, or in my knowledge of D.) In this page: http://www.digitalmars.com/d/2.0/templates-revisited.html In the section "Template Parameters" there is written: P:P*, // P must be a pointer type - So I have written this D2 program: template IsPointer1(T) { enum bool IsPointer1 = is(T : T*); } void main() { int* ptr; static assert(IsPointer1!(typeof(ptr))); // Err } But it asserts, do you know why? - Then I have written a different program: template IsPointer2(T) { enum bool IsPointer2 = is(typeof(*T)) || is(T == void*); } void main() { int* ptr; static assert(IsPointer2!(typeof(ptr))); // OK int[] arr; static assert(!IsPointer2!(typeof(arr))); // Err } Do you know why IsPointer2 is true for the dynamic array type too? (I know in std.traits of Phobos 2 there is an isPointer). Thank you, bye, bearophile
Re: What is PostgreSQL driver is most stable?
Dne 14.3.2017 v 14:13 Suliman via Digitalmars-d-learn napsal(a): I need to develop App that should work on Linux and Windows. It need PostgreSQL driver. I tried Vadim's ddbc for PostgreSQL but it's fail on x64 version of PostgreSQL and possible will not on x64 PG on Linux (I can't test it now). Could anybody advice me good driver without problems? I seen some pg-wrapers on code.dlang.ru, but do not have test all of them. ddbc works fine for me
Re: What is PostgreSQL driver is most stable?
On Tuesday, 14 March 2017 at 13:13:31 UTC, Suliman wrote: I need to develop App that should work on Linux and Windows. It need PostgreSQL driver. I tried Vadim's ddbc for PostgreSQL but it's fail on x64 version of PostgreSQL and possible will not on x64 PG on Linux (I can't test it now). Could anybody advice me good driver without problems? I seen some pg-wrapers on code.dlang.ru, but do not have test all of them. I'm using ddb [1], a full-D implementation of the PostgreSQL protocol. Not everything it's in place, but it does its works, and the codebase is pretty simple, so it's not difficult to contribute if you need to add some feature that's missing for your use case. [1] https://github.com/pszturmaj/ddb --- Paolo
Re: What is PostgreSQL driver is most stable?
On Tuesday, 14 March 2017 at 13:21:39 UTC, Paolo Invernizzi wrote: On Tuesday, 14 March 2017 at 13:13:31 UTC, Suliman wrote: I need to develop App that should work on Linux and Windows. It need PostgreSQL driver. I tried Vadim's ddbc for PostgreSQL but it's fail on x64 version of PostgreSQL and possible will not on x64 PG on Linux (I can't test it now). Could anybody advice me good driver without problems? I seen some pg-wrapers on code.dlang.ru, but do not have test all of them. I'm using ddb [1], a full-D implementation of the PostgreSQL protocol. Not everything it's in place, but it does its works, and the codebase is pretty simple, so it's not difficult to contribute if you need to add some feature that's missing for your use case. [1] https://github.com/pszturmaj/ddb --- Paolo Does it work fine on Linux with x64 Postgres?
Re: What is PostgreSQL driver is most stable?
Dne 14.3.2017 v 14:21 Daniel Kozak napsal(a): Dne 14.3.2017 v 14:13 Suliman via Digitalmars-d-learn napsal(a): I need to develop App that should work on Linux and Windows. It need PostgreSQL driver. I tried Vadim's ddbc for PostgreSQL but it's fail on x64 version of PostgreSQL and possible will not on x64 PG on Linux (I can't test it now). Could anybody advice me good driver without problems? I seen some pg-wrapers on code.dlang.ru, but do not have test all of them. ddbc works fine for me s/ddbc/ddb/
Re: What is PostgreSQL driver is most stable?
On Tuesday, 14 March 2017 at 13:32:31 UTC, Suliman wrote: On Tuesday, 14 March 2017 at 13:21:39 UTC, Paolo Invernizzi wrote: On Tuesday, 14 March 2017 at 13:13:31 UTC, Suliman wrote: [...] I'm using ddb [1], a full-D implementation of the PostgreSQL protocol. Not everything it's in place, but it does its works, and the codebase is pretty simple, so it's not difficult to contribute if you need to add some feature that's missing for your use case. [1] https://github.com/pszturmaj/ddb --- Paolo Does it work fine on Linux with x64 Postgres? Yes --- Paolo
Re: What is PostgreSQL driver is most stable?
On Tuesday, 14 March 2017 at 16:24:31 UTC, Paolo Invernizzi wrote: On Tuesday, 14 March 2017 at 13:32:31 UTC, Suliman wrote: On Tuesday, 14 March 2017 at 13:21:39 UTC, Paolo Invernizzi wrote: On Tuesday, 14 March 2017 at 13:13:31 UTC, Suliman wrote: [...] I'm using ddb [1], a full-D implementation of the PostgreSQL protocol. Not everything it's in place, but it does its works, and the codebase is pretty simple, so it's not difficult to contribute if you need to add some feature that's missing for your use case. [1] https://github.com/pszturmaj/ddb --- Paolo Does it work fine on Linux with x64 Postgres? Yes --- Paolo We used dpq. http://code.dlang.org/packages/dpq
Re: What is PostgreSQL driver is most stable?
On Wednesday, 15 March 2017 at 08:50:11 UTC, Dsby wrote: On Tuesday, 14 March 2017 at 16:24:31 UTC, Paolo Invernizzi wrote: On Tuesday, 14 March 2017 at 13:32:31 UTC, Suliman wrote: On Tuesday, 14 March 2017 at 13:21:39 UTC, Paolo Invernizzi wrote: On Tuesday, 14 March 2017 at 13:13:31 UTC, Suliman wrote: [...] I'm using ddb [1], a full-D implementation of the PostgreSQL protocol. Not everything it's in place, but it does its works, and the codebase is pretty simple, so it's not difficult to contribute if you need to add some feature that's missing for your use case. [1] https://github.com/pszturmaj/ddb --- Paolo Does it work fine on Linux with x64 Postgres? Yes --- Paolo We used dpq. http://code.dlang.org/packages/dpq I'm curious: ddb does not support yet arbitrary precision numbers [1], does dpq support them? Thanks, Paolo [1] https://www.postgresql.org/docs/9.5/static/datatype-numeric.html#DATATYPE-NUMERIC-DECIMAL
Re: What is PostgreSQL driver is most stable?
On Tuesday, 14 March 2017 at 13:36:04 UTC, Daniel Kozak wrote: Dne 14.3.2017 v 14:21 Daniel Kozak napsal(a): Dne 14.3.2017 v 14:13 Suliman via Digitalmars-d-learn napsal(a): I need to develop App that should work on Linux and Windows. It need PostgreSQL driver. I tried Vadim's ddbc for PostgreSQL but it's fail on x64 version of PostgreSQL and possible will not on x64 PG on Linux (I can't test it now). Could anybody advice me good driver without problems? I seen some pg-wrapers on code.dlang.ru, but do not have test all of them. ddbc works fine for me s/ddbc/ddb/ Am I rightn understand that DBRow! is allow to get only single row, and if I need array of rows I need to use foreach? If I am wrong could you provide an example please.
Re: What is PostgreSQL driver is most stable?
On Wednesday, 15 March 2017 at 09:18:16 UTC, Suliman wrote: On Tuesday, 14 March 2017 at 13:36:04 UTC, Daniel Kozak wrote: Dne 14.3.2017 v 14:21 Daniel Kozak napsal(a): Dne 14.3.2017 v 14:13 Suliman via Digitalmars-d-learn napsal(a): I need to develop App that should work on Linux and Windows. It need PostgreSQL driver. I tried Vadim's ddbc for PostgreSQL but it's fail on x64 version of PostgreSQL and possible will not on x64 PG on Linux (I can't test it now). Could anybody advice me good driver without problems? I seen some pg-wrapers on code.dlang.ru, but do not have test all of them. ddbc works fine for me s/ddbc/ddb/ Am I rightn understand that DBRow! is allow to get only single row, and if I need array of rows I need to use foreach? If I am wrong could you provide an example please. The retrieval of records is done via the execution of a (prepared) sql query, that returns a range object (PGResultSet), and the element of that range is the DBRow, in one of its form. So, basically, the elements are retrieved on demand while you popFront that range, leveraging what the PostgreSQL stream protocol provide. --- Paolo
Re: What is PostgreSQL driver is most stable?
The retrieval of records is done via the execution of a (prepared) sql query, that returns a range object (PGResultSet), and the element of that range is the DBRow, in one of its form. So, basically, the elements are retrieved on demand while you popFront that range, leveraging what the PostgreSQL stream protocol provide. --- Paolo Could you give an example when it's better to use DBRow and where to get data in structure?
Re: What is PostgreSQL driver is most stable?
On 2017-03-14 14:32, Suliman wrote: Does it work fine on Linux with x64 Postgres? I've tested it on macOS and Linux 64bit. Works great. -- /Jacob Carlborg
Re: What is PostgreSQL driver is most stable?
On 2017-03-15 15:08, Suliman wrote: Could you give an example when it's better to use DBRow and where to get data in structure? Use PGCommand and call "executeQuery" to get back a result set that is iteratable: auto query = "SELECT * FROM foos" auto cmd = new PGCommand(connection, query); auto resultSet = cmd.executeQuery!(string, int); // these types are the column types foreach (row ; resultSet) { auto name = row["name"]; auto bar = row[1]; // use the column name or index to get the value from a row } resultSet.close(); // the result set needs to be closed to be able to execute additional queries You can also directly create structs out of the rows: struct Foo { string name; string bar; } auto resultSet = cmd.executeQuery!(typeof(Foo.tupleof)); foreach (row ; resultSet) { auto foo = Foo(row[0 .. Foo.tupleof.length]); assert(foo.name == row["name"]); } executeQuery - for returning a set of rows executeRow - for returning a single executeNonQuery - for executing a query without any result See the examples for more information [1]. [1] https://github.com/pszturmaj/ddb/blob/master/examples/basic.d -- /Jacob Carlborg
Re: What is PostgreSQL driver is most stable?
On Wednesday, 15 March 2017 at 08:54:59 UTC, Paolo Invernizzi wrote: I'm curious: ddb does not support yet arbitrary precision numbers [1], does dpq support them? Does Dlang supports them?
Re: Is it std.regex, or is it me.
A file stream would be another example of a thing that can't be naturally const even if you opened it for reading.
Re: Is it std.regex, or is it me.
On Monday, March 20, 2017 14:36:32 Russel Winder via Digitalmars-d-learn wrote: > Given the following, where X and Y mark the spot: > > X epochRegex = regex("([0-9])+:"); > Y aEpochCapture = matchFirst(aVersionString, epochRegex); > Y bEpochCapture = matchFirst(bVersionString, epochRegex); > > If X or Y are const or immutable the code fails to compile. Only if > both X and Y are auto does this code compile. So question to the > audience: how do you do single assignment programming in D? Is it, in > fact, impossible to program with bindings rather than variables in D? > > And yes this does seem to be a violation of the Principle of Least > Surprise. They're variables even if they're const or immutable. To avoid having a variable, you'd need to use enum, which would then require that it work at compile time. In general though, making things const or immutable requires a lot of extra copying in order to make it work, so I don't think that it's all that surprising when something doesn't work with them. Code _can_ be made to work with const and immutable; it's just that there's often a significant cost to doing so. And since D's const and immutable are transitive and don't have backdoors, you can't get around them like you would in C++ (where on some level, const is actually a lie, albeit a convenient one). So, a lot of the time, folks simply don't bother to make their code work with const. What the deal with std.regex is, I don't know, since I've never done much with it, but if ranges are involved, then const definitely doesn't work, because D's const and ranges are pretty much fundamentally incompatible. Ranges mutate in order to iterate. In order to get around that, we'd need a generic way to get a tail-const version of a range, which we definitely don't have. It works with dynamic arrays, because the compiler understands those, but it would be a much more difficult thing to sort out with a user-defined type and would almost certainly require a language change to do so. But ranges aside, I would expect code that worked well with const or immutable to be written specifically with them in mind rather than just happening to work with them. - Jonathan M Davis
Is std.xml seriously broken, or is it me?
I'm trying to use std.xml, and I can't get it to work. I tried the simplest program I could think of: import std.xml; import std.stdio; void main() { auto parser = new DocumentParser("encoding=\"utf-8\"?>"); parser.onStartTag["device"] = (ElementParser parser) { writeln("device"); }; parser.parse(); } https://dpaste.dzfl.pl/262597d2fda6 I used it before without any trouble. Is it somehow seriously broken? If not, what am I doing wrong? Thanks, Mike
Re: Is is a Bug or just me?
On Friday, 8 May 2020 at 14:16:10 UTC, foerdi wrote: Now I am unsure if this is a bug or an undefined behavior that I don't know. This is a regression, and a potentially pretty bad one, so thx for tracking it down! If this is a bug, then I don't know how to call it for the bug tracker. Maybe something like 'return statement might access memory from destructed temporary'.
Re: Is is a Bug or just me?
On Friday, 8 May 2020 at 14:32:33 UTC, kinke wrote: On Friday, 8 May 2020 at 14:16:10 UTC, foerdi wrote: Now I am unsure if this is a bug or an undefined behavior that I don't know. This is a regression, and a potentially pretty bad one, so thx for tracking it down! If this is a bug, then I don't know how to call it for the bug tracker. Maybe something like 'return statement might access memory from destructed temporary'. Thanks, I filed a regression: https://issues.dlang.org/show_bug.cgi?id=20809
Re: Is is a Bug or just me?
On Friday, 8 May 2020 at 14:16:10 UTC, foerdi wrote: Hi d community, I got a strange behavior since dmd 2.090 (dmd 2.089 is the last working version). See this reduced code: https://run.dlang.io/is/yoyHXC I would expect that foo() returns 2. My guess in foo is: The return value of val is saved locally as a ref int and then the destructor of S is called (set the local cache to 0). Now the ref value is dereferenced and returned. Now I am unsure if this is a bug or an undefined behavior that I don't know. If this is a bug, then I don't know how to call it for the bug tracker. I hope you can help me with this problem. PS: This is only tested on my Linux system and on run.dlang.io. - foerdi Gets even weirder because this fixes it LOL??? int foo() out { } do { return bar.val; } What the??
Re: double.init is real.nan, is it a bug?
On Thursday, August 15, 2013 06:01:21 bsd wrote: > Hi all, > > > I think this is a bug, but if not I'm very confused and would > like some clarification. > > When checking double values that could be nan or unassigned I > have to check both double.init and double.nan. But double.init IS > double.nan. > > --- > void main() { > // passes but I believe it is checked during compile > assert(double.init is double.nan); > > double val; > std.stdio.writeln( to!string(val) ); // writes "nan" to > console > assert(val is double.init); // passes > assert(val is double.nan); // << FAILS (unexpectedly for me > anyway) > } > --- > > Why does assert(val is double.nan) fail? Given: > > a) double.init is double.nan > b) val is double.init > c) to!string(val) sees val as a nan There are multiple values for NaN. It's still a bit surprising to me that assert(val is double.nan) failed, but as long as val is still one of the values for NaN, it shouldn't matter. It wouldn't have been at all suprising though if you had two different NaNs which were generated through arithmetic which didn't match. In general, you can't rely on the bit pattern for NaN. > I also found this confusing: > --- > void main() { > > assert(double.init is double.nan); // passes expected > > assert(double.init is float.init); // passes, unexpected > assert(double.init is real.init); // passes, unexpected > > assert(double.init is real.nan); // passes, unexpected > assert(double.init is float.nan); // passes, unexpected > > } > --- > I don't think these should be passing...should they?? To do the comparison, the same size types must be compared, so the smaller floating point types are promoted to the larger type in the expression, and evidently, promoting the init value of a smaller floating point value gives you the same value as the init value of the larger floating point value. - Jonathan M Davis
Re: double.init is real.nan, is it a bug?
On Thursday, 15 August 2013 at 04:01:28 UTC, bsd wrote: Hi all, I think this is a bug, but if not I'm very confused and would like some clarification. When checking double values that could be nan or unassigned I have to check both double.init and double.nan. But double.init IS double.nan. --- void main() { // passes but I believe it is checked during compile assert(double.init is double.nan); double val; std.stdio.writeln( to!string(val) ); // writes "nan" to console assert(val is double.init); // passes assert(val is double.nan); // << FAILS (unexpectedly for me anyway) } --- Why does assert(val is double.nan) fail? Given: a) double.init is double.nan b) val is double.init c) to!string(val) sees val as a nan I also found this confusing: --- void main() { assert(double.init is double.nan); // passes expected assert(double.init is float.init); // passes, unexpected assert(double.init is real.init); // passes, unexpected assert(double.init is real.nan); // passes, unexpected assert(double.init is float.nan); // passes, unexpected } --- I don't think these should be passing...should they?? I'm on fedora 19, dmd 2.063.2 extracted from the ZIP Thanks There is the issue with order on is. Try reversing them and see if you get the same results. I imagine for floats and doubles are interchangeable for nans(both are nan, regardless of the encoding used).
Re: double.init is real.nan, is it a bug?
On Thursday, 15 August 2013 at 05:12:35 UTC, Jonathan M Davis wrote: On Thursday, August 15, 2013 06:01:21 bsd wrote: Hi all, There are multiple values for NaN. It's still a bit surprising to me that assert(val is double.nan) failed, but as long as val is still one of the values for NaN, it shouldn't matter. It wouldn't have been at all suprising though if you had two different NaNs which were generated through arithmetic which didn't match. In general, you can't rely on the bit pattern for NaN. I also found this confusing: --- void main() { assert(double.init is double.nan); // passes expected assert(double.init is float.init); // passes, unexpected assert(double.init is real.init); // passes, unexpected assert(double.init is real.nan); // passes, unexpected assert(double.init is float.nan); // passes, unexpected } --- I don't think these should be passing...should they?? To do the comparison, the same size types must be compared, so the smaller floating point types are promoted to the larger type in the expression, and evidently, promoting the init value of a smaller floating point value gives you the same value as the init value of the larger floating point value. - Jonathan M Davis This explains why (double.nan is float.nan) && (double.nan is real.nan). I understand that now, thanks. I found std.math.isNaN in just after I posted, I really should read the docs first :D For some reason I thought ('var' is double.nan) did this isNaN check, sort of like (key in AA) ... but 'in' is in and 'is' is, well, just is. Thanks for the help.
Re: double.init is real.nan, is it a bug?
On Thursday, August 15, 2013 08:20:01 bsd wrote: > For some reason I thought ('var' is double.nan) did this isNaN > check, sort of like (key in AA) ... but 'in' is in and 'is' is, > well, just is. The is operate does a bitwise comparison, so it's checking whether the bits are identical or not. The primary place that it's used is comparing pointers. Beyond that, its use should probably be fairly rare as in most cases, what you want is ==. - Jonathan M Davis
balancedParens is not nothrow bug, is this known?
import std.path; void main(string[] args) { globMatch("foo.bar", "*"); } compile with: dmd -profile test.d Error: /usr/share/dmd/src/phobos/std/path.d(2187): Error: balancedParens is not nothrow /usr/share/dmd/src/phobos/std/path.d(2188): Error: balancedParens is not nothrow a). Is this bug known? b). Is this fixed in the latest release, i'm using 2.063.2.
Re: is(T : long) vs is(T == long)
On 3/26/11 12:36 PM, Caligo wrote: What is the difference between this: template isNumerik(T){ enum bool isNumerik = is(T : long) || is(T : real); } and this: template isNumerik(T){ enum bool isNumerik = is(T == long) || is(T == real); } They both work and I can't find anywhere in the book where it talks about the : When in doubt, RTFM: http://digitalmars.com/d/2.0/expression.html#IsExpression (Using the colon allows implicit conversion, while == requires the types to be exactly the same) David
Re: is(T : long) vs is(T == long)
:-) thanks.
Parameter is null by default. No value is given. Code says it is not null.
I have written a function as follows: public bool setCookie( string name, string value, long maxAgeInSeconds = long.min, string expiresOnGMTDate=null, string path=null, string domain=null, bool secure=false ) shared{ // if headers are sent already, leave if( headersSent ) return false; // name cannot be empty if( (name is null) || (name.length <= 0) ) return false; writeln( "Name: ", name, " Max Age: ", maxAgeInSeconds, " Expires null: ", (expiresOnGMTDate == null), " Path equals null: ", (path == null), " Domain null: ", (domain is null) ); return true; } Here is the testing code: responseObject.setCookie( "A", "B" ); auto now = std.datetime.Clock.currTime().toSimpleString(); //writeln("Now |", now, "|"); responseObject.setCookie( "Response Time", now ); Here is the results: Name: A Max Age: -9223372036854775808 Expires null: true Path equals null: true Domain null: true Name: Response Time Max Age: -9223372036854775808 Expires null: true Path equals null: false Domain null: false I don't know what is happening though, somehow path and domain parameters in second use of function are not null even I haven't given any value to them. If I uncomment the "writeln" line in test code, it turns normal. I am so much confused right now. What is happening here?
Is it safe to use 'is' to compare types?
Will typeid(a) is typeid(b) yield different results than typeid(a) == typeid(b)?
Which application is much suited and which is not.
Let's say you have decided to use D programming language. For what kind of applications would you choose D programming language and For what kind of applications you won't choose D programming.
Re: Is std.xml seriously broken, or is it me?
On Sunday, 30 July 2017 at 02:58:09 UTC, Mike wrote: import std.xml; import std.stdio; void main() { auto parser = new DocumentParser("encoding=\"utf-8\"?>"); parser.onStartTag["device"] = (ElementParser parser) { writeln("device"); }; parser.parse(); } https://dpaste.dzfl.pl/262597d2fda6 I used it before without any trouble. Is it somehow seriously broken? If not, what am I doing wrong? It appears `onStartTag` does not handle the root element. For example, this code seems to work: import std.xml; import std.stdio; void main() { auto parser = new DocumentParser("encoding=\"utf-8\"?>"); parser.onStartTag["peripheral"] = (ElementParser parser) { writeln("peripheral"); }; parser.parse(); } Mike
Re: Is std.xml seriously broken, or is it me?
On Sunday, 30 July 2017 at 02:58:09 UTC, Mike wrote: I'm trying to use std.xml, and I can't get it to work. I tried the simplest program I could think of: import std.xml; import std.stdio; void main() { auto parser = new DocumentParser("encoding=\"utf-8\"?>"); parser.onStartTag["device"] = (ElementParser parser) { writeln("device"); }; parser.parse(); } https://dpaste.dzfl.pl/262597d2fda6 I used it before without any trouble. Is it somehow seriously broken? If not, what am I doing wrong? Thanks, Mike I don't know about your code specifically, but std.xml has been on the chopping block for many years and is pretty much still around because nobody has written a replacement yet. I'd recommend using Adam Ruppe's DOM library instead: https://github.com/adamdruppe/arsd/blob/master/dom.d
Re: Is std.xml seriously broken, or is it me?
On Sunday, 30 July 2017 at 03:16:35 UTC, Mike wrote: On Sunday, 30 July 2017 at 02:58:09 UTC, Mike wrote: [...] It appears `onStartTag` does not handle the root element. For example, this code seems to work: import std.xml; import std.stdio; void main() { auto parser = new DocumentParser("encoding=\"utf-8\"?>"); parser.onStartTag["peripheral"] = (ElementParser parser) { writeln("peripheral"); }; parser.parse(); } Mike You may want to try the experimental candidate for Phobos instead, which was developed as a GSoC project but never finished: http://code.dlang.org/packages/std-experimental-xml
Re: Is std.xml seriously broken, or is it me?
On Sunday, 30 July 2017 at 03:16:35 UTC, Mike wrote: It appears `onStartTag` does not handle the root element. Looks like a bug. Until the module is replaced, bug reports are still accepted for it.
if (X !is null && X.Y !is null) access crash
I don't understand why if (X !is null && X.Y !is null) access crash is crashing. It is true that it is being used in a thread. It happens when I close down my app. The whole point of the check is to make sure X is not null but it seems to be failing. The debugger is showing X is not null yet X.Y is null. (Y is a delegate) I believe this is because I'm not using shared(which causes problems with orange serdes) and the GC. I'm not sure though.
Re: balancedParens is not nothrow bug, is this known?
On Friday, 8 November 2013 at 14:07:38 UTC, Gary Willoughby wrote: import std.path; void main(string[] args) { globMatch("foo.bar", "*"); } compile with: dmd -profile test.d Error: /usr/share/dmd/src/phobos/std/path.d(2187): Error: balancedParens is not nothrow /usr/share/dmd/src/phobos/std/path.d(2188): Error: balancedParens is not nothrow a). Is this bug known? b). Is this fixed in the latest release, i'm using 2.063.2. Found it: https://d.puremagic.com/issues/show_bug.cgi?id=10295
Re: balancedParens is not nothrow bug, is this known?
On Friday, 8 November 2013 at 14:15:05 UTC, Gary Willoughby wrote: Found it: https://d.puremagic.com/issues/show_bug.cgi?id=10295 With that said, anyone have any idea when this is gonna get fixed? Otherwise the profiler is useless for me.
Re: balancedParens is not nothrow bug, is this known?
On Friday, 8 November 2013 at 14:07:38 UTC, Gary Willoughby wrote: import std.path; void main(string[] args) { globMatch("foo.bar", "*"); } compile with: dmd -profile test.d Error: /usr/share/dmd/src/phobos/std/path.d(2187): Error: balancedParens is not nothrow /usr/share/dmd/src/phobos/std/path.d(2188): Error: balancedParens is not nothrow a). Is this bug known? b). Is this fixed in the latest release, i'm using 2.063.2. Can it be nothrow? It might encounter unicode exceptions.
Re: balancedParens is not nothrow bug, is this known?
simendsjo: Can it be nothrow? It might encounter unicode exceptions. I think -profile should not influence the exception tree analysis. So it seems a bug. And there are probably some dupes: https://d.puremagic.com/issues/buglist.cgi?quicksearch=profile+nothrow Bye, bearophile
Re: balancedParens is not nothrow bug, is this known?
On Friday, 8 November 2013 at 14:17:03 UTC, Gary Willoughby wrote: With that said, anyone have any idea when this is gonna get fixed? Otherwise the profiler is useless for me. In fact i might give it a shot.
Is "is" the same as ptr == ptr for arrays?
Is the following equalent? int[] a; int[] b = a; assert(a is b); assert(a.ptr == b.ptr);
Why is the Win32 boilerplate the way it is?
I found an example of boilerplate code for Win32 programming in D here: http://wiki.dlang.org/D_for_Win32 I have some questions. 1. It appears that the call to myWinMain from WinMain is to ensure that any exception or error is caught. At first glance it looks like this is to ensure that runtime.terminate() gets called, but in fact it doesn't, the catch block doesn't do it and there is no scope(exit). Is this a problem? (And what would happen if you didn't catch the exception?) 2. Why does the boilerplate return 0 on success and failure? (If the return code is irrelevant, why the comment that says "failed" next to the return code?) 3. I can't imagine a technical reason why the myWinMain signature has to match the WinMain signature. Wouldn't it be better to omit the hPrevInstance since it isn't used? (Or are we preserving backwards compatibility with Win16?). If there is a resource somewhere that explains all this I would happy to consult it but I couldn't find anything. Thanks.
Where is sleep()?
Hey guys. First time poster here. I've searched high and low but can't seem to find a simple sleep/delay/wait/pause function in the core or in phobos. The most recent information I can find about it is this forum post from 12 years ago: http://forum.dlang.org/thread/avr99b$b8j$2...@digitaldaemon.com In which they suggest using std.c.time which is now depreciated and seems to have been replaced by core.stdc.time which doesn't have any sleep functions... What am I missing?
is it regression?
https://run.dlang.io/is/HJxtvw ``` import std.stdio, std.typecons, std.math; void main() { auto foo = nullable(2.0); auto bar = nullable(2.0); assert (foo.approxEqual(bar)); } ``` Comiling gives the following: Up to 2.067.1: Failure with output: - onlineapp.d(4): Error: undefined identifier nullable, did you mean struct Nullable(T)? onlineapp.d(5): Error: undefined identifier nullable, did you mean struct Nullable(T)? - 2.068.2 to 2.072.2: Failure with output: - onlineapp.d(4): Error: undefined identifier 'nullable', did you mean struct 'Nullable(T)'? onlineapp.d(5): Error: undefined identifier 'nullable', did you mean struct 'Nullable(T)'? - 2.073.2 to 2.077.1: Success and no output Since 2.078.1: Failure with output: - /path/to/dmd.linux/dmd2/linux/bin64/../../src/phobos/std/math.d(7575): Error: template std.math.approxEqual cannot deduce function from argument types !()(Nullable!double, Nullable!double, double, double), candidates are: /path/to/dmd.linux/dmd2/linux/bin64/../../src/phobos/std/math.d(7499): std.math.approxEqual(T, U, V)(T lhs, U rhs, V maxRelDiff, V maxAbsDiff = 1e-05) if ((isNumeric!T || isInputRange!T && isNumeric!(ElementType!T)) && (isNumeric!U || isInputRange!U && isNumeric!(ElementType!U)) && isNumeric!V) /path/to/dmd.linux/dmd2/linux/bin64/../../src/phobos/std/math.d(7573): std.math.approxEqual(T, U)(T lhs, U rhs) onlineapp.d(7): Error: template instance std.math.approxEqual!(Nullable!double, Nullable!double) error instantiating - tldr - std.math.approxEqual stops deduced its args type when Nullable is used.
Is HibernateD dead?
Last commit on https://github.com/buggins/hibernated was almost a year ago So what is the status of HibernateD?Should I use it if I need an ORM? Or would I risk unpatched security risks?
Is DWT busted?
I'm sorry about bringing this into here instead of DWT's subforum, but it's somewhat dead and hasn't been getting a lot of attention. I decided to finally play around with DWT today and tried to build the example. I got this: Performing "debug" build using /usr/bin/dmd for x86_64. dwt:base 1.0.1+swt-3.4.1: target for configuration "library" is up to date. dwt 1.0.1+swt-3.4.1: target for configuration "linux-gtk" is up to date. main ~master: building configuration "application"... Linking... To force a rebuild of up-to-date targets, run again with --force. Running ./main Program exited with code -11 I'm on Pop!_OS (basically Ubuntu), x64, DMD 2.079.0. Every library they ask for is installed. I tried cloning the source and building their snippets, and none of them work. Other people have apparently had this same problem for the past few months, and none of them find a solution. What's going on here? IDK if this is any help, but here's the backtrace according to gdb: https://pastebin.com/Xd46YwwP
std.regex is fat
Like, insanely fat. All I wanted was a simple regex. The second include a regex function, my program would no longer compile "out of memory for fork". /usr/bin/time -v reports it went from 150MB of RAM for D, DAllegro, and Allegro5. To over 650MB of RAM, and from 1.5 seconds to >5.5 seconds to compile. Now I have to close all my Chrome tabs just to compile. Just for one line of regex. And I get it, it's the overhead of the library import, not the single line. But good gosh, more than 3X the RAM of the entire project for a single library import? Something doesn't add up!
this is null
Hello everyone! I've encountered the problem which I already encountered before. Unfortunately, I had no time in the previous time to report and to talk about it. So I decided to play making my own "malloc" function in pure D (betterC) at this time. And I encountered the issue one more time. `this` can be null. How? Please take a look at my project [0]. It gets the current heap break and tries to increase via a free list. So the segfault I meet happens there [1]. Tell me, please. What do I wrong? [0] https://github.com/ANtlord/deadmemory [1] https://github.com/ANtlord/deadmemory/blob/master/src/deadmemory/freelist.d#L56
dpaste.dzfl.pl is blocked
What are alternatives for it? Thanks.
`finally` is redundant?
The page http://dlang.org/exception-safe.html says: "It's try-finally that becomes redundant." IIUC this is because we have scope(exit). Does this mean that `finally` should eventually be removed from the language? -- Shriramana Sharma, Penguin #395953
Is stdout.flush() unsafe?
Trying to compile this: void main() @safe { import std.stdio; stdout.flush(); } Fails with this message: Error: safe function 'main' cannot access __gshared data 'stdout' Is this necessary? If so, what are the synchronization requirements for access to `stdout`?
is std.algorithm.joiner lazy?
Hi: when I use map with joiner, I found that function in map are called. In the document it says joiner is lazy, so why is the function called? say: int[] mkarray(int a) { writeln("mkarray called!"); return [a * 2]; // just for test } void main() { auto xs = [1, 2]; auto r = xs.map!(x=>mkarray(x)).joiner; } running this will get the output: mkarray called! mkarray called! I suppose joiner does not consume? when I actually consume the result by writlen, I get more output: mkarray called! mkarray called! [2mkarray called! mkarray called! , 4] I don't understand
is there "this"?
The question is simple. Is there something like "this" word for classes? For example: ``` class CLS { int numberValue; public this(numberValue) { // how can I put the local numberValue to class property? // in some prog language I can do like: // this.numberValue = numberValue; } } ```
staticIota is easy
I thought I needed something like staticIota in a unittest to effect static foreach over a number range and I found one in druntime's implementation: https://github.com/dlang/druntime/blob/master/src/core/internal/traits.d#L106 (I wonder why that one is implemented in divide-and-conquer fashion. Perhaps due to faster compilation that way?) Then I realized that this is actually pretty easy with D: template staticIota(size_t N) { import std.range: iota; import std.meta: aliasSeqOf; alias staticIota = aliasSeqOf!(N.iota); } unittest { size_t count = 0; foreach (i; staticIota!10) { mixin("++count;"); } assert(count == 10); } void main() { } I realized that I don't actually need it but I wanted to share. :) Ali P.S. Related, I've been using D for a living since I started working for Weka.IO in June. (I think the only mention of that was in this blog post: https://dlang.org/blog/2016/06/). The more I use D, the more I like it but you already know it. ;)
Is D slow?
Hi guys, I wrote a toy benchmark in C++ [1] and tried to literally translate it to D [2]. The results are quite disappointing. What seems particularly strange to me is that -boundscheck=off leads to a performance decrease. Am I missing anything? // $ clang++ -std=c++1z -O3 cmp-bench.cpp // $ time ./a.out // 501 // // real 0m2.777s // user 0m2.774s // sys 0m0.004s // // // $ clang++ --version // clang version 4.0.0 (tags/RELEASE_400/final) // Target: x86_64-unknown-linux-gnu // Thread model: posix // InstalledDir: /usr/bin // $ ldc2 -O3 -release cmp-bench.d // $ time ./cmp-bench // 501 // // real 0m5.257s // user 0m5.224s // sys 0m0.000s // // // $ ldc2 -O3 -release -boundscheck=off cmp-bench.d // $ time ./cmp-bench // 501 // // real 0m11.083s // user 0m11.083s // sys 0m0.000s // // // $ ldc2 --version // LDC - the LLVM D compiler (1.2.0): // based on DMD v2.072.2 and LLVM 4.0.0 // built with DMD64 D Compiler v2.074.0 // Default target: x86_64-unknown-linux-gnu // Host CPU: haswell [1] C++ Insertion Sort - https://dpaste.dzfl.pl/74fdb92a0579 [2] D Insertion Sort - https://dpaste.dzfl.pl/b97a1fca1546
is it bug?
https://run.dlang.io/is/uk0CMC
is(this : myClass)
The compiler seems to reject the following code in a class method: bool test = is(this : myClass); Could some please explain this? Thanks, Patrick
Is variable void?
Is there any way of determining whether a variable has been initialized or not? For example, if something is declared like this: int x = void; can I check if it's void before I use it, say, in a function it's been passed to?
What is "stringImportPaths"
Can anyone explain what "stringImportPaths" is? I have seen this being used in dub.json files and I think I kind of know what it does, but I haven't been able to find a clear explanation in any documentation of what it does. It does not look like anything I'm familiar with from other languages. I understand it can be used for resources but I have seen it being used with both text files and binary files so I'm a bit confused. The documentation says I can import "whatever", but that feels a bit weird since importing is a construct used for importing symbols, right?
Re: What is :-) ?
On Monday, 20 November 2023 at 08:47:34 UTC, Antonio wrote: Now, I uncomment the ```writeln( "'Counter' is ", Counter );``` line and compiler says ``` /home/antonio/Devel/topbrokers/whatsapp-srv/admin/x.d(12): Error: function `x.Counter(int nextValue)` is not callable using argument types `()` /home/antonio/Devel/topbrokers/whatsapp-srv/admin/x.d(12): too few arguments, expected 1, got 0 ``` I understand the problem with UFCS (``next`` is not using UFCS because it is a delegate defined in the own main() function, and ``Counter``` without () is treated as a function call because it is UFCS eligible ) `writeln( "'Counter' is ", Counter );` this code is actually internally looks like this `writeln( "'Counter' is ", Counter() );` if you meant to take the function/delegate and not invoke try `&Counter` instead, otherwise it expects the parameters. - What is the way to do ```writeln``` work with ```Counter``` function the same way it works with ```next``` function? Sorry, that's too confusing and I have no idea what you mean, maybe if you can explain what you are trying to achieve someone might be able to help you.
Re: What is :-) ?
On Monday, 20 November 2023 at 09:11:07 UTC, evilrat wrote: if you meant to take the function/delegate and not invoke try `&Counter` instead, otherwise it expects the parameters. If you execute ``` writeln( "'Counter' is ", &Counter ); ``` It shows the Counter address: ``` 'Counter' is 557F2567F940 ``` Not the function signature like it does with ```next``` I propose a simple change: ```d void main(){ auto Counter = (int nextValue) => () => nextValue++; auto next = Counter(10); writeln( "'next' is ", next ); writeln( "'Counter' is ", Counter ); } ``` first ```writeln``` shows the signature of next: ``` 'next' is int delegate() pure nothrow @nogc @safe ``` second writeln shows the address of Counter ``` 'Counter' is 55568953C910 ``` - Why writeln doesn't treat ```next``` and ```Counter``` the same way? (I think I understand why, but it shows a "low" level difference of something that syntactically is equivalent) - What is the way to show Counter signature using ```writeln``` (if possible)? ```
Re: What is :-) ?
On Monday, 20 November 2023 at 09:44:32 UTC, Antonio wrote: - Why writeln doesn't treat ```next``` and ```Counter``` the same way? (I think I understand why, but it shows a "low" level difference of something that syntactically is equivalent) - What is the way to show Counter signature using ```writeln``` (if possible)? I found no way to tell compiler that I don't want to call Counter and instead want to take the function itself, but closest thing is just to take the string representation at compile time (same as used in pragma msg) and pass it to writeln instead of Counter. I guess this is one of these bif oof moments with UFCS, a function returning a (parameterless) function. Note that in most cases you should never make runtime decisions on .stringof value as it is not standardized. ``` //pragma(msg, typeof(Counter)); // pure nothrow @safe int delegate() pure nothrow @nogc @safe(int nextValue) enum f = typeof(Counter).stringof; // same string as above writeln( "'Counter' is ", f); ``` Of course this works too `writeln( "'Counter' is ", typeof(Counter).stringof);`
Re: What is :-) ?
On Monday, 20 November 2023 at 08:47:34 UTC, Antonio wrote: I understand the problem with UFCS (``next`` is not using UFCS because it is a delegate defined in the own main() function, and ``Counter``` without () is treated as a function call because it is UFCS eligible ) This is not UFCS, it's [optional parentheses][1], which is a separate language feature. (Reminder: UFCS only applies when the callee has the form `x.y`) According to the spec, it's disabled for function pointers and delegates due to the potential for ambiguity. [1]: https://dlang.org/spec/function.html#optional-parenthesis