Re: Deduct and return class type
On Saturday, 23 January 2021 at 05:54:09 UTC, Виталий Фадеев wrote: On Saturday, 23 January 2021 at 05:39:18 UTC, Виталий Фадеев wrote: Context: data + GUI List Goal: auto list = new List( data ); I want 'this( T )( T data )' deduction: class A( T ) { this( T )( T data ) { // ... } } What way to implement this ? Rules: 1. if class is template 2. if ctor is template 3. if ctor template arg have same name with class template arg name (example: T ) 4. deduct T of ctor 5. set type T for class template ( or put in suggestion queue ) Verify, please. Where source ? Where deduction implementation ?
Re: which free operating systems have a gtkd package?
https://d-apt.sourceforge.io/ Or you could use dub and not worry about where its installed. https://github.com/gtkd-developers/GtkD/wiki/Hello-World-Example-on-Ubuntu-19.10-(Linux)
which free operating systems have a gtkd package?
Debian 10 has a nice gtkd package, stored in libgtkd-3-dev i believe (when i installed it, i installed several packages at once, basically everything that had 'gtkd' as a substring in the package name). It uses ldmd2 (part of the ldc package). So it's possible to write and build a gtkd application using only debian packages. I've done this with debian 10, and it works well imvho. Although i have not tried it, it looks like ubuntu (20.4 and presumably later) also has a gtkd package. I'm going to install a new os on a machine, and i'm trying to pick one that has a gtkd package available, so that all the d imports are in standard locations and i don't have to mess with anything. So debian 10 and ubuntu 20.4 are candidates, but i'm wondering if there are others. (I tried to find gtkd on linux mint but did not see a package for it, but man i could sure be wrong.) Thanks in advance for any info! dan
Re: Deduct and return class type
On Saturday, 23 January 2021 at 05:54:09 UTC, Виталий Фадеев wrote: auto listFactory( T )( T data ) { return new List!( T )( data ); } This is the correct way to do it in D; it's annoying, I know. (Personally, I usually shorten `listFactory` to just `list` to make the name as similar as possible to the type name, without actually causing a collision.)
Re: Deduct and return class type
On Saturday, 23 January 2021 at 05:54:09 UTC, Виталий Фадеев wrote: But, how to create class instance with type deduction in usual way ? auto list = new List( extensions ); You can't; there's no type deduction for constructors.
Re: Deduct and return class type
On Saturday, 23 January 2021 at 05:39:18 UTC, Виталий Фадеев wrote: Context: data + GUI List Goal: auto list = new List( data ); Of course, we can use 'factory': import std.stdio; template List( alias T ) { class List { T data; this( T data ) { this.data = data; } // data usage... } } auto listFactory( T )( T data ) { return new List!( T )( data ); } void main() { string[] extensions = [ ".d", ".di" ]; auto list = listFactory( extensions ); //auto list = new List( extensions ); } source: https://run.dlang.io/is/y167tu But, how to create class instance with type deduction in usual way ? auto list = new List( extensions );
Deduct and return class type
Context: data + GUI List Goal: auto list = new List( data ); Concept: class is created in the usual way : new List( data ) store inside the class: T data; type T deducted : ( T )( T data ) Tried way: template List( T ) { class List { T data; this( T data ) { this.data = data; } // data usage... } } void main() { string[] extensions = [ ".d", ".di" ]; auto list = new List( extensions ); } Source: https://run.dlang.io/is/Bw2zHB Question: How to implement on D beauty clean flexible code ? like a: auto list = new List( data ); How to return from 'List( data )' class type ?
Re: std.algorithm.splitter on a string not always bidirectional
On Friday, 22 January 2021 at 17:29:08 UTC, Steven Schveighoffer wrote: On 1/22/21 11:57 AM, Jon Degenhardt wrote: [...] Another way to look at it: If split (eager) took a predicate, that 'xyz.splitter(args).back' and 'xyz.split(args).back' should produce the same result. But they will not with the example given. With what example given? The example you gave is incomplete (what are args?) [...] Here is a case for which iterating forwards yields a different sequence from iterating backwards (if we were to allow the latter): "bbcbcba".splitter("bcb") Iterating forwards gives us the subranges: "b", "cba". Iterating backwards gives us: "a", "bbc". So it cannot be a bidirectional range, at least not in the expected sense that iterating from the back ought to give us the same subranges as iterating from the front, only in a reverse order. Here iterating backwards yields a completely different decomposition. --T
Re: std.algorithm.splitter on a string not always bidirectional
On Friday, 22 January 2021 at 17:29:08 UTC, Steven Schveighoffer wrote: On 1/22/21 11:57 AM, Jon Degenhardt wrote: I think the idea is that if a construct like 'xyz.splitter(args)' produces a range with the sequence of elements {"a", "bc", "def"}, then 'xyz.splitter(args).back' should produce "def". But, if finding the split points starting from the back results in something like {"f", "de", "abc"} then that relationship hasn't held, and the results are unexpected. But that is possible with all 3 splitter variants. Why is one allowed to be bidirectional and the others are not? I'm not defending it, just explaining what I believe the thinking was based on the examination I did. It wasn't just looking at the code, there was a discussion somewhere. A forum discussion, PR discussion, bug or code comments. Something somewhere, but I don't remember exactly. However, to answer your question - The relationship described is guaranteed if the basis for the split is a single element. If the range is a string, that's a single 'char'. If the range is composed of integers, then a single integer. Note that if the basis for the split is itself a range, then the relationship described is not guaranteed. Personally, I can see a good argument that bidirectionality should not be supported in any of these cases, and instead force the user to choose between eager splitting or reversing the range via retro. For the common case of strings, the further argument could be made that the distinction between char and dchar is another point of inconsistency. Regardless whether the choices made were the best choices, there was some thinking that went into it, and it is worth understanding the thinking when considering changes. --Jon
Re: std.algorithm.splitter on a string not always bidirectional
On Friday, 22 January 2021 at 17:29:08 UTC, Steven Schveighoffer wrote: On 1/22/21 11:57 AM, Jon Degenhardt wrote: [...] But that is possible with all 3 splitter variants. Why is one allowed to be bidirectional and the others are not? [...] +1
Re: std.algorithm.splitter on a string not always bidirectional
On 1/22/21 11:57 AM, Jon Degenhardt wrote: I think the idea is that if a construct like 'xyz.splitter(args)' produces a range with the sequence of elements {"a", "bc", "def"}, then 'xyz.splitter(args).back' should produce "def". But, if finding the split points starting from the back results in something like {"f", "de", "abc"} then that relationship hasn't held, and the results are unexpected. But that is possible with all 3 splitter variants. Why is one allowed to be bidirectional and the others are not? Another way to look at it: If split (eager) took a predicate, that 'xyz.splitter(args).back' and 'xyz.split(args).back' should produce the same result. But they will not with the example given. With what example given? The example you gave is incomplete (what are args?) I believe these consistency issues are the reason why the bidirectional support is limited. Note: I didn't design any of this, but I did redo the examples in the documentation at one point, which is why I looked at this. We sometimes spend time justifying why the existing implementation is the way it is, when we should be questioning why it was designed that way in the first place. If splitter should be restricted based on possible edge cases, then it should be consistently restricted. My opinion is it should not be restricted in any case. All three cases provide equal possibility of bidirectional correctness. The one case that should be restricted is the splitter version that accepts a non-bi-directional delimiting range. -Steve
Re: std.algorithm.splitter on a string not always bidirectional
On Friday, 22 January 2021 at 14:14:50 UTC, Steven Schveighoffer wrote: On 1/22/21 12:55 AM, Jon Degenhardt wrote: On Friday, 22 January 2021 at 05:51:38 UTC, Jon Degenhardt wrote: On Thursday, 21 January 2021 at 22:43:37 UTC, Steven Schveighoffer wrote: auto sp1 = "a|b|c".splitter('|'); writeln(sp1.back); // ok auto sp2 = "a.b|c".splitter!(v => !isAlphaNum(v)); writeln(sp2.back); // error, not bidirectional Why? is it an oversight, or is there a good reason for it? I believe the reason is two-fold. First, splitter is lazy. Second, the range splitting is defined in the forward direction, not the reverse direction. A bidirectional range is only supported if it is guaranteed that the splits will occur at the same points in the range when run in either direction. That's why the single element delimiter is supported. Its clearly the case for the predicate function in your example. If that's known to be always true then perhaps it would make sense to enhance splitter to generate bidirectional results in this case. Note that the predicate might use a random number generator to pick the split points. Even for same sequence of random numbers, the split points would be different if run from the front than if run from the back. I think this isn't a good explanation. All forms of splitter accept a predicate (including the one which supports a bi-directional result). Many other phobos algorithms that accept a predicate provide bidirectional support. The splitter result is also a forward range (which makes no sense in the context of random splits). Finally, I'd suggest that even if you split based on a subrange that is also bidirectional, it doesn't make sense that you couldn't split backwards based on that. Common sense says a range split on substrings is the same whether you split it forwards or backwards. I can do this too (and in fact I will, because it works, even though it's horrifically ugly): auto sp3 = "a.b|c".splitter!((c, unused) => !isAlphaNum(c))('?'); writeln(sp3.back); // ok Looking at the code, it looks like the first form of spltter uses a different result struct than the other two (which have a common implementation). It just needs cleanup. -Steve I think the idea is that if a construct like 'xyz.splitter(args)' produces a range with the sequence of elements {"a", "bc", "def"}, then 'xyz.splitter(args).back' should produce "def". But, if finding the split points starting from the back results in something like {"f", "de", "abc"} then that relationship hasn't held, and the results are unexpected. Note that in the above example, 'xyz.retro.splitter(args)' might produce {"f", "ed", "cba"}, so again not the same. Another way to look at it: If split (eager) took a predicate, that 'xyz.splitter(args).back' and 'xyz.split(args).back' should produce the same result. But they will not with the example given. I believe these consistency issues are the reason why the bidirectional support is limited. Note: I didn't design any of this, but I did redo the examples in the documentation at one point, which is why I looked at this. --Jon
Re: Dub seems to be using an earlier version of the dependency that I tell it to use
On Friday, 22 January 2021 at 15:57:00 UTC, Steven Schveighoffer wrote: On 1/22/21 10:34 AM, vnr wrote: [...] It just needs a tag. delimited (for example) added here: https://github.com/DmitryOlshansky/pry-parser/commit/808d01c30b50a928f5795dab7e6c0a7a392899b0 May of 2017, Last tag was v0.3.2 on January 2017. Just add an issue, ask Dmitry to release a new version. -Steve All right, I'll do that, thank you.
Re: Dub seems to be using an earlier version of the dependency that I tell it to use
On 1/22/21 10:34 AM, vnr wrote: Hello I'm trying to use the combinator Pry parser library (https://code.dlang.org/packages/pry/0.3.2), but, as I'll explain in the rest of this message, it seems to be a bad version of the lib that dub downloads me. So, simply by adding pry as a dependency on a virgin project, and using features that are present in the documentation and examples, dub indicates that these features are non-existent. I have identified the following combinators that were not recognized: `delimited`, `optional`, `skipWs`, `slice`, `utfString` and also the `stk `atom. There may be others. Searching in the code and in the different versions, it seems that the combinators I quoted are not part of the old versions (under 0.3.2), but it is indeed this version that I included in the blank project... Here is a simple example (by the way, the examples in the "example" folder don't work for me either): ```d import pry; import std.stdio; void main() { alias S = SimpleStream!string; with(parsers!S) { auto p = delimited(range!('0', '9').rep, tk!','); auto s = "3,3,4".stream; string[] values; S.Error err; auto r = p.parse(s, values, err); writeln(r); } } ``` With the following dub.sdl : ```sdl name "test" dependency "pry" version="~>0.3.2" ``` By building, I get: ```bash $ dub build pry 0.3.2: target for configuration "library" is up to date. test ~master: building configuration "application"... source\app.d(9,12): Error: undefined identifier delimited ``` What's wrong with all this? How come I'm using the "newest" version of pry, but an older version of the library seems to be used instead? Is there a problem with the way I use dub, or is the library too old (4 years old anyway)? It just needs a tag. delimited (for example) added here: https://github.com/DmitryOlshansky/pry-parser/commit/808d01c30b50a928f5795dab7e6c0a7a392899b0 May of 2017, Last tag was v0.3.2 on January 2017. Just add an issue, ask Dmitry to release a new version. -Steve
Dub seems to be using an earlier version of the dependency that I tell it to use
Hello I'm trying to use the combinator Pry parser library (https://code.dlang.org/packages/pry/0.3.2), but, as I'll explain in the rest of this message, it seems to be a bad version of the lib that dub downloads me. So, simply by adding pry as a dependency on a virgin project, and using features that are present in the documentation and examples, dub indicates that these features are non-existent. I have identified the following combinators that were not recognized: `delimited`, `optional`, `skipWs`, `slice`, `utfString` and also the `stk `atom. There may be others. Searching in the code and in the different versions, it seems that the combinators I quoted are not part of the old versions (under 0.3.2), but it is indeed this version that I included in the blank project... Here is a simple example (by the way, the examples in the "example" folder don't work for me either): ```d import pry; import std.stdio; void main() { alias S = SimpleStream!string; with(parsers!S) { auto p = delimited(range!('0', '9').rep, tk!','); auto s = "3,3,4".stream; string[] values; S.Error err; auto r = p.parse(s, values, err); writeln(r); } } ``` With the following dub.sdl : ```sdl name "test" dependency "pry" version="~>0.3.2" ``` By building, I get: ```bash $ dub build pry 0.3.2: target for configuration "library" is up to date. test ~master: building configuration "application"... source\app.d(9,12): Error: undefined identifier delimited ``` What's wrong with all this? How come I'm using the "newest" version of pry, but an older version of the library seems to be used instead? Is there a problem with the way I use dub, or is the library too old (4 years old anyway)? I only need to analyze a very simple format, so changing library or method won't be complicated, but since I already have a base with this lib, I was wondering if there was not a way to continue with it. Thanks for your help!
Re: std.algorithm.splitter on a string not always bidirectional
On 1/22/21 12:55 AM, Jon Degenhardt wrote: On Friday, 22 January 2021 at 05:51:38 UTC, Jon Degenhardt wrote: On Thursday, 21 January 2021 at 22:43:37 UTC, Steven Schveighoffer wrote: auto sp1 = "a|b|c".splitter('|'); writeln(sp1.back); // ok auto sp2 = "a.b|c".splitter!(v => !isAlphaNum(v)); writeln(sp2.back); // error, not bidirectional Why? is it an oversight, or is there a good reason for it? I believe the reason is two-fold. First, splitter is lazy. Second, the range splitting is defined in the forward direction, not the reverse direction. A bidirectional range is only supported if it is guaranteed that the splits will occur at the same points in the range when run in either direction. That's why the single element delimiter is supported. Its clearly the case for the predicate function in your example. If that's known to be always true then perhaps it would make sense to enhance splitter to generate bidirectional results in this case. Note that the predicate might use a random number generator to pick the split points. Even for same sequence of random numbers, the split points would be different if run from the front than if run from the back. I think this isn't a good explanation. All forms of splitter accept a predicate (including the one which supports a bi-directional result). Many other phobos algorithms that accept a predicate provide bidirectional support. The splitter result is also a forward range (which makes no sense in the context of random splits). Finally, I'd suggest that even if you split based on a subrange that is also bidirectional, it doesn't make sense that you couldn't split backwards based on that. Common sense says a range split on substrings is the same whether you split it forwards or backwards. I can do this too (and in fact I will, because it works, even though it's horrifically ugly): auto sp3 = "a.b|c".splitter!((c, unused) => !isAlphaNum(c))('?'); writeln(sp3.back); // ok Looking at the code, it looks like the first form of spltter uses a different result struct than the other two (which have a common implementation). It just needs cleanup. -Steve
Re: Issue with socket recieve
On Wednesday, 20 January 2021 at 21:31:54 UTC, Tim wrote: Hi all, I'm having a really terrible bug that seemed to come from nowhere and is really hard to narrow down. You may be hitting this issue: https://issues.dlang.org/show_bug.cgi?id=7349 FWIW, popped onto the radar in the most recent Foundation meeting.
Re: Issue with socket recieve
On Thursday, 21 January 2021 at 03:30:50 UTC, Tim wrote: On Thursday, 21 January 2021 at 03:21:41 UTC, Adam D. Ruppe wrote: On Wednesday, 20 January 2021 at 21:31:54 UTC, Tim wrote: [...] [snip] generate a core.exception.InvalidMemoryOperationError that I can't catch. None of this makes much sense given the code you provided. InvalidMemoryOperationError (the scariest thing in D btw, such a pain to debug) is usually caused by a class destructor somewhere, and none of those should be trying to resolve those files. Do you have any destructors defined? You seem like a rather switched-on fellow. Would you be able to send me an email at some point at tim.oli...@tutanota.com. I have a proposition for you. On Discord fyi