digitalmars.D.learn - chunkBy array at compile time
- Andrey (9/34) Dec 19 2018 There is an array of strings. I filter it using length of each
- Steven Schveighoffer (5/41) Dec 19 2018 Probably because it's using RefCounted.
- H. S. Teoh (14/17) Dec 19 2018 [...]
- Steven Schveighoffer (8/23) Dec 19 2018 I see, that does pose an issue, especially if you aren't traversing it
- H. S. Teoh (12/30) Dec 19 2018 [...]
- Steven Schveighoffer (10/38) Dec 19 2018 There is a problem here though -- CTFE must compile the same
- H. S. Teoh (8/28) Dec 19 2018 [...]
Hi, I have got this code:import std.array : array; import std.algorithm.mutation; import std.algorithm.iteration; import std.stdio; void main() { string input = "sieviaghp"; enum data = ["emo", "emoze", "emow", "emuo", "evuo", "ete", "ie", "vuo", "sie", "w"]; enum index = 3; enum filtered = data.filter!(value => value.length > index).array(); pragma(msg, filtered); enum GetSeq = filtered.chunkBy!((first, second) => first[index] == second[index]);//.array(); pragma(msg, GetSeq); }There is an array of strings. I filter it using length of each element. Result should be:["emoze", "emow", "emuo", "evuo"]Then I want to chuck it using symbol at position 'index' to get this:["emoze"] // group 1, symbol 'z' ["emow"] // group 2, symbol 'w' ["emuo", "evuo"] // group 1, symbol 'o'Everything I'm doing at COMPILE time! But when I try to build program I get this strange error:/dlang/dmd/linux/bin64/../../src/druntime/import/core/memory.d(827): Error: `fakePureErrno` cannot be interpreted at compile time, because it has no available source code onlineapp.d(15): compile time context created hereSo, what is wrong here and how to chunkBy at compile time?
Dec 19 2018
On 12/19/18 3:20 AM, Andrey wrote:Hi, I have got this code:Probably because it's using RefCounted. Looking at the code for chunkBy, it seems to me that the implementation is quite complex for what in my head should be a simple wrapper... -Steveimport std.array : array; import std.algorithm.mutation; import std.algorithm.iteration; import std.stdio; void main() { string input = "sieviaghp"; enum data = ["emo", "emoze", "emow", "emuo", "evuo", "ete", "ie", "vuo", "sie", "w"]; enum index = 3; enum filtered = data.filter!(value => value.length > index).array(); pragma(msg, filtered); enum GetSeq = filtered.chunkBy!((first, second) => first[index] == second[index]);//.array(); pragma(msg, GetSeq); }There is an array of strings. I filter it using length of each element. Result should be:["emoze", "emow", "emuo", "evuo"]Then I want to chuck it using symbol at position 'index' to get this:["emoze"] // group 1, symbol 'z' ["emow"] // group 2, symbol 'w' ["emuo", "evuo"] // group 1, symbol 'o'Everything I'm doing at COMPILE time! But when I try to build program I get this strange error:/dlang/dmd/linux/bin64/../../src/druntime/import/core/memory.d(827): Error: `fakePureErrno` cannot be interpreted at compile time, because it has no available source code onlineapp.d(15): compile time context created here
Dec 19 2018
On Wed, Dec 19, 2018 at 10:38:06AM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote: [...]Looking at the code for chunkBy, it seems to me that the implementation is quite complex for what in my head should be a simple wrapper...[...] It was originally a simple wrapper when I first submitted it, but Andrei requested to use RefCounted in order to work around the subrange traversal problem. I.e., in the original implementation, the underlying range traversed twice, once when each subrange is consumed, and once when you call popFront on the outer range. Having RefCounted allows us to retain a reference to the original range so that subranges will also advance the underlying range as seen by the outer range, thereby eliminating calling popFront on the underlying range twice per element. T -- People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird. -- D. Knuth
Dec 19 2018
On 12/19/18 12:20 PM, H. S. Teoh wrote:On Wed, Dec 19, 2018 at 10:38:06AM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote: [...]I see, that does pose an issue, especially if you aren't traversing it in order. Communicating back to the "outer" range where the traversal should stop requires having a reference to it in the subrange. However, in terms of a random-access range, or even an array, it should be pretty straightforward to... oh wait, these are narrow strings. nevermind. -SteveLooking at the code for chunkBy, it seems to me that the implementation is quite complex for what in my head should be a simple wrapper...[...] It was originally a simple wrapper when I first submitted it, but Andrei requested to use RefCounted in order to work around the subrange traversal problem. I.e., in the original implementation, the underlying range traversed twice, once when each subrange is consumed, and once when you call popFront on the outer range. Having RefCounted allows us to retain a reference to the original range so that subranges will also advance the underlying range as seen by the outer range, thereby eliminating calling popFront on the underlying range twice per element.
Dec 19 2018
On Wed, Dec 19, 2018 at 01:19:28PM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote:On 12/19/18 12:20 PM, H. S. Teoh wrote:[...][...] For CTFE, though, we don't really care about calling popFront twice, so I surmise that we should be able to just use the original non-RefCounted implementation. It's not hard, just take out the bits where the subranges communicate with the outer range, and just have each subrange carry its own instance of the underlying range. It will incur some CTFE performance hit, but that's better than not being CTFE-able at all. T -- "The whole problem with the world is that fools and fanatics are always so certain of themselves, but wiser people so full of doubts." -- Bertrand Russell. "How come he didn't put 'I think' at the end of it?" -- AnonymousIt was originally a simple wrapper when I first submitted it, but Andrei requested to use RefCounted in order to work around the subrange traversal problem. I.e., in the original implementation, the underlying range traversed twice, once when each subrange is consumed, and once when you call popFront on the outer range. Having RefCounted allows us to retain a reference to the original range so that subranges will also advance the underlying range as seen by the outer range, thereby eliminating calling popFront on the underlying range twice per element.I see, that does pose an issue, especially if you aren't traversing it in order. Communicating back to the "outer" range where the traversal should stop requires having a reference to it in the subrange. However, in terms of a random-access range, or even an array, it should be pretty straightforward to... oh wait, these are narrow strings. nevermind.
Dec 19 2018
On 12/19/18 1:30 PM, H. S. Teoh wrote:On Wed, Dec 19, 2018 at 01:19:28PM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote:There is a problem here though -- CTFE must compile the same (essentially) as normal runtime. We can make different code paths for CTFE, but the problem I see in the meantime is that the TYPE must be the same. In other words, the CTFE version shouldn't use RefCounted, but the type already has that in there. I also see some bad things happening if initialized at compile time via CTFE, but then used at runtime. But I don't know if that works or not. -SteveOn 12/19/18 12:20 PM, H. S. Teoh wrote:[...][...] For CTFE, though, we don't really care about calling popFront twice, so I surmise that we should be able to just use the original non-RefCounted implementation. It's not hard, just take out the bits where the subranges communicate with the outer range, and just have each subrange carry its own instance of the underlying range. It will incur some CTFE performance hit, but that's better than not being CTFE-able at all.It was originally a simple wrapper when I first submitted it, but Andrei requested to use RefCounted in order to work around the subrange traversal problem. I.e., in the original implementation, the underlying range traversed twice, once when each subrange is consumed, and once when you call popFront on the outer range. Having RefCounted allows us to retain a reference to the original range so that subranges will also advance the underlying range as seen by the outer range, thereby eliminating calling popFront on the underlying range twice per element.I see, that does pose an issue, especially if you aren't traversing it in order. Communicating back to the "outer" range where the traversal should stop requires having a reference to it in the subrange. However, in terms of a random-access range, or even an array, it should be pretty straightforward to... oh wait, these are narrow strings. nevermind.
Dec 19 2018
On Wed, Dec 19, 2018 at 02:01:28PM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote:On 12/19/18 1:30 PM, H. S. Teoh wrote:[...][...] Hmph. This is an annoying limitation. :-/ And one of the major downsides of using RefCounted in the implementation. :-( T -- It's bad luck to be superstitious. -- YHLFor CTFE, though, we don't really care about calling popFront twice, so I surmise that we should be able to just use the original non-RefCounted implementation. It's not hard, just take out the bits where the subranges communicate with the outer range, and just have each subrange carry its own instance of the underlying range. It will incur some CTFE performance hit, but that's better than not being CTFE-able at all.There is a problem here though -- CTFE must compile the same (essentially) as normal runtime. We can make different code paths for CTFE, but the problem I see in the meantime is that the TYPE must be the same. In other words, the CTFE version shouldn't use RefCounted, but the type already has that in there. I also see some bad things happening if initialized at compile time via CTFE, but then used at runtime. But I don't know if that works or not.
Dec 19 2018