Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 07:24:31 UTC, Basile B. wrote: A testA() { return alwaysReturnNull(); // Tnull can be implictly converted to A } still nice tho. Why not [1]? [1] typeof(null) alwaysReturnNull() { ... } Andrea
Floating-Point arithmetic in dlang - Difference to other languages
Today i have stumbled on Hacker News into: https://0.30004.com/ I am learning D, that's why i have to ask. Why does writefln("%.17f", .1+.2); not evaluate into: 0.30004, like C++ but rather to: 0.2 Many other languages evaluate to 0.30004 as well.
Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 08:47:45 UTC, Andrea Fontana wrote: On Tuesday, 3 December 2019 at 07:24:31 UTC, Basile B. wrote: A testA() { return alwaysReturnNull(); // Tnull can be implictly converted to A } still nice tho. Why not [1]? [1] typeof(null) alwaysReturnNull() { ... } Andrea Yeah nice, that works instead of auto. That reminds me of the discussion about TBottom.
Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 09:44:20 UTC, Basile B. wrote: On Tuesday, 3 December 2019 at 08:47:45 UTC, Andrea Fontana wrote: On Tuesday, 3 December 2019 at 07:24:31 UTC, Basile B. wrote: A testA() { return alwaysReturnNull(); // Tnull can be implictly converted to A } still nice tho. Why not [1]? [1] typeof(null) alwaysReturnNull() { ... } Andrea Yeah nice, that works instead of auto. That reminds me of the discussion about TBottom. You see what surprises me here is that we cannot express the special type that is `TypeNull` and that can only have one value (`null`) so instead we have to use `auto` or `typeof(null)`. Making this type public would make the logic more clear: when `null` is used it's not a value but rather a value of a type that is convertible to all pointers or reference types.
Re: Floating-Point arithmetic in dlang - Difference to other languages
On Tuesday, 3 December 2019 at 09:22:49 UTC, Jan Hönig wrote: Today i have stumbled on Hacker News into: https://0.30004.com/ I am learning D, that's why i have to ask. Why does writefln("%.17f", .1+.2); not evaluate into: 0.30004, like C++ but rather to: 0.2 Many other languages evaluate to 0.30004 as well. You can get this result in D as well: $ rdmd --eval 'double a = .1, b = .2; writefln("%.17f", a+b)' 0.30004 https://dlang.org/spec/float.html explains it: real (80bit, 'long double' in C) floats are used in your first calculation, and doubles are used in my revised example. Most other languages give you the double result for very reasonable historical reasons, described here: https://retrocomputing.stackexchange.com/questions/9751/did-any-compiler-fully-use-intel-x87-80-bit-floating-point/9760#9760 D's behavior is a minor 'miss': https://nwcpp.org/Oct-2019.html ... I wanted to include a C example that gives the D result, but it seems to be trickier to force 80 bit intermediates.
Blog Post #92: Window Stats - Size and Maximize
Today, we carry on looking at Window stats and how we can prepare to preserve them. You'll find it here: https://gtkdcoding.com/2019/12/03/0092-window-stats-ii-size.html
Re: Unexpectedly nice case of auto return type
On Tuesday, December 3, 2019 12:12:18 AM MST Basile B. via Digitalmars-d- learn wrote: > I wish something like this was possible, until I change the > return type of `alwaysReturnNull` from `void*` to `auto`. > > > --- > class A {} > class B {} > > auto alwaysReturnNull() // void*, don't compile > { > writeln(); > return null; > } > > A testA() > { > return alwaysReturnNull(); > } > > B testB() > { > return alwaysReturnNull(); > } > > void main() > { > assert( testA() is null ); > assert( testB() is null ); > } > --- > > OMG, isn't it nice that this works ? > > I think that this illustrates an non intuitive behavior of auto > return types. > One would rather expect auto to work depending on the inner > return type. The void* version doesn't work, because void* doesn't implicitly convert to a class type. It has nothing to do with null. auto works thanks to the fact that typeof(null) was added to the language a while back, and since class references can be null, typeof(null) implicitly converts to the class type. Before typeof(null) was added to the language, null by itself had no type, since it's just a literal representing the null value for any pointer or class reference. The result was that using null in generic code or with auto could run into issues. typeof(null) was added to solve those problems. - Jonathan M Davis
Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 09:58:36 UTC, Jonathan M Davis wrote: On Tuesday, December 3, 2019 12:12:18 AM MST Basile B. via Digitalmars-d- learn wrote: I wish something like this was possible, until I change the return type of `alwaysReturnNull` from `void*` to `auto`. --- class A {} class B {} auto alwaysReturnNull() // void*, don't compile { writeln(); return null; } A testA() { return alwaysReturnNull(); } B testB() { return alwaysReturnNull(); } void main() { assert( testA() is null ); assert( testB() is null ); } --- OMG, isn't it nice that this works ? I think that this illustrates an non intuitive behavior of auto return types. One would rather expect auto to work depending on the inner return type. The void* version doesn't work, because void* doesn't implicitly convert to a class type. It has nothing to do with null. auto works thanks to the fact that typeof(null) was added to the language a while back, and since class references can be null, typeof(null) implicitly converts to the class type. Before typeof(null) was added to the language, null by itself had no type, since it's just a literal representing the null value for any pointer or class reference. The result was that using null in generic code or with auto could run into issues. typeof(null) was added to solve those problems. - Jonathan M Davis That's interesting details of D developement. Since you reply to the first message I think you have not followed but in the last reply I told that maybe we should be able to name the type of null. I think this relates to TBottom too a bit.
Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 09:48:39 UTC, Basile B. wrote: You see what surprises me here is that we cannot express the special type that is `TypeNull` and that can only have one value (`null`) so instead we have to use `auto` or `typeof(null)`. You can still create an alias anyway :) alias TypeNull = typeof(null);
Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 10:03:22 UTC, Basile B. wrote: That's interesting details of D developement. Since you reply to the first message I think you have not followed but in the last reply I told that maybe we should be able to name the type of null. I think this relates to TBottom too a bit. https://github.com/dlang/DIPs/blob/40352337053998885fbd0fe2718c300a322d3996/DIPs/DIP1NNN-DK.md
Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 10:06:22 UTC, Mike Parker wrote: On Tuesday, 3 December 2019 at 10:03:22 UTC, Basile B. wrote: That's interesting details of D developement. Since you reply to the first message I think you have not followed but in the last reply I told that maybe we should be able to name the type of null. I think this relates to TBottom too a bit. https://github.com/dlang/DIPs/blob/40352337053998885fbd0fe2718c300a322d3996/DIPs/DIP1NNN-DK.md Ah, well. I meant to post the link to the PR: https://github.com/dlang/DIPs/pull/172
Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 10:02:47 UTC, Andrea Fontana wrote: On Tuesday, 3 December 2019 at 09:48:39 UTC, Basile B. wrote: You see what surprises me here is that we cannot express the special type that is `TypeNull` and that can only have one value (`null`) so instead we have to use `auto` or `typeof(null)`. You can still create an alias anyway :) alias TypeNull = typeof(null); Speaking of nice stuff and aliases, suppose you want to return a nice tuple with named elements? Option 1: auto auto option1() { return tuple!(int, "apples", int, "oranges")(1, 2); } Option 2: redundancy Tuple!(int, "apples", int, "oranges") option2() { return tuple!(int, "apples", int, "oranges")(1, 2); } Option 3: an alias alias BadMath = Tuple!(int, "apples", int, "oranges"); BadMath option3() { return BadMath(1, 2); } It wasn't obvious to me that BadMath(...) would work. It *should* be obvious since this also works: ... return Tuple!(int, "apples", int, "oranges")(1, 2); But the convenience of tuple() helped to mask that. I was going with silly stuff like ... return cast(BadMath) tuple(1, 2);
Re: Unexpectedly nice case of auto return type
On Tuesday, December 3, 2019 3:03:22 AM MST Basile B. via Digitalmars-d- learn wrote: > On Tuesday, 3 December 2019 at 09:58:36 UTC, Jonathan M Davis > > wrote: > > On Tuesday, December 3, 2019 12:12:18 AM MST Basile B. via > > > > Digitalmars-d- learn wrote: > >> I wish something like this was possible, until I change the > >> return type of `alwaysReturnNull` from `void*` to `auto`. > >> > >> > >> --- > >> class A {} > >> class B {} > >> > >> auto alwaysReturnNull() // void*, don't compile > >> { > >> > >> writeln(); > >> return null; > >> > >> } > >> > >> A testA() > >> { > >> > >> return alwaysReturnNull(); > >> > >> } > >> > >> B testB() > >> { > >> > >> return alwaysReturnNull(); > >> > >> } > >> > >> void main() > >> { > >> > >> assert( testA() is null ); > >> assert( testB() is null ); > >> > >> } > >> --- > >> > >> OMG, isn't it nice that this works ? > >> > >> I think that this illustrates an non intuitive behavior of auto > >> return types. > >> One would rather expect auto to work depending on the inner > >> return type. > > > > The void* version doesn't work, because void* doesn't > > implicitly convert to a class type. It has nothing to do with > > null. auto works thanks to the fact that typeof(null) was added > > to the language a while back, and since class references can be > > null, typeof(null) implicitly converts to the class type. > > Before typeof(null) was added to the language, null by itself > > had no type, since it's just a literal representing the null > > value for any pointer or class reference. The result was that > > using null in generic code or with auto could run into issues. > > typeof(null) was added to solve those problems. > > > > - Jonathan M Davis > > That's interesting details of D developement. Since you reply to > the first message I think you have not followed but in the last > reply I told that maybe we should be able to name the type of > null. I think this relates to TBottom too a bit. There isn't much point in giving the type of null an explicit name given that it doesn't come up very often, and typeof(null) is quite explicit about what the type is. Also, anyone doing much generic programming in D is going to be well versed in typeof. They might not know about typeof(null) explicitly, but they should recognize what it means when they see it, and if someone were trying to get the type of null, it would be the obvious thing to try anyway. And typeof(null) isn't even the prime case where typeof gets used on something other than an object. From what I've seen, typeof(return) gets used far more. As for TBottom, while the DIP does give it a relationship to null, they're still separate things, and giving typeof(null) a name wouldn't affect TBottom at all. - Jonathan M Davis
Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 10:19:02 UTC, Jonathan M Davis wrote: On Tuesday, December 3, 2019 3:03:22 AM MST Basile B. via Digitalmars-d- learn wrote: [...] There isn't much point in giving the type of null an explicit name given that it doesn't come up very often, and typeof(null) is quite explicit about what the type is. Also, anyone doing much generic programming in D is going to be well versed in typeof. They might not know about typeof(null) explicitly, but they should recognize what it means when they see it, and if someone were trying to get the type of null, it would be the obvious thing to try anyway. And typeof(null) isn't even the prime case where typeof gets used on something other than an object. From what I've seen, typeof(return) gets used far more. [...] you're right but I see two cases: - transpiling - header generation
Re: Floating-Point arithmetic in dlang - Difference to other languages
On Tuesday, 3 December 2019 at 09:22:49 UTC, Jan Hönig wrote: not evaluate into: 0.30004, like C++ but rather to: 0.2 You get the same in C++ with: #include int main() { printf("%.17f",double(0.1L + 0.2L)); }
Re: Floating-Point arithmetic in dlang - Difference to other languages
On Tuesday, 3 December 2019 at 09:52:18 UTC, mipri wrote: Most other languages give you the double result for very reasonable historical reasons Not only historical, it is also for numerical reasons. You can get very unpredictable results if you do compares and compiletime evalution is different from runtime evaluation.
Re: Floating-Point arithmetic in dlang - Difference to other languages
On Tuesday, 3 December 2019 at 09:22:49 UTC, Jan Hönig wrote: Today i have stumbled on Hacker News into: https://0.30004.com/ I am learning D, that's why i have to ask. Why does writefln("%.17f", .1+.2); not evaluate into: 0.30004, like C++ but rather to: 0.2 Many other languages evaluate to 0.30004 as well. D lang could have a very good sprintf replacement.
Intersection of two sets
It seems i don't google the right keywords. What i want to do: I have two sets. (I didn't find how to do sets, so i have two associative boolean arrays `bool[]`). And i want to join them, via an intersection. I know how to code this. Loop over one AA, if the key is also in the other one, we add that to the third array which is going to be returned. pseudocode: alias set = bool[] set foo = ... set bar = ... set result; foreach(key; foo) { if (key in bar) { result[key] = true; } } return result; 1) Is there a better way for creating a set, other then `alias set = bool[keyClass]`? 2) Are there some build-in function for handling such sets?
Re: Unexpectedly nice case of auto return type
On Tuesday, December 3, 2019 3:23:20 AM MST Basile B. via Digitalmars-d- learn wrote: > On Tuesday, 3 December 2019 at 10:19:02 UTC, Jonathan M Davis > > wrote: > > On Tuesday, December 3, 2019 3:03:22 AM MST Basile B. via > > > > Digitalmars-d- learn wrote: > >> [...] > > > > There isn't much point in giving the type of null an explicit > > name given that it doesn't come up very often, and typeof(null) > > is quite explicit about what the type is. Also, anyone doing > > much generic programming in D is going to be well versed in > > typeof. They might not know about typeof(null) explicitly, but > > they should recognize what it means when they see it, and if > > someone were trying to get the type of null, it would be the > > obvious thing to try anyway. And typeof(null) isn't even the > > prime case where typeof gets used on something other than an > > object. From what I've seen, typeof(return) gets used far more. > > > > [...] > > you're right but I see two cases: > > - transpiling > - header generation I don't see why either of those would be a problem. For a transpiler, typeof(null) and an explicit type name for typeof(null) would be the same thing, and it would have to be translated to something that would work in the other language either way. As for header generation, do you mean .di files? They'd just use typeof(null) explicitly, whereas if you're talking about something like having extern(C) functions in D and declaring a corresponding .h file, typeof(null) wouldn't work anyway, because there is no equivalent in C. In either case, whether you represent the type as typeof(null) or by an explicit name in the D source code is irrelevant. It would mean the same thing regardless. Having an explicit name wouldn't really be any different from declaring an alias like alias TypeOfNull = typeof(null); The type is the same either way and would be treated the same by the compiler or by any tool that needed to translate it to another language. It's what the type is that matters, not how its represented in the D source code. The only real difference would be what the programmer would see when interacting with the D source code. It would be like arguing over whether the root class object should be called Object or Root. It would be the same thing either way, just with a different name. - Jonathan M Davis
Re: Intersection of two sets
On Tuesday, 3 December 2019 at 13:43:26 UTC, Jan Hönig wrote: It seems i don't google the right keywords. What i want to do: I have two sets. (I didn't find how to do sets, so i have two associative boolean arrays `bool[]`). And i want to join them, via an intersection. I know how to code this. Loop over one AA, if the key is also in the other one, we add that to the third array which is going to be returned. pseudocode: alias set = bool[] set foo = ... set bar = ... set result; foreach(key; foo) { if (key in bar) { result[key] = true; } } return result; 1) Is there a better way for creating a set, other then `alias set = bool[keyClass]`? This depends on the available accesses on your sets. In terms of ranges: Are your sets InputRanges, ForwardRange, ... ? 2) Are there some build-in function for handling such sets? This is maybe what you are looking for: https://dlang.org/phobos/std_algorithm_setops.html
Re: Intersection of two sets
On Tuesday, 3 December 2019 at 13:43:26 UTC, Jan Hönig wrote: It seems i don't google the right keywords. What i want to do: I have two sets. (I didn't find how to do sets, so i have two associative boolean arrays `bool[]`). And i want to join them, via an intersection. I know how to code this. Loop over one AA, if the key is also in the other one, we add that to the third array which is going to be returned. pseudocode: alias set = bool[] set foo = ... set bar = ... set result; foreach(key; foo) { if (key in bar) { result[key] = true; } } return result; 1) Is there a better way for creating a set, other then `alias set = bool[keyClass]`? 2) Are there some build-in function for handling such sets? Never tried, but depending of the nature of your "something" you can try bit sets. There are efficient algorithms for large bit arrays (see "roaring" for example).
Strange casting error when using lamdas
I have very strange casting error I don't understand: alias typeof(windows_message_streams[WM_MOUSEMOVE].filter!(win => (win.wParam & MK_LBUTTON))) WM_MOUSEMOVE_LBUTTON_TYPE; WM_MOUSEMOVE_LBUTTON_TYPE WM_MOUSEMOVE_LBUTTON_STREAM; pragma(msg,typeof(WM_MOUSEMOVE_LBUTTON_STREAM)); FilterObservable!(__lambda39, SubjectObject!(OS_State)) WM_MOUSEMOVE_LBUTTON_STREAM = cast(WM_MOUSEMOVE_LBUTTON_TYPE)(windows_message_streams[WM_MOUSEMOVE].filter!(win => (win.wParam & MK_LBUTTON))); pragma(msg,typeof(wstreams[WM_MOUSEMOVE].filter!(win => (win.wParam & MK_LBUTTON; FilterObservable!(__lambda7, SubjectObject!(OS_State)) ..\..\gui.d(317,104): Error: cannot cast expression filter(windows_message_streams[512u]) of type FilterObservable!(__lambda6, SubjectObject!(OS_State)) to FilterObservable!(__lambda39, SubjectObject!(OS_State)) because of different sizes FilterObservable!(__lambda7, SubjectObject!(OS_State)) My code worked in the past but now it doesn't and I don't know why. I don't understand the "because of different sizes" message. It looks like I have to explicitly create a lambda and re-use it. But how to do that? -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Re: druntime 2.087 regression? (was: Old codebase stops compiling at 2.087)
On 11/17/19 7:15 PM, Steven Schveighoffer wrote: On 11/17/19 10:45 AM, James Blachly wrote: /home/james/dmd2.087/dmd2/linux/bin64/../../src/druntime/import/object.d(3453,36): Error: cannot implicitly convert expression aa of type shared(GSeqAllele[string]) to const(shared(GSeqAllele)[string]) There's a subtle removing of the shared from the entire AA. Is that on purpose? i.e. I see shared(GSeqAllele[string]) in one, and shared(GSeqAllele)[string] in another. -Steve Steve: Sorry for the delay in replying. That is the runtime removing the shared from the entire AA, not our code. I point out the change that induces this with a link to github. Should I move this discussion to the main D group? My primary concerns are: 0. Ask if it is intended behavior that the runtime cannot handle a shared AA post 2.086.1? 1. Report this as bug 2. Ask why this commit ("object: Declare private struct AA and fix aaA function signatures ") not mentioned in the changelog for 2.087? Thanks in advance
Re: Strange casting error when using lamdas
On 2019-12-03 16:34:43 +, Robert M. Münch said: I have very strange casting error I don't understand: alias typeof(windows_message_streams[WM_MOUSEMOVE].filter!(win => (win.wParam & MK_LBUTTON))) WM_MOUSEMOVE_LBUTTON_TYPE; WM_MOUSEMOVE_LBUTTON_TYPE WM_MOUSEMOVE_LBUTTON_STREAM; pragma(msg,typeof(WM_MOUSEMOVE_LBUTTON_STREAM)); FilterObservable!(__lambda39, SubjectObject!(OS_State)) WM_MOUSEMOVE_LBUTTON_STREAM = cast(WM_MOUSEMOVE_LBUTTON_TYPE)(windows_message_streams[WM_MOUSEMOVE].filter!(win => (win.wParam & MK_LBUTTON))); pragma(msg,typeof(wstreams[WM_MOUSEMOVE].filter!(win => (win.wParam & MK_LBUTTON; FilterObservable!(__lambda7, SubjectObject!(OS_State)) ..\..\gui.d(317,104): Error: cannot cast expression filter(windows_message_streams[512u]) of type FilterObservable!(__lambda6, SubjectObject!(OS_State)) to FilterObservable!(__lambda39, SubjectObject!(OS_State)) because of different sizes FilterObservable!(__lambda7, SubjectObject!(OS_State)) My code worked in the past but now it doesn't and I don't know why. I don't understand the "because of different sizes" message. It looks like I have to explicitly create a lambda and re-use it. But how to do that? The first three lines are on module level, the second two lines are inside a class member function. pragma(msg,WM_MOUSEMOVE_LBUTTON_STREAM.sizeof); 8LU but pragma(msg,windows_message_streams[WM_MOUSEMOVE].filter!(win => (win.wParam & MK_LBUTTON)).sizeof); 16LU Why do these two things have different sizes even the declaration is exactly the same? -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Re: Unexpectedly nice case of auto return type
On Tue, Dec 03, 2019 at 03:19:02AM -0700, Jonathan M Davis via Digitalmars-d-learn wrote: > On Tuesday, December 3, 2019 3:03:22 AM MST Basile B. via Digitalmars-d- > learn wrote: [...] > > [...] maybe we should be able to name the type of null. I think this > > relates to TBottom too a bit. > > There isn't much point in giving the type of null an explicit name > given that it doesn't come up very often, and typeof(null) is quite > explicit about what the type is. Just add this line somewhere in object.d and we're good to go: alias Null = typeof(null); :-) [...] > As for TBottom, while the DIP does give it a relationship to null, > they're still separate things, and giving typeof(null) a name wouldn't > affect TBottom at all. [...] We need to tread carefully here, because of the unfortunate conflation of top and bottom types we inherited from C in the form of the keyword `void`, which greatly confuses the issue. The thing is, `void` means "no return type" (or "no type" in some contexts), i.e., void == TBottom in that case. However, `void*` does NOT mean a pointer to TBottom; rather, it's a *top type* that includes pointers of every kind (this can be seen in the fact that any pointer implicitly converts to void*). I.e., the relationship between `void` and `void*` is NOT the same as the relationship with `T` and `T*` for any other T. This unfortunate overloading of `void` to mean both top and bottom types in different contexts misleads many C (and D) programmers into the wrong understanding of what a bottom type is (or what a top type is), and how it should behave. T -- The problem with the world is that everybody else is stupid.
Re: Intersection of two sets
On Tuesday, 3 December 2019 at 15:14:03 UTC, ikod wrote: Never tried, but depending of the nature of your "something" you can try bit sets. There are efficient algorithms for large bit arrays (see "roaring" for example). "roaring" is massive overkill for my case, but thanks for suggesting it. I didn't know about it.
Re: Floating-Point arithmetic in dlang - Difference to other languages
On Tue, Dec 03, 2019 at 09:22:49AM +, Jan Hönig via Digitalmars-d-learn wrote: > Today i have stumbled on Hacker News into: https://0.30004.com/ > > I am learning D, that's why i have to ask. > > Why does > > writefln("%.17f", .1+.2); > > not evaluate into: 0.30004, like C++ > but rather to: 0.2 > > Many other languages evaluate to 0.30004 as well. In short, because they use 64-bit floats for intermediate values (`double`), whereas D defaults to 80-bit intermediates (`real`). The use of a more precise intermediate value is also indicated by the fact that 0.2 is closer to the real answer (error of 1e-17) than 0.30004 (error of 4e-17). If you explicitly specify to use `double`, then you should get the same answer as C++. double a=.1, b=.2; writefln("%.17f", a+b); T -- MSDOS = MicroSoft's Denial Of Service
Re: Intersection of two sets
On Tuesday, 3 December 2019 at 13:55:51 UTC, Alex wrote: This depends on the available accesses on your sets. In terms of ranges: Are your sets InputRanges, ForwardRange, ... ? 2) Are there some build-in function for handling such sets? This is maybe what you are looking for: https://dlang.org/phobos/std_algorithm_setops.html In terms of ranges, i need to understand ranges properly first. The std.algorithm.setops have definitely the functionality i need. I guess my current implementation would be a simple array. I just need to make sure delete, or not create double entries.
Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 17:45:27 UTC, H. S. Teoh wrote: The thing is, `void` means "no return type" (or "no type" in some contexts), i.e., void == TBottom in that case. This is incorrect. `void` as a return type is a unit type; that is, a type with exactly one value. A function with a return type of TBottom is one that never returns at all--for example, libc's `exit` or POSIX's `execve`.
Re: Unexpectedly nice case of auto return type
On Tue, Dec 03, 2019 at 09:08:55PM +, Paul Backus via Digitalmars-d-learn wrote: > On Tuesday, 3 December 2019 at 17:45:27 UTC, H. S. Teoh wrote: > > The thing is, `void` means "no return type" (or "no type" in some > > contexts), i.e., void == TBottom in that case. > > This is incorrect. `void` as a return type is a unit type; that is, a > type with exactly one value. A function with a return type of TBottom > is one that never returns at all--for example, libc's `exit` or > POSIX's `execve`. Ah, my bad. See? This whole `void` business just throws me off. No wonder we can never get things straight when it comes to top/bottom types in C/C++/D. T -- He who sacrifices functionality for ease of use, loses both and deserves neither. -- Slashdotter
Re: Intersection of two sets
On Tuesday, 3 December 2019 at 18:45:18 UTC, Jan Hönig wrote: On Tuesday, 3 December 2019 at 13:55:51 UTC, Alex wrote: This depends on the available accesses on your sets. In terms of ranges: Are your sets InputRanges, ForwardRange, ... ? 2) Are there some build-in function for handling such sets? This is maybe what you are looking for: https://dlang.org/phobos/std_algorithm_setops.html In terms of ranges, i need to understand ranges properly first. The top of https://dlang.org/phobos/std_range.html has some talks and tutorials to consider. The std.algorithm.setops have definitely the functionality i need. I guess my current implementation would be a simple array. I just need to make sure delete, or not create double entries. A problem with the unittest examples is that they assume the reader is very familiar with the language :) Here are some things to keep in mind with setIntersection: 1. setIntersection expects its inputs to be sorted. If they aren't, it doesn't notice; you just don't get the behavior you want. int[] a = [4, 2, 3, 1], b = [8, 4, 2, 6]; assert(setIntersection(a, b).array == []); // ! assert(setIntersection(a.sort, b.sort).array == [2, 4]); 2. setIntersection returns a range, not an array. This probably lets you return the infinite intersections of two infinite ranges, for example. If you're looking at this for Advent of Code you'll probably want to pass the intersections through some other operators that will accept a range. (Also, sort mutates *and* returns the array. if you're depending on the positions of 2 and 4 in the original arrays, you should get the intersection of a sorted copy of them.) In general, pay attention to the static constraints: if (Rs.length >= 2 && allSatisfy!(isInputRange, Rs) && !is(CommonType!(staticMap!(ElementType, Rs)) == void)); In English: 1. if you're getting an intersection of ranges, you need to provide at least two ranges. 2. all of the ranges need to be input ranges 3. the ranges' element types need to have a common type that isn't 'void'. You can use these same constraints in your code if you're not sure if they apply static assert (isInputRange!(typeof(a))); assert(setIntersection(a, b).array == []); or you can test them interactively: $ rdmd --eval 'isInputRange!(typeof([1, 2, 3])).writeln' true And you can also check on their documentation and see if it's what you expect: https://dlang.org/phobos/std_range_primitives.html D doesn't have 500+ line errors for the simplest template misuse like C does, but its much shorter template error messages still could be friendlier. Usually they're in terms of these constraints, or you've a more basic error like having a range type (like the SetIntersection struct that setIntersection actually returns) where some other code expects a simple array, or vice versa.
Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 17:45:27 UTC, H. S. Teoh wrote: The thing is, `void` means "no return type" (or "no type" in some contexts), i.e., void == TBottom in that case. Not *quite* correct. void is not a bottom type; it's a unit type, meaning that it's a type with only 1 value (as is null, interestingly). void does not mean "no return type"; it means "there's only 1 possible value that can be returned". A function returning TBottom means that the function will never return, e.g., it loops forever, or throws an exception, etc. I agree with the OP that it's silly not to give typeof(null) a name. As null is a unit type, we could easily have `null` stand in for typeof(null) as well. A type that contains only one value can be synonymous with that value (see also, Rust's unit type (), which has one value, ()).
Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 22:11:39 UTC, Meta wrote: On Tuesday, 3 December 2019 at 17:45:27 UTC, H. S. Teoh wrote: The thing is, `void` means "no return type" (or "no type" in some contexts), i.e., void == TBottom in that case. Not *quite* correct. void is not a bottom type; it's a unit type, meaning that it's a type with only 1 value (as is null, interestingly). void does not mean "no return type"; it means "there's only 1 possible value that can be returned". A function returning TBottom means that the function will never return, e.g., it loops forever, or throws an exception, etc. Whoops, skimmed over the post already mentioning this.
Re: druntime 2.087 regression? (was: Old codebase stops compiling at 2.087)
On 12/3/19 12:15 PM, James Blachly wrote: On 11/17/19 7:15 PM, Steven Schveighoffer wrote: On 11/17/19 10:45 AM, James Blachly wrote: /home/james/dmd2.087/dmd2/linux/bin64/../../src/druntime/import/object.d(3453,36): Error: cannot implicitly convert expression aa of type shared(GSeqAllele[string]) to const(shared(GSeqAllele)[string]) There's a subtle removing of the shared from the entire AA. Is that on purpose? i.e. I see shared(GSeqAllele[string]) in one, and shared(GSeqAllele)[string] in another. Steve: Sorry for the delay in replying. That is the runtime removing the shared from the entire AA, not our code. I point out the change that induces this with a link to github. I admit, this was a drive-by analysis, and I didn't look at the code at all. Just the error. Should I move this discussion to the main D group? My primary concerns are: 0. Ask if it is intended behavior that the runtime cannot handle a shared AA post 2.086.1? 1. Report this as bug 2. Ask why this commit ("object: Declare private struct AA and fix aaA function signatures ") not mentioned in the changelog for 2.087? 0. learn is fine. I'm never one to care about where someone posts. 1. Bugzilla is the correct place to report. Looks like you have a solid case and have done all the hard work. Should be fixable. 2. Not all commits are mentioned in the changelog. But if there is a change that breaks existing code, arguably it should be in there. -Steve
Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 10:13:30 UTC, mipri wrote: Speaking of nice stuff and aliases, suppose you want to return a nice tuple with named elements? Option 1: auto auto option1() { return tuple!(int, "apples", int, "oranges")(1, 2); } Option 2: redundancy Tuple!(int, "apples", int, "oranges") option2() { return tuple!(int, "apples", int, "oranges")(1, 2); } Option 3: an alias alias BadMath = Tuple!(int, "apples", int, "oranges"); BadMath option3() { return BadMath(1, 2); } Option 4: typeof(return) Tuple!(int, "apples", int, "oranges") option4() { return typeof(return)(1, 2); }
Re: Unexpectedly nice case of auto return type
On Tuesday, 3 December 2019 at 23:44:59 UTC, mipri wrote: Option 4: typeof(return) typeof(return) is super cool for like option type things too!
Re: Unexpectedly nice case of auto return type
On Wed, Dec 04, 2019 at 01:01:04AM +, Adam D. Ruppe via Digitalmars-d-learn wrote: > On Tuesday, 3 December 2019 at 23:44:59 UTC, mipri wrote: > > Option 4: typeof(return) > > typeof(return) is super cool for like option type things too! typeof(return) is one of the lesser known cool things about D that make it so cool. Somebody should write an article about it to raise awareness of it. :-D T -- An imaginary friend squared is a real enemy.
Re: Unexpectedly nice case of auto return type
On Wednesday, 4 December 2019 at 01:28:00 UTC, H. S. Teoh wrote: typeof(return) is one of the lesser known cool things about D that make it so cool. Somebody should write an article about it to raise awareness of it. :-D you know i probably will write about that next week. so be sure to like, comment, and subscribe so you never miss my next post and then give me all your money on patreon so i can keep bringing you content :P :P