Re: Is there something like a consuming take?
On Sunday, July 7, 2019 12:36:42 PM MDT berni via Digitalmars-d-learn wrote: > On Sunday, 7 July 2019 at 09:01:53 UTC, Jonathan M Davis wrote: > > Without slicing, that's impossible without iterating over the > > elements multiple times. > > That's what I thought too, but meanwhile I think it is possible. > To get it working, the second range needs to know about the first > one and when the second one is queried the first time it has to > notify the first one, that it has to remove all remaining items > from the underlying range (and in case it still needs them, save > them) and never use it again. > > The advantage of this setup over copying the items immediately is > some sort of laziness. It might happen, that the second one will > never query or it might happen, that the first one finished > allready when the second one queries. In this cases no additional > memory is needed. > Even if the second one is queried before the first one finished, > the needed buffer might be much smaller. Having one range know about the other isn't enough. That just means that the take range would tell the other range that it had popped an element off, and then the other would know that it had to pop an element off. That still involves popping the same element on different ranges twice. In order to have popFront only called once, they have to be the same range, so when take pops an element off, it pops an element off of the other range. If both the take range and the drop range are wrappers, then it would be possible to do something with pointers to the original range where the number of elements that has been popped off is kept track of, and as long as the take range pops them all first, the drop range can just continue iterating through the original range, but if any elements from the drop range got iterated first, then it would have to save the range and start popping from there not to screw up the take range. And since pointers to the original range would have to be used to avoid having independent copies, you run the risk of all of this being screwed up by a piece of code popping an element from the original range at some point. Also, all of that machinery would likely quickly become far more expensive than simply saving the range to call take on it and then calling drop on the original. Yes, that pops the same elements multiple times, but wrapper ranges already end up calling chains of popFronts, fronts, and emptys as they iterate through a range. You rarely really get a single popFront call for a popFront unless the optimizer has actually managed to optimize out all of the layers. You can try mucking around with your own implemention of take if you want, but I'd suggest that you're just better off taking the approach that it's expected that if you use take, you're going to have to iterate through those elements twice and that if that's not acceptable, it's better to do whatever you need to do with the take range by manually operating on each of the elements rather than having them be a range. Unless random-access ranges with slicing are involved, trying to do anything that effectively slices a range without iterating over the elements multiple times is almost certainly going to be a mess. At some point, if you really want slicing semantics, then you need to make sure that your range actually has slicing rather than trying to act like it does when it doesn't. - Jonathan M Davis
Re: Using output-range overloads of SysTime.toISO{Ext}String with formatting code
07.07.2019 17:49, Joseph Rushton Wakeling пишет: it's possible to do something like `writefln!"%s"(now.toISOExtString)` and have it automatically use the output range overload rather than allocating a new string instance. This is exactly how it is intended to work: https://run.dlang.io/is/ATjAkx
Re: Why are immutable array literals heap allocated?
On Saturday, 6 July 2019 at 09:56:57 UTC, ag0aep6g wrote: On 06.07.19 01:12, Patrick Schluter wrote: On Friday, 5 July 2019 at 23:08:04 UTC, Patrick Schluter wrote: On Thursday, 4 July 2019 at 10:56:50 UTC, Nick Treleaven wrote: immutable(int[]) f() @nogc { return [1,2]; } [...] and it cannot optimize it away because it doesn't know what the caller want to do with it. It might in another module invoke it and modify it, the compiler cannot tell. auto a=f(); a[0]++; f returns immutable. typeof(a) is immutable(int[]). You can't do a[0]++. You're right, I shouldn't post at 1 am.
Re: Why does `static foreach` lead to something calling `~=` internally?
On Sunday, 7 July 2019 at 16:51:57 UTC, 0xEAB wrote: Why does this `static foreach` lead to hidden usage of operator Further notes by Dan (aka "Wild"): I added some small printfs to the compiler, http://ix.io/1NWM It seems like it lowers it into something weird
Re: Is there something like a consuming take?
On Sunday, 7 July 2019 at 09:01:53 UTC, Jonathan M Davis wrote: Without slicing, that's impossible without iterating over the elements multiple times. That's what I thought too, but meanwhile I think it is possible. To get it working, the second range needs to know about the first one and when the second one is queried the first time it has to notify the first one, that it has to remove all remaining items from the underlying range (and in case it still needs them, save them) and never use it again. The advantage of this setup over copying the items immediately is some sort of laziness. It might happen, that the second one will never query or it might happen, that the first one finished allready when the second one queries. In this cases no additional memory is needed. Even if the second one is queried before the first one finished, the needed buffer might be much smaller.
Re: Why does `static foreach` lead to something calling `~=` internally?
On Sunday, 7 July 2019 at 17:07:59 UTC, a11e99z wrote: On Sunday, 7 July 2019 at 16:51:57 UTC, 0xEAB wrote: Why does this `static foreach` lead to hidden usage of operator `~=` calls in some cases? probably same oops! this one https://forum.dlang.org/post/eidpgqohllwmuumxw...@forum.dlang.org
Re: Why does `static foreach` lead to something calling `~=` internally?
On Sunday, 7 July 2019 at 16:51:57 UTC, 0xEAB wrote: Why does this `static foreach` lead to hidden usage of operator `~=` calls in some cases? probably same https://forum.dlang.org/post/qd9ee0$2eud$1...@digitalmars.com
Why does `static foreach` lead to something calling `~=` internally?
Why does this `static foreach` lead to hidden usage of operator `~=` calls in some cases? static foreach(i; 0 .. cnt) onlineapp.d(9): Error: cannot use operator ~= in @nogc delegate onlineapp.xv!(myUDA("/")).__funcliteral2.__lambda1 import std.traits; private @safe pure nothrow @nogc { enum xv(alias uda) = function() { enum cnt = 10; static foreach(i; 0 .. cnt) { } }; } struct myUDA { string path; } @myUDA("/") void doSth(string path) { } extern(C) void main() { xv!(getUDAs!(doSth, myUDA))(); } Try: https://run.dlang.io/is/clQgeA
Using output-range overloads of SysTime.toISO{Ext}String with formatting code
Hello folks, Is there an idiomatic/intended way to use the output-range taking overloads of SysTime.toISOString and toISOExtString with stuff like `writeln` and `format`, as opposed to explicitly generating an output range to stdout or a string, and passing that to these methods? I'm a bit unfamiliar with exactly all the ins and outs of the more recent output-range-based formatting design, but what I'm interested in whether it's possible to do something like `writefln!"%s"(now.toISOExtString)` and have it automatically use the output range overload rather than allocating a new string instance. If that exact syntax doesn't work, is there anything almost as convenient? Thanks & best wishes, -- Joe
Re: Is there something like a consuming take?
On Saturday, July 6, 2019 12:58:52 PM MDT Adam D. Ruppe via Digitalmars-d- learn wrote: > On Saturday, 6 July 2019 at 18:17:26 UTC, Jonathan M Davis wrote: > > take _always_ consumes the range that it's given > > not if it hasSlicing. see > http://dpldocs.info/experimental-docs/source/std.range.d.html#L2015 > > but yeah otherwise i agree with you True enough, though if the code is generic, it still pretty much has to assume that the range was consumed. - Jonathan M Davis
Re: Is there something like a consuming take?
On Saturday, July 6, 2019 11:02:15 PM MDT berni via Digitalmars-d-learn wrote: > Or better: I'd like to hand in my voucher and get back two > vouchers, one for the first 5 bytes and one for the rest. That's > actually, what I thought, take() is doing... Without slicing, that's impossible without iterating over the elements multiple times. It would be possible to have a function like take that did something like return a tuple of two ranges where the first one is the taken elements, and the second one is the rest, but without slicing, that could only be done by calling save so that the two ranges are independent copies of the original range, and then the range that doesn't have the elements that were taken off has to internally pop off all of the elements that were taken so that its first element is the first one that wasn't taken. There's no way to magically skip the taken elements for the second range without slicing. The alternative is to manually iterate through all of the elements that you want to take, doing whatever you're going to do with them, and then doing whatever you want to do with rest of the range after that. Then iteration only occurs once. But that means that you don't have a range of the taken elements and can't do something like pass them to another algorithm as a range without constructing a new range from them, and if you're going to do that, you might as well just call save, pass the range to take, and the call drop on the original range to pop off the elements that were taken. - Jonathan M Davis