www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - chunkBy array at compile time

reply Andrey <saasecondbox yandex.ru> writes:
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 here
So, what is wrong here and how to chunkBy at compile time?
Dec 19 2018
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/19/18 3:20 AM, Andrey wrote:
 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 here
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... -Steve
Dec 19 2018
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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:
 [...]
 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.
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. -Steve
Dec 19 2018
parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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:
[...]
 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.
[...] 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?" -- Anonymous
Dec 19 2018
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
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:
 On 12/19/18 12:20 PM, H. S. Teoh wrote:
[...]
 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.
[...] 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.
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. -Steve
Dec 19 2018
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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:
[...]
 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.
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.
[...] 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. -- YHL
Dec 19 2018