Re: Deduct and return class type

2021-01-22 Thread Виталий Фадеев via Digitalmars-d-learn
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?

2021-01-22 Thread rikki cattermole via Digitalmars-d-learn

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?

2021-01-22 Thread dan via Digitalmars-d-learn
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

2021-01-22 Thread tsbockman via Digitalmars-d-learn
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

2021-01-22 Thread Paul Backus via Digitalmars-d-learn
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

2021-01-22 Thread Виталий Фадеев via Digitalmars-d-learn
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

2021-01-22 Thread Виталий Фадеев via Digitalmars-d-learn

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

2021-01-22 Thread H. S. Teoh via Digitalmars-d-learn
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

2021-01-22 Thread Jon Degenhardt via Digitalmars-d-learn
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

2021-01-22 Thread Imperatorn via Digitalmars-d-learn
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

2021-01-22 Thread Steven Schveighoffer via Digitalmars-d-learn

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

2021-01-22 Thread Jon Degenhardt via Digitalmars-d-learn
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

2021-01-22 Thread vnr via Digitalmars-d-learn
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

2021-01-22 Thread Steven Schveighoffer via Digitalmars-d-learn

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

2021-01-22 Thread vnr via Digitalmars-d-learn

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

2021-01-22 Thread Steven Schveighoffer via Digitalmars-d-learn

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

2021-01-22 Thread Mike Parker via Digitalmars-d-learn

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

2021-01-22 Thread Imperatorn via Digitalmars-d-learn

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