Re: The Phobos Put
On Wednesday, 29 March 2023 at 20:50:04 UTC, Steven Schveighoffer wrote: On 3/29/23 4:29 PM, ag0aep6g wrote: But regardless of Salih's exact intent, the broader point is: a non-ref overload could be added to Phobos. And that would enable `a[1..$-1].phobos_put([2, 3])`. Which is what he asked about originally. I think the idea of requiring ref output ranges is that you can then let the range keep track of its output state. So why not copying the range to a static array? The error during compilation of the code is as follows: onlineapp.d(6): Error: none of the overloads of template `std.algorithm.mutation.copy` are callable using argument types `!()(int[], int[8])` /dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/mutation.d(367): Candidate is: `copy(SourceRange, TargetRange)(SourceRange source, TargetRange target)` with `SourceRange = int[], TargetRange = int[8]` must satisfy the following constraint: ` isOutputRange!(TargetRange, ElementType!SourceRange)` ```d import std.algorithm.mutation : copy; void main() { int[8] buf; auto dig = [1, 2, 3, 4]; auto rem = dig.copy(buf); assert(rem.length == 4); } ``` Looks like 'copy' has the same overload issue. SDB@79
Re: How to debug and watch globals in windows debugger?
On Wednesday, 29 March 2023 at 21:09:57 UTC, ryuukk_ wrote: Also it's more of an accumulation of problems that makes me very annoyed https://issues.dlang.org/show_bug.cgi?id=20737 This for example shouldn't be a thing in 2023, period I agree with you because it's such a simple problem and it's surprising if it exists. I've never used -betterC though, but it's a pity. SDB@79
Re: How to debug and watch globals in windows debugger?
On 30/03/2023 10:09 AM, ryuukk_ wrote: more people should voice their complains Making noise about problems in D.learn is not the place to do it, I don't think compiler developers tend to monitor it much. Show your analysis of the situation in General, that is monitored. Especially since the fix for this stuff is probably pretty simple for TLS.
Re: How to debug and watch globals in windows debugger?
On Wednesday, 29 March 2023 at 15:26:21 UTC, Steven Schveighoffer wrote: On 3/28/23 6:42 PM, ryuukk_ wrote: Am i the only want who want to improve things, is it a lost cause? I'm not one to use a debugger often, but it is very helpful for many people. I lament that the Windows debugging situation out of the box is dreadful. The students I teach D to I don't show the debugger because I'm worried it would confuse them more than help. I only use windows because i'm making a game and i have to test on that platform I both don't use Windows and mostly do debugging via writeln, so for something that doesn't affect me much, I tend not to put effort in. I'm hoping someone who is motivated enough will do it. I am motivated, hopefully someone more knowledgeable can join me figure that out If I recall correctly, visual studio debugging is better than the other solutions. But I don't know having never got debugging to work. I've heard that mago is supposed to work better, and was written for D, but is Visual Studio dependent: https://github.com/rainers/mago I wonder if there isn't some way to make this work well for other IDEs? I couldn't get it to work on VSCode. That's unfortunate that the solution is bound to a proprietary editor that requires a license Effort should be made in the open and be universal, so it's easy to port/adapt to other tools/platforms Coordinated efforts is the way to go, Go/Rust/Zig people are demonstrating this very well and it helped their growth Should i move on? In any case, the debugging experience isn't perfect, but seems like a drastic measure to leave D altogether if you can't debug globals. -Steve I exaggerate a little bit i must admit it, but I'm trying to raise awareness, when other languages have no problem with debugging out of the box on popular IDEs, why should it have problems only with D? Currently, at least on windows, there are 2 problems with debugging: - global variables - extern(C) variables I'm willing to find the cause for the 1st one, then i'll attempt the 2nd one, so expect more frustrated posts I should emphasis again that the reason why i'm into this mess is due to a bug i'm trying to debug related to loading a shared DLL built using DMD on windows, wich apparently is known to be broken for YEARS.. great, more people should voice their complains, D is not a new language.. So what to expect other than frustration? specially when people keep recommending to use "workarounds", well, if the fix is a workaround, one shouldn't be surprised to see people getting frustrated every so often Also it's more of an accumulation of problems that makes me very annoyed https://issues.dlang.org/show_bug.cgi?id=20737 This for example shouldn't be a thing in 2023, period
Re: The Phobos Put
On 3/29/23 4:29 PM, ag0aep6g wrote: But regardless of Salih's exact intent, the broader point is: a non-ref overload could be added to Phobos. And that would enable `a[1..$-1].phobos_put([2, 3])`. Which is what he asked about originally. I think the idea of requiring ref output ranges is that you can then let the range keep track of its output state. An input range with lvalue elements is therefore an output range, but only if it's accepted via ref, since it has to be iterated as it goes. If you iterate it only internally, then it's either in an undetermined state when you exit `put`, or it is a forward range that was copied without using `save`. It's not the greatest situation. I feel like we probably shouldn't have made lvalue input ranges be output ranges automatically. -Steve
Re: The Phobos Put
On Wednesday, 29 March 2023 at 20:29:24 UTC, ag0aep6g wrote: But regardless of Salih's exact intent, the broader point is: a non-ref overload could be added to Phobos. And that would enable `a[1..$-1].phobos_put([2, 3])`. Which is what he asked about originally. Yes, that was it, but even more. Both functions serve the same thing. Why don't we combine them? SDB@79
Re: The Phobos Put
On Wednesday, 29 March 2023 at 19:49:47 UTC, Ali Çehreli wrote: On 3/29/23 12:21, ag0aep6g wrote: > As far as I understand, you're saying that we cannot overload on `ref`. > But we can. Salih's code demonstrates just that. > > void f(ref int x) {} > void f(int x) {} > void main() { int x; f(x); f(42); } /* no errors */ I thought Salih was proposing two more overloads to the existing put(). When I copy the existing put(), which takes 'ref R', not R[], then the code does not compile: Wait a minute, isn't `copy` actually a `put` as well? Forget about `ref` for a moment, please. Actually, logically, the parameters have been swapped between the two functions. Well, if we only had `copy` and we used `put` like `copy`, what is the need for `put`? Examples are below: :) ```d //version = simple;/* version = standart;//*/ version(simple) { auto put(R)(R[] range, R[] source) => copyImpl(source, range); auto copy(R)(R[] source, R[] range) => copyImpl(source, range); auto copyImpl(R)(R[] source, R[] range) { assert(source.length <= range.length); foreach(element; source) { range[0] = element; // range.front() range = range[1..$]; // range.popFront() } return range; } void swap (ref int x, ref int y) { x = x ^ y; y = y ^ x; x = x ^ y; } } version(standart) import std.algorithm.mutation, std.range : put; void main() { // copy() example: enum len = 10; auto buf = new int[len]; // buffer auto dig = [7, 1, 2, 3]; // digits auto diff = len - dig.length; auto rem = copy(dig, buf); assert(buf[0..$ - diff] == [7, 1, 2, 3]); swap(buf[0], rem[0]); assert(rem == [7, 0, 0, 0, 0, 0]); // put() example 1: put(rem, [4, 5, 6, 7, 8, 9]); assert(buf == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); // put() example 2: enum data = [1, 0, 0, 4]; auto arr = data; auto slice = arr[1..$-1]; version(standart) put(slice, [2]); version(simple) slice = put(slice, [2]); assert(arr == [1, 2, 0, 4]); version(standart) put(slice, [3]); version(simple) slice = put(slice, [3]); assert(arr == [1, 2, 3, 4]); version(standart) { auto slc = arr[1..$-1]; put(slc, [0, 0]); } version(simple) arr[1..$-1].put([0, 0]); assert(arr == data); } ``` All you have to do is remove the // mark in the first line. The code compiles for me, what about you? SDB@79
Re: The Phobos Put
On Wednesday, 29 March 2023 at 19:49:47 UTC, Ali Çehreli wrote: I thought Salih was proposing two more overloads to the existing put(). When I copy the existing put(), which takes 'ref R', not R[], then the code does not compile: auto put(R)(R[] range, R[] source) => putImpl(range, source); auto put(R)(ref R[] range, R[] source) => putImpl(range, source); [...] void put(R, E)(ref R r, E e) { // This is from Phobos <--- } I understand Salih's ref `put` to be same as yours: a stand-in for the one that is already in Phobos. So he's proposing to add the non-ref one. But regardless of Salih's exact intent, the broader point is: a non-ref overload could be added to Phobos. And that would enable `a[1..$-1].phobos_put([2, 3])`. Which is what he asked about originally.
Re: The Phobos Put
On 3/29/23 12:21, ag0aep6g wrote: > As far as I understand, you're saying that we cannot overload on `ref`. > But we can. Salih's code demonstrates just that. > > void f(ref int x) {} > void f(int x) {} > void main() { int x; f(x); f(42); } /* no errors */ I thought Salih was proposing two more overloads to the existing put(). When I copy the existing put(), which takes 'ref R', not R[], then the code does not compile: auto put(R)(R[] range, R[] source) => putImpl(range, source); auto put(R)(ref R[] range, R[] source) => putImpl(range, source); void putImpl(R)(ref R[] range, R[] source) { assert(source.length <= range.length); foreach(element; source) { range[0] = element; // range.front() range = range[1..$]; // range.popFront() } } void put(R, E)(ref R r, E e) { // This is from Phobos <--- } void main() { enum data = [1, 0, 0, 4]; auto arr = data; auto slice = arr[1..$-1]; slice.put([2]); // <-- ERROR assert(arr == [1, 2, 0, 4]); slice.put([3]); assert(arr == [1, 2, 3, 4]); arr[1..$-1].put([0, 0]); assert(arr == data); } Ali
Re: The Phobos Put
On Wednesday, 29 March 2023 at 16:44:31 UTC, Ali Çehreli wrote: On 3/29/23 09:27, Salih Dincer wrote: > In this way, > it could also be used directly with slices. For example: > auto put(R)(R[] range, R[] source) >=> putImpl(range, source); That's for rvalues. > auto put(R)(ref R[] range, R[] source) >=> putImpl(range, source); That's for lvalues. If you are proposing keeping the current ref-taking Phobos put() as well, then the following call would be ambiguous: slice.put([2]); // Compilation ERROR As far as I understand, you're saying that we cannot overload on `ref`. But we can. Salih's code demonstrates just that. void f(ref int x) {} void f(int x) {} void main() { int x; f(x); f(42); } /* no errors */
Re: The Phobos Put
On 3/29/23 09:27, Salih Dincer wrote: > In this way, > it could also be used directly with slices. For example: > auto put(R)(R[] range, R[] source) >=> putImpl(range, source); That's for rvalues. > auto put(R)(ref R[] range, R[] source) >=> putImpl(range, source); That's for lvalues. If you are proposing keeping the current ref-taking Phobos put() as well, then the following call would be ambiguous: slice.put([2]); // Compilation ERROR That can be remedied by using template constraints for 'slices' vs. other output ranges. But that would be against the idea of "D slices are most capable ranges". What I mean is, I should be able to write any range algorithm and pass a slice to it and it should work. If we go with your proposal, then we would have to check for that case for some algorithms like put(). Further, I think the user of put() in templates would have to check whether they are dealing with a slice or not: void foo(R)(R range) { range.put(/* ... */); // If we go with your proposal, whether 'range' changed depends // on whether R is a slice or not. Do we have to check with // 'static if' in such range algorithms? } Note that I am not defending the behavior of put(). I am just trying to explain why it is so. Ali
Re: The Phobos Put
On Wednesday, 29 March 2023 at 15:01:27 UTC, Ali Çehreli wrote: On 3/29/23 04:48, Dennis wrote: On the other hand, Phobos's put() works with any OutputRange so it has to take a 'ref' to advance to know where it is left off. This behavior makes its use with slices weird but sometimes such is life. :) Would not adding a prototype without a ref cause ambiguity? In this way, it could also be used directly with slices. For example: ```d auto put(R)(R[] range, R[] source) => putImpl(range, source); auto put(R)(ref R[] range, R[] source) => putImpl(range, source); void putImpl(R)(ref R[] range, R[] source) { assert(source.length <= range.length); foreach(element; source) { range[0] = element; // range.front() range = range[1..$]; // range.popFront() } } void main() { enum data = [1, 0, 0, 4]; auto arr = data; auto slice = arr[1..$-1]; slice.put([2]); assert(arr == [1, 2, 0, 4]); slice.put([3]); assert(arr == [1, 2, 3, 4]); arr[1..$-1].put([0, 0]); assert(arr == data); } ``` SDB@79
Re: How to debug and watch globals in windows debugger?
On 3/28/23 6:42 PM, ryuukk_ wrote: Am i the only want who want to improve things, is it a lost cause? I'm not one to use a debugger often, but it is very helpful for many people. I lament that the Windows debugging situation out of the box is dreadful. The students I teach D to I don't show the debugger because I'm worried it would confuse them more than help. I both don't use Windows and mostly do debugging via writeln, so for something that doesn't affect me much, I tend not to put effort in. I'm hoping someone who is motivated enough will do it. If I recall correctly, visual studio debugging is better than the other solutions. But I don't know having never got debugging to work. I've heard that mago is supposed to work better, and was written for D, but is Visual Studio dependent: https://github.com/rainers/mago I wonder if there isn't some way to make this work well for other IDEs? I couldn't get it to work on VSCode. Should i move on? In any case, the debugging experience isn't perfect, but seems like a drastic measure to leave D altogether if you can't debug globals. -Steve
Re: The Phobos Put
On 3/29/23 04:48, Dennis wrote: > On Wednesday, 29 March 2023 at 11:10:42 UTC, Salih Dincer wrote: >> Why does my `put` work but the Phobos `put` doesn't work with a slice? > > Your `put` doesn't take `range` by `ref`, so it allows you to pass an > rvalue. Consequently, it doesn't advance the range from the callers > perspective. And that 'ref' is necessary because not every OutputRange can be sliced for further calls to put(). Salih does not have that problem because he is working with slices, which are (usually) trivially slicable for the next portion to be passed to put(). On the other hand, Phobos's put() works with any OutputRange so it has to take a 'ref' to advance to know where it is left off. This behavior makes its use with slices weird but sometimes such is life. :) Ali
Re: The Phobos Put
On Wednesday, 29 March 2023 at 11:10:42 UTC, Salih Dincer wrote: Why does my `put` work but the Phobos `put` doesn't work with a slice? Your `put` doesn't take `range` by `ref`, so it allows you to pass an rvalue. Consequently, it doesn't advance the range from the callers perspective.
The Phobos Put
Why does my `put` work but the Phobos `put` doesn't work with a slice? onlineapp.d(11): Error: none of the overloads of template `std.range.primitives.put` are callable using argument types `!()(int[], int[])` /dlang/dmd/linux/bin64/../../src/phobos/std/range/primitives.d(386): Candidate is: `put(R, E)(ref R r, E e)` ```d void main() { import std.range : phobos_put = put; enum testLen = 4; auto a = new int[testLen]; auto b = new int[testLen]; auto slice = a[1..$-1]; slice.phobos_put([2, 3]); //a[1..$-1].phobos_put([2, 3]); b[1..$-1].put([2, 3]); import std.conv : text; assert(a == b, text(a)); } void put(R)(R[] range, R[] source) { assert(source.length <= range.length); foreach(element; source) { range[0] = element; // range.front() range = range[1..$]; // range popFront() } } ``` SDB@79
The Phobos put()
Why does my `put` work but the Phobos `put` doesn't work with a slice? onlineapp.d(11): Error: none of the overloads of template `std.range.primitives.put` are callable using argument types `!()(int[], int[])` /dlang/dmd/linux/bin64/../../src/phobos/std/range/primitives.d(386): Candidate is: `put(R, E)(ref R r, E e)` ```d void main() { import std.range : phobos_put = put; enum testLen = 4; auto a = new int[testLen]; auto b = new int[testLen]; auto slice = a[1..$-1]; slice.phobos_put([2, 3]); //a[1..$-1].phobos_put([2, 3]); b[1..$-1].put([2, 3]); import std.conv : text; assert(a == b, text(a)); } void put(R)(R[] range, R[] source) { assert(source.length <= range.length); foreach(element; source) { range[0] = element; // range.front() range = range[1..$]; // range popFront() } } ``` SDB@79