Re: How to iterate over range two items at a time

2020-02-16 Thread Mitacha via Digitalmars-d-learn

On Monday, 17 February 2020 at 05:04:02 UTC, Adnan wrote:
What is the equivalent of Rust's chunks_exact()[1] method in D? 
I want to iterate over a spitted string two chunks at a time.



[1] 
https://doc.rust-lang.org/beta/std/primitive.slice.html#method.chunks_exact


It sounds similar to `slide` 
https://dlang.org/phobos/std_range.html#slide


Re: AA code 50x slower

2020-02-16 Thread Nathan S. via Digitalmars-d-learn

On Sunday, 16 February 2020 at 12:57:43 UTC, AlphaPurned wrote:

template AA(string[] S)
{
auto _do() { int[string] d; foreach(s; S) d[s] = 0; return d; }
enum AA = _do;
}


if (t in AA!(["a", "and", "mp4", "mp3", "the", "with", "live", 
"no", "&", "of", "band"])) continue;		



The if statement literally causes a 50x slow down of the code. 
(LDC debug, dmd debug takes about 1000 times longer)


template AA(string[] S) {
__gshared int[string] AA;
shared static this() {
int[string] d;
foreach (s; S)
d[s] = 0;
AA = d;
};
}
if (t in AA!(["a", "and", "mp4", "mp3", "the", "with", "live", 
"no", "&", "of", "band"])) continue;


This will have the performance you want if you don't care whether 
it works in CTFE.


Re: dub / use git branch

2020-02-16 Thread Basile B. via Digitalmars-d-learn
On Sunday, 16 February 2020 at 14:01:13 UTC, Robert M. Münch 
wrote:
I want to use a specific branch version if a package. I 
specified the branch version in a dub.selections.json file.


But it seems that dub requires a ZIP file that can be 
downloaded from code.dlang.org, which of course fails because 
the branch is only available on github.


Fetching rtree ~fix-#3 (getting selected version)...
Downloading https://code.dlang.org/packages/rtree/~fix-#3.zip 
failed with 404 (Not Found).


How am I supposed to switch to a branch version of a package to 
try a bug-fix version for example?


We fail to get the most basic support for git since a full year 
now:


https://github.com/dlang/dub/pull/1802
https://github.com/dlang/dub/pull/1798
https://github.com/dlang/dub/pull/1403

So for now you have two options:

1/ in your project recipe, you can add the dependency as a path 
to the git submodule representing the DUB package and do the 
branch checkout manually or using a DUB pregenerate command.


2/ ask to the dependency maintainer to add a git tag in the 
branch you'd like to use.
the DUB registry will automatically create a new version of the 
package, using the right branch. This is done for example for stx 
allocator and so far this work.


How to get the name of an object's class at compile time?

2020-02-16 Thread Nathan S. via Digitalmars-d-learn

What I want is something like this:


string className(in Object obj) {
return obj is null ? "null" : typeid(obj).name;
}


...except I want it to work in CTFE. What is the way to do this 
in D?


Re: How to iterate over range two items at a time

2020-02-16 Thread mipri via Digitalmars-d-learn

On Monday, 17 February 2020 at 05:04:02 UTC, Adnan wrote:
What is the equivalent of Rust's chunks_exact()[1] method in D? 
I want to iterate over a spitted string two chunks at a time.



[1] 
https://doc.rust-lang.org/beta/std/primitive.slice.html#method.chunks_exact


And, after actually reading the Rust doc, I see that you want
to iterate over a string two chars at a time while discarding
any remaining 1-length chunk.

There isn't an equivalent of that.

A quick one is

auto chunks_exact(R)(R r, size_t n) {
return r.take(r.length - r.length%n).chunks(n);
}

but to get the exact same behavior you'll want to return a
range type that stores the final chunk.


Re: How to iterate over range two items at a time

2020-02-16 Thread mipri via Digitalmars-d-learn

On Monday, 17 February 2020 at 05:04:02 UTC, Adnan wrote:
What is the equivalent of Rust's chunks_exact()[1] method in D? 
I want to iterate over a spitted string two chunks at a time.



[1] 
https://doc.rust-lang.org/beta/std/primitive.slice.html#method.chunks_exact


$ rdmd --eval '"hello world".chunks(2).each!writeln'
he
ll
o
wo
rl
d

$ rdmd --eval '"hello 
world".chunks(2).map!"a.array.length".each!writeln'

2
2
2
2
2
1

Note the .array; each chunk is a range type.

$ rdmd --eval 'typeid("hello world".chunks(2).take(1)).writeln'
std.range.Take!(Chunks!string).Take



How to iterate over range two items at a time

2020-02-16 Thread Adnan via Digitalmars-d-learn
What is the equivalent of Rust's chunks_exact()[1] method in D? I 
want to iterate over a spitted string two chunks at a time.



[1] 
https://doc.rust-lang.org/beta/std/primitive.slice.html#method.chunks_exact


Re: AA code 50x slower

2020-02-16 Thread evilrat via Digitalmars-d-learn

On Monday, 17 February 2020 at 02:18:15 UTC, AlphaPurned wrote:


But the input to the AA is static, it never changes. I thought 
D would essentially treat it as a constant and compute it once?


(I'm only using the AA in one place but it is in another 
template that is used twice. I can't imagine it would couldn't 
figure out how to optimzie it, I'm feeding it a constant so...)


The reason is that AA is a runtime-dependent construct, but it's 
not available at compile time, nor that there is some known ahead 
of time interface to it(ok, not exactly but something like that), 
so instead it does this whenever AA enum is referenced.


See Steven's code above, it might work like you thought however 
despite whatever input it will likely have exactly one variant of 
it because instantiated on string[] type, if that's the case and 
this is not what you wanted you might try tuple parameter instead 
of string[].


Re: Doubt about compiler: Front-End vs Back-End

2020-02-16 Thread Curious via Digitalmars-d-learn

On Monday, 17 February 2020 at 03:07:33 UTC, Adam D. Ruppe wrote:

On Monday, 17 February 2020 at 02:55:56 UTC, Curious wrote:
Note the ending: "The same front-end code is used by DMD, GDC 
and LDC."


But what the meaning of this sentence?


They literally share like 97% of the code.

Looking over Github: https://github.com/dlang/ I see DMD, 
Phobos and so on, but no separated project called Front-End.


Compare dmd:
https://github.com/dlang/dmd/

to ldc:
https://github.com/ldc-developers/ldc/

dmd has a `src` folder. ldc has a `dmd` folder. inside those 
you'll find most the content is identical - written in D btw.


gdc is a little different because it is based on an older 
version of dmd when it was written in C++ before it was ported 
to D. it will be moving to the D version probably later this 
year too, but it had to be C++ at first for gcc inclusion. But 
even so, it is still almost all the same code and even has some 
patches from new D versions ported back to c++ for it.



But basically all three compilers are branches of the same 
codebase with most the same patches applied going forward so 
they share the vast, vast majority of frontend code.


Hmm I see now, so DMD compiler has both Front-End and Back-End, 
the LDC in this case is getting only the Front-End part from DMD 
project.


So since the Front-End written in D and the GDC is still the 
older version (C++), then they need to replicate the new features 
from D to C++. Well this seems a pain.


By the way since the Front-End is in D, so it's occurring 
bootstrapping, interesting.


Thanks.


Re: Doubt about compiler: Front-End vs Back-End

2020-02-16 Thread Adam D. Ruppe via Digitalmars-d-learn

On Monday, 17 February 2020 at 02:55:56 UTC, Curious wrote:
Note the ending: "The same front-end code is used by DMD, GDC 
and LDC."


But what the meaning of this sentence?


They literally share like 97% of the code.

Looking over Github: https://github.com/dlang/ I see DMD, 
Phobos and so on, but no separated project called Front-End.


Compare dmd:
https://github.com/dlang/dmd/

to ldc:
https://github.com/ldc-developers/ldc/

dmd has a `src` folder. ldc has a `dmd` folder. inside those 
you'll find most the content is identical - written in D btw.


gdc is a little different because it is based on an older version 
of dmd when it was written in C++ before it was ported to D. it 
will be moving to the D version probably later this year too, but 
it had to be C++ at first for gcc inclusion. But even so, it is 
still almost all the same code and even has some patches from new 
D versions ported back to c++ for it.



But basically all three compilers are branches of the same 
codebase with most the same patches applied going forward so they 
share the vast, vast majority of frontend code.


Doubt about compiler: Front-End vs Back-End

2020-02-16 Thread Curious via Digitalmars-d-learn

Hi, could anyone shed a light about the Frond-End and Back-End?

I understood the Back-End part, where "roughly" each compiler 
will generate a machine code based on a IR (Intermediate 
Representation) generated by the Front-End.


But I'm having trouble with the Front-End part, and for what I 
gather here: https://wiki.dlang.org/DMD_Source_Guide


The front-end (DMD-FE) implements all things D-specific: lexing 
and parsing D syntax, instantiating templates, producing error 
messages, etc. The same front-end code is used by DMD, GDC and 
LDC.


Note the ending: "The same front-end code is used by DMD, GDC and 
LDC."


But what the meaning of this sentence?

These are 3 different projects so how they share the SAME 
front-end or how they are connected? Is it a source written in 
*.CPP for example and the 3 compilers uses the same source? Or 
the "SAME" means each compiler needs to implement the same code?


Looking over Github: https://github.com/dlang/ I see DMD, Phobos 
and so on, but no separated project called Front-End.


Thanks in advance.


Re: AA code 50x slower

2020-02-16 Thread AlphaPurned via Digitalmars-d-learn

On Sunday, 16 February 2020 at 13:50:49 UTC, evilrat wrote:

On Sunday, 16 February 2020 at 12:57:43 UTC, AlphaPurned wrote:

template AA(string[] S)
{
	auto _do() { int[string] d; foreach(s; S) d[s] = 0; return d; 
}

enum AA = _do;
}



My best guess is that enum arrays(except strings) and AA's are 
instantiated every time you access them.

This is especially bad with loops.

Probably you want static or module level variable instead.
Module level AA's can't have compile time initializer, however 
you can do initialization with module constructor instead.

https://dlang.org/spec/module.html#staticorder


But the input to the AA is static, it never changes. I thought D 
would essentially treat it as a constant and compute it once?


(I'm only using the AA in one place but it is in another template 
that is used twice. I can't imagine it would couldn't figure out 
how to optimzie it, I'm feeding it a constant so...)




Re: Difference between range `save` and copy constructor

2020-02-16 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, February 16, 2020 12:22:01 PM MST Paul Backus via Digitalmars-d-
learn wrote:
> On Sunday, 16 February 2020 at 18:11:11 UTC, Jonathan M Davis
>
> wrote:
> > Either way, generic code should never be using a range after
> > it's been copied, and copying is a key part of how idiomatic,
> > range-based code works in D.
>
> "Copy and then never use the original again" is conceptually the
> same thing as "move", right? In which case, generic code can
> accommodate non-copyable ranges *and* more clearly communicate
> its intent by using `move` instead of a naked copy.

We already have enough of a mess with save without making things even worse
by trying to add moves into the mix. Also, non-copyable ranges have never
really been a thing, and I really don't want to see things complicated even
further trying to support such an uncommon use case. There are too many
weird corner cases with ranges as it is.

- Jonathan M Davis





Re: "register int n" alternative

2020-02-16 Thread lithium iodate via Digitalmars-d-learn

On Sunday, 16 February 2020 at 15:15:44 UTC, Stefan Koch wrote:

The register keyword as been deprecated for ages in C.
Since the compiler cannot actually guarantee that the variable 
will be a register.

As a result D does not have the register keyword.


That only applies for C++, where it doesn't (or rather didn't) 
even do the same thing as in C. In C it's an optimization aid 
with actual semantic implications. A register storage-class 
variable cannot be aliased, in fact, any attempt should cause 
compilation failure.


Whether it actually helps modern compilers with optimization is 
of course another matter ;)


Re: Difference between range `save` and copy constructor

2020-02-16 Thread Paul Backus via Digitalmars-d-learn
On Sunday, 16 February 2020 at 18:11:11 UTC, Jonathan M Davis 
wrote:
Either way, generic code should never be using a range after 
it's been copied, and copying is a key part of how idiomatic, 
range-based code works in D.


"Copy and then never use the original again" is conceptually the 
same thing as "move", right? In which case, generic code can 
accommodate non-copyable ranges *and* more clearly communicate 
its intent by using `move` instead of a naked copy.


Re: Difference between range `save` and copy constructor

2020-02-16 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, February 16, 2020 10:53:36 AM MST Paul Backus via Digitalmars-d-
learn wrote:
> On Sunday, 16 February 2020 at 17:10:24 UTC, Jonathan M Davis
>
> wrote:
> > On Sunday, February 16, 2020 7:29:11 AM MST uranuz via
> >
> >> This is working fine with disabled postblit...
> >> import std;
> >>
> >> struct SS
> >> {
> >>
> >>  @disable this(this); // Disabled copy
> >>
> >>  bool _empty = false;
> >>
> >>  bool empty() @property {
> >>
> >>  return _empty;
> >>
> >>  }
> >>
> >>  void popFront() {
> >>
> >> _empty = true;
> >>
> >>  }
> >>
> >>  int front() @property { return 10; }
> >>
> >> }
> >>
> >>
> >> void main()
> >> {
> >>
> >>  foreach( it; SS() ) { writeln(it); }
> >>
> >> }
> >>
> >> Am I missing something?
> >
> > That code compiles, because you're passing a temporary to
> > foreach. So, the compiler does a move instead of a copy. It's
> > the difference between
> >
> > auto ss = SS();
> >
> > and
> >
> > SS ss;
> > auto ss2 = ss;
> >
> > If your main were
> >
> > void main()
> > {
> >
> > SS ss;
> > foreach( it; ss ) { writeln(it); }
> >
> > }
> >
> > then it would not compile.
>
> On the other hand, this does work:
>
>  void main()
>  {
>  SS ss;
>  foreach( it; move(ss) ) { writeln(it); }
>  }
>
> So perhaps the correct approach is to use `move` when copying
> input ranges.

Given that the way that almost all range-based functions work is to copy the
range that they're given (often then wrapping it in another range that's
returned), I don't see how it would make sense to use move outside of very
specific circumstances. If you pass a range to a function, and it's a basic
input range, then you just use the range via the return value (be it the
same range returned directly or returned within a wraper range), and if it's
a forward range, you call save before passing it to the function if you want
to be able to use the range directly again. Either way, generic code should
never be using a range after it's been copied, and copying is a key part of
how idiomatic, range-based code works in D.

And really, using move just to be able to use an uncopyable range with
foreach doesn't make a lot of sense, since if that's what you want to do,
you can always just use a normal for loop. Regardless, there isn't much
point in declaring a range type that can't be copied, since it's pretty much
only going to work with code that you write.

- Jonathan M Davis





Re: Difference between range `save` and copy constructor

2020-02-16 Thread Paul Backus via Digitalmars-d-learn
On Sunday, 16 February 2020 at 17:10:24 UTC, Jonathan M Davis 
wrote:

On Sunday, February 16, 2020 7:29:11 AM MST uranuz via

This is working fine with disabled postblit...
import std;

struct SS
{
 @disable this(this); // Disabled copy

 bool _empty = false;

 bool empty() @property {
 return _empty;
 }

 void popFront() {
_empty = true;
 }

 int front() @property { return 10; }
}


void main()
{
 foreach( it; SS() ) { writeln(it); }
}

Am I missing something?


That code compiles, because you're passing a temporary to 
foreach. So, the compiler does a move instead of a copy. It's 
the difference between


auto ss = SS();

and

SS ss;
auto ss2 = ss;

If your main were

void main()
{
SS ss;
foreach( it; ss ) { writeln(it); }
}

then it would not compile.


On the other hand, this does work:

void main()
{
SS ss;
foreach( it; move(ss) ) { writeln(it); }
}

So perhaps the correct approach is to use `move` when copying 
input ranges.


Re: AA code 50x slower

2020-02-16 Thread Steven Schveighoffer via Digitalmars-d-learn

On 2/16/20 7:57 AM, AlphaPurned wrote:

template AA(string[] S)
{
 auto _do() { int[string] d; foreach(s; S) d[s] = 0; return d; }
 enum AA = _do;


evilrat is 100% correct. Each time you call that if statement, it 
constructs a NEW AA, checks to see if the t parameter is in there, and 
then leaves it for garbage.


In order to fix it, you have to initialize it in a shared static 
constructor (D doesn't currently allow static initialization of runtime 
AAs).


example:

template AA(string[] S)
{
__gshared const int[string] AA;
enum _do = (){ int[string] d; foreach(s; S) d[s] = 0; return d; }();
shared static this()
{
AA = _do;
}
}

-Steve


Re: Difference between range `save` and copy constructor

2020-02-16 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, February 16, 2020 6:52:17 AM MST uranuz via Digitalmars-d-learn 
wrote:
> It's very bad. Because there seem that when I use range based
> algorithm I need to take two things into account. The first is
> how algrorithm is implemented. If it creates copies of range
> inside or pass it by reference. And the second is how the range
> is implemented if it has value or reference semantics. So every
> time I need to look into implementation and I can't rely on API
> description in most of the cases. In a lot of cases Phobos uses
> value semantics. But there are cases where I want the range
> actually be consumed, but it's not. And the other problemme is
> when algorithm expects range to have value semantics, but it's
> not. So it's a buggy mess that it's hard to think about. In
> trivial cases this is working although. But in more complex cases
> it's simplier to implement some algorithms by own hands so that
> it would work as I expect it myself rather that thinking about
> all these value-ref-range mess. But still can't say that I
> implement it correctly, because range specification actually
> sucks as yo say.
> It's just horrible

The current situation is definitely not ideal, but it can be used quite
consistently. Just follow the rule that once you copy a range, you do not
use that range ever again unless you assign it a new value. So, if you do
something like

auto result = r.find(e);

then you should not be using r again unless you assign it a new value.
e.g.

r = r.find(e);
r.popFront();

auto result = r.find(e);
r = otherRange;
r.popFront();

would be fine, because r was assigned a new value, whereas

auto result = r.find(e);
r.popFront();

should never happen in your code unless you know that typeof(r) is a type
where copying it is equivalent to calling save on it. In generic code, that
means that you should never use a range again after passing it to a function
unless you assign it a new value, or that function accepted the argument by
ref (which almost no range-based functions do).

If you want to be able to use the range again after passing it to a function
without assigning it a new value, then you need to call save so that you
pass an independent copy. e.g.

auto result = r.find.save(e);
r.popFront();

The only copying going on here is with save, so there's no problem, whereas
if r were passed to find directly, the behavior is implementation-dependent
- hence why you should not be using a range after it's been copied (which
includes passing it to a function).

The only time that generic code can reuse a range after passing it to a
function is if that function accepts its argument by ref, which almost no
range-based code does. Far more frequently, it returns the result as a
wrapper range, in which case, you can't use the original range any longer
unless you used save when calling the function or if the code is not generic
and you're coding based on the specific behavior of that particular range
type - which usually isn't something that code should be doing.

By no means do I claim that the status quo here is desirable, but if you
just follow the simple rule that you don't ever use a range once it's been
copied (unless that copy came from save), then you shouldn't run into
problems related to the fact that different ranges have different copying
semantics unless the function that you're calling is buggy.

If you're going to run into a bug along those lines though, it's likely
going to be because a function didn't call save when it was supposed to, and
it was only tested with range types where copying them is equivalent to
save. That's why it's important to test range-based code with both range
types where copying them is equivalent to save and range types which are
full-on reference types (and thus copying just results in another
reference). In general though, any range that is a forward range should have
copying it be equivalent to save, and using reference types for forward
ranges tends to be inefficient and error-prone even if range-based functions
(especially those in Phobos) should be able to handle them correctly.

- Jonathan M Davis





Re: Difference between range `save` and copy constructor

2020-02-16 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, February 16, 2020 7:29:11 AM MST uranuz via Digitalmars-d-learn 
wrote:
> On Sunday, 16 February 2020 at 12:38:51 UTC, Jonathan M Davis
>
> wrote:
> > On Sunday, February 16, 2020 3:41:31 AM MST uranuz via
> >
> > Digitalmars-d-learn wrote:
> >> I have reread presentation:
> >> http://dconf.org/2015/talks/davis.pdf
> >> We declare that `pure` input range cannot be `unpoped` and we
> >> can't return to the previous position of it later at the time.
> >> So
> >> logically there is no sence of copying input range at all. So
> >> every Phobos algorithm that declares that it's is working with
> >> InputRange must be tested for working with range with disabled
> >
> > A range that can't be copied is basically useless. Not only do
> > almost all range-based algorithms take their argumenst by value
> > (and thus copy them), but foreach copies any range that it's
> > given, meaning that if a range isn't copyable, you can't even
> > use it with foreach. And since many range-based algorithms
> > function by wrapping one range with another, the ability to
> > copy ranges is fundamental to most range-based code.
>
> This is working fine with disabled postblit...
> import std;
>
> struct SS
> {
>  @disable this(this); // Disabled copy
>
>  bool _empty = false;
>
>  bool empty() @property {
>  return _empty;
>  }
>
>  void popFront() {
> _empty = true;
>  }
>
>  int front() @property { return 10; }
> }
>
>
> void main()
> {
>  foreach( it; SS() ) { writeln(it); }
> }
>
> Am I missing something?

That code compiles, because you're passing a temporary to foreach. So, the
compiler does a move instead of a copy. It's the difference between

auto ss = SS();

and

SS ss;
auto ss2 = ss;

If your main were

void main()
{
SS ss;
foreach( it; ss ) { writeln(it); }
}

then it would not compile.

foreach(e; range) {...}

basically gets lowered to

for(auto __r = range; !__r.empty; __r.popFront())
{
auto e = __r.front;
...
}

So,

foreach( it; SS() ) { writeln(it); }

would become

for(auto __r = SS(); !__r.empty; __r.popFront())
{
auto it = __r.front;
writeln(it);
}

whereas

SS ss;
foreach( it; ss ) { writeln(it); }

would become

SS ss;
for(auto __r = ss; !__r.empty; __r.popFront())
{
auto it = __r.front;
writeln(it);
}

- Jonathan M Davis





Re: "register int n" alternative

2020-02-16 Thread Stefan Koch via Digitalmars-d-learn

On Sunday, 16 February 2020 at 13:48:43 UTC, Виталий Фадеев wrote:

Possible mark variable for force use register ?

Example C-code:
{
register char *buf;
long   pos;
register int   n;
register int   r;

if (!n)
return 0;
}


How to implement in D ?


Don't you get a warning from your c compiler a C compiler?
The register keyword as been deprecated for ages in C.
Since the compiler cannot actually guarantee that the variable 
will be a register.

As a result D does not have the register keyword.

in D simply allocating a local is enough (and compiling with 
optimization enabled), if there is a register free to put the 
variable in, that's what the optimizer will do.


If you don't want to be at the mercy of the optimizer you can 
always write a block of asm.

Which is what I usually do when I _really_ care.


Re: How to get to body of HTTP 500 error with std.net.curl.get()?

2020-02-16 Thread Anonymouse via Digitalmars-d-learn

On Sunday, 16 February 2020 at 09:13:54 UTC, ikod wrote:

Just a note - this is not a bug, server really send empty body:

< HTTP/1.1 500 Internal Server Error
< cache-control: private
< server: Microsoft-IIS/10.0
< x-aspnetmvc-version: 5.1
< access-control-allow-origin: *
< x-aspnet-version: 4.0.30319
< request-context: 
appId=cid-v1:7585021b-2db7-4da6-abff-2cf23005f0a9

< access-control-expose-headers: Request-Context
< x-powered-by: ASP.NET
< date: Sat, 15 Feb 2020 20:44:03 GMT
< content-length: 0
< 0 bytes of body received


Yes, my bad. I was assuming curl's output was what was sent.


Re: Difference between range `save` and copy constructor

2020-02-16 Thread uranuz via Digitalmars-d-learn
On Sunday, 16 February 2020 at 12:38:51 UTC, Jonathan M Davis 
wrote:
On Sunday, February 16, 2020 3:41:31 AM MST uranuz via 
Digitalmars-d-learn wrote:

I have reread presentation:
http://dconf.org/2015/talks/davis.pdf
We declare that `pure` input range cannot be `unpoped` and we
can't return to the previous position of it later at the time. 
So

logically there is no sence of copying input range at all. So
every Phobos algorithm that declares that it's is working with
InputRange must be tested for working with range with disabled
A range that can't be copied is basically useless. Not only do 
almost all range-based algorithms take their argumenst by value 
(and thus copy them), but foreach copies any range that it's 
given, meaning that if a range isn't copyable, you can't even 
use it with foreach. And since many range-based algorithms 
function by wrapping one range with another, the ability to 
copy ranges is fundamental to most range-based code.

This is working fine with disabled postblit...
import std;

struct SS
{
@disable this(this); // Disabled copy

bool _empty = false;

bool empty() @property {
return _empty;
}

void popFront() {
   _empty = true;
}

int front() @property { return 10; }
}


void main()
{
foreach( it; SS() ) { writeln(it); }
}

Am I missing something?


Re: Difference between range `save` and copy constructor

2020-02-16 Thread uranuz via Digitalmars-d-learn
In general for value-semantics and ref-semantics the different 
code is actually needed. But generic algorithm try to pretend 
that the logic is the same. But it's not true. But in wide subset 
of trivial algorithm it's true. So it's incorrectly interpolated 
that it's true for every case. The very bad thing if range is 
passed by value it still can have value or reference semantic. 
And algorithm cannot say which is it actually. There is not such 
problemme for classes. So as I already said when passing ranges 
by ref in algorithms they behave predictible. And if I want 
algrorithm to operate on copy of algorithm then I can just create 
this copy before passing it to this algorithm. And again 
intention is more clear. But Phobos algorithms don't work like 
that. It's why I can't use them in some cases, because they are 
looking unpredictable for me.


dub / use git branch

2020-02-16 Thread Robert M. Münch via Digitalmars-d-learn
I want to use a specific branch version if a package. I specified the 
branch version in a dub.selections.json file.


But it seems that dub requires a ZIP file that can be downloaded from 
code.dlang.org, which of course fails because the branch is only 
available on github.


Fetching rtree ~fix-#3 (getting selected version)...
Downloading https://code.dlang.org/packages/rtree/~fix-#3.zip failed 
with 404 (Not Found).


How am I supposed to switch to a branch version of a package to try a 
bug-fix version for example?


--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: Difference between range `save` and copy constructor

2020-02-16 Thread uranuz via Digitalmars-d-learn
It's very bad. Because there seem that when I use range based 
algorithm I need to take two things into account. The first is 
how algrorithm is implemented. If it creates copies of range 
inside or pass it by reference. And the second is how the range 
is implemented if it has value or reference semantics. So every 
time I need to look into implementation and I can't rely on API 
description in most of the cases. In a lot of cases Phobos uses 
value semantics. But there are cases where I want the range 
actually be consumed, but it's not. And the other problemme is 
when algorithm expects range to have value semantics, but it's 
not. So it's a buggy mess that it's hard to think about. In 
trivial cases this is working although. But in more complex cases 
it's simplier to implement some algorithms by own hands so that 
it would work as I expect it myself rather that thinking about 
all these value-ref-range mess. But still can't say that I 
implement it correctly, because range specification actually 
sucks as yo say.

It's just horrible


Re: AA code 50x slower

2020-02-16 Thread evilrat via Digitalmars-d-learn

On Sunday, 16 February 2020 at 12:57:43 UTC, AlphaPurned wrote:

template AA(string[] S)
{
auto _do() { int[string] d; foreach(s; S) d[s] = 0; return d; }
enum AA = _do;
}



My best guess is that enum arrays(except strings) and AA's are 
instantiated every time you access them.

This is especially bad with loops.

Probably you want static or module level variable instead.
Module level AA's can't have compile time initializer, however 
you can do initialization with module constructor instead.

https://dlang.org/spec/module.html#staticorder


"register int n" alternative

2020-02-16 Thread Виталий Фадеев via Digitalmars-d-learn

Possible mark variable for force use register ?

Example C-code:
{
register char *buf;
long   pos;
register int   n;
register int   r;

if (!n)
return 0;
}


How to implement in D ?



AA code 50x slower

2020-02-16 Thread AlphaPurned via Digitalmars-d-learn

template AA(string[] S)
{
auto _do() { int[string] d; foreach(s; S) d[s] = 0; return d; }
enum AA = _do;
}


if (t in AA!(["a", "and", "mp4", "mp3", "the", "with", "live", 
"no", "&", "of", "band"])) continue;		



The if statement literally causes a 50x slow down of the code. 
(LDC debug, dmd debug takes about 1000 times longer)




Re: Difference between range `save` and copy constructor

2020-02-16 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, February 16, 2020 3:41:31 AM MST uranuz via Digitalmars-d-learn 
wrote:
> I have reread presentation:
> http://dconf.org/2015/talks/davis.pdf
> We declare that `pure` input range cannot be `unpoped` and we
> can't return to the previous position of it later at the time. So
> logically there is no sence of copying input range at all. So
> every Phobos algorithm that declares that it's is working with
> InputRange must be tested for working with range with disabled
> copy constructor and postblit. And if it is not it means that
> this algroithm actually requires a forward range and there we
> missing `save` calls?
> Because as it was written in this presentation a range copy is
> undefined (without call to save). So it's illegal to create copy
> of range in Phobos algorithms without `save`?
> So we need a test for every algorithm that it is working with
> range with disabled copy constructor and postblit if we declare
> that we only use `save` for range copy?

A range that can't be copied is basically useless. Not only do almost all
range-based algorithms take their argumenst by value (and thus copy them),
but foreach copies any range that it's given, meaning that if a range isn't
copyable, you can't even use it with foreach. And since many range-based
algorithms function by wrapping one range with another, the ability to copy
ranges is fundamental to most range-based code.

That being said, the semantics of copying a range are not actually defined
by the range API. Whether iterating over a copy affects the original depends
on how a range was implemented. e.g. In code such as

void foo(R)(R r)
if(isInputRange!R)
{
r.popFront();
}

foo(range);

whether the range in the original range in the calling code is affected by
the element being popped from the copy inside of foo is implementation
dependent. If it's a class or a struct that's a full-on reference type, then
mutating the copy does affect the original, whereas if copying a range is
equivalent to save, then mutating the copy has no effect on the original.
And with pseudo-reference types, it's even worse, because you could end up
_partially_ mutating the original by mutating the copy, meaning that you can
get some pretty serious bugs if you attempt to use a range after it's been
copied.

This means that in practice, in generic code, you can never use a range once
it's been copied unless you overwrite it with a new value. Passing a range
to a function or using it with foreach basically means that you should not
continue to use that range, and if you want to be able to continue to use
it, you need to call save and pass that copy to the function or foreach
instead of passing the range directly to a function or foreach.

In order to fix it so that you can rely on the semantics of using a range
after it's been copied, we'd have to rework the range API and make it so
that the semantics of copying a range were well-defined, and that gets into
a huge discussion on its own.

As things stand, if you want to test range-based code to ensure that it
works correctly (including calling save correctly), you have to test it with
a variety of different range types, including both ranges where copying is
equivalent to calling save and ranges which are reference types so that
copying them simply results in another reference to the same data such that
iterating one copy iterates all copies.

- Jonathan M Davis





Re: Difference between range `save` and copy constructor

2020-02-16 Thread uranuz via Digitalmars-d-learn

I have reread presentation:
http://dconf.org/2015/talks/davis.pdf
We declare that `pure` input range cannot be `unpoped` and we 
can't return to the previous position of it later at the time. So 
logically there is no sence of copying input range at all. So 
every Phobos algorithm that declares that it's is working with 
InputRange must be tested for working with range with disabled 
copy constructor and postblit. And if it is not it means that 
this algroithm actually requires a forward range and there we 
missing `save` calls?
Because as it was written in this presentation a range copy is 
undefined (without call to save). So it's illegal to create copy 
of range in Phobos algorithms without `save`?
So we need a test for every algorithm that it is working with 
range with disabled copy constructor and postblit if we declare 
that we only use `save` for range copy?


Re: How the hell to split multiple delims?

2020-02-16 Thread evilrat via Digitalmars-d-learn

On Sunday, 16 February 2020 at 09:57:26 UTC, AlphaPurned wrote:


1>Test.d(31): error : template ...
1>Test.d(61): error : template ...
1>Test.d(66): error : cannot implicitly convert expression `l` 
of type `immutable(char)` to `string`

1>Test.d(31): error : template ...
1>Test.d(79): error : template ...



You can clearly see it all starts with 'template' except your 
code. Did you write any templates? No? Well then.


How do you think library writers can point you out to the 
problem? What if you do template with template? BOOM.


Don't get me wrong I'm not protecting the existing order, but.. 
Have you ever thinked about why so much 'junk' for templates? If 
not, here is a little comparison - whenever you use templates 
you've stepping into completely dynamic typing territory. Have 
you ever written any JS or Python code and then tried to make 
sense out of it when refactor? Yep, same shit here. Compiler have 
no idea what nonsense is all this junk, until you use it. And 
this is awesome because in dynamic typing languages you won't 
know it happens until you run it!





This is very annoying. It talks about regex, CTRegexWrapper...

so much BS for such a simple error. To me these error messages 
are counter productive. It's just a wall of crap that I have to 
sift through and analyze and then reason to the bug.




(no offence, you can ignore this)
so ignorant, much attitude, such wow...

You won't believe it but sifting through and analyze is just but 
regular programming stuff.




Re: How the hell to split multiple delims?

2020-02-16 Thread AlphaPurned via Digitalmars-d-learn
On Saturday, 15 February 2020 at 14:35:59 UTC, Steven 
Schveighoffer wrote:

On 2/15/20 6:32 AM, AlphaPurned wrote:
I've tried 10 different ways with split and splitter, I've 
used all the stuff that people have said online but nothing 
works. I always get a template mismatch error.


Why is something so easy to do so hard in D?

auto toks = std.regex.split(l, Regex("s"));
auto toks = std.regex.splitter(l, Regex("s"));
auto toks = std.regex.splitter(l, ctRegex!r"\.");


What type is 'l'?

-Steve


l happened to be a char ;/

I had

auto s = ...;

...

foreach(l; s)

splitter(l,...)

and I was thinking s was an array but it happened to be a string 
so l was char.


The error message made me think(because I was expecting it to 
just work) it was with the regex since I remember some issues 
with regex and I haven't used them in a while so I thought maybe 
I was doing something wrong.


It would be far better if the error message just told me that l 
is the wrong type for splitter rather than printing out template 
constraints and such. When I see a bunch of lines of irrelevant 
error code it just makes me close my eyes.



This was a programming bug on my part but it goes to the root 
that error messages could be better.


Could they not simply print out the id of the variable and the 
type that is wrong rather than making it seem like the template 
is wrong(as if I'm not using it properly) or both.


If it would have said something like "type l is of char while 
splitter expects string" I would have realized the bug 
immediately. I didn't go down that path because I thought l was a 
string.


I was reading a text: readText("file") and for some reason I 
thought it would read it by lines or I was going to split it and 
forgot... so I was getting one large string rather than array of 
strings.


This then cascaded the problem and because of another issue of 
not using D for a while it confounded. The error that D displayed 
was not registering and too much useless info(for the actual 
error).


It would be very nice if D could have more user friendly error 
messages that try to pinpoint the bug rather than just throwing 
out generic information[which may or may not be all that helpful].


D should try to have some heuristic that figures out the actual 
real error and give the relevant info. If it mentioned l or s as 
being of the wrong type(which it could figure out where s comes 
from through l and the foreach) then I think I would have saved 
about 15 minutes and not have written this post.



This is litterally the error(When I change s back to a string)

1>Test.d(31): error : template `std.regex.split` cannot deduce 
function from argument types `!()(immutable(char), 
CTRegexWrapper!char)`, candidates are:

1>C:\Data\ldc2-1.17.0-windows-multilib\bin\..\import\std\regex\package.d(1603):
`std.regex.split(String, RegEx)(String input, RegEx rx) if (isSomeString!String && 
isRegexFor!(RegEx, String))`
1>Test.d(61): error : template instance `Test.main.rate!(d, "")` 
error instantiating
1>Test.d(66): error : cannot implicitly convert expression `l` of 
type `immutable(char)` to `string`
1>Test.d(31): error : template `std.regex.split` cannot deduce 
function from argument types `!()(immutable(char), 
CTRegexWrapper!char)`, candidates are:

1>C:\Data\ldc2-1.17.0-windows-multilib\bin\..\import\std\regex\package.d(1603):
`std.regex.split(String, RegEx)(String input, RegEx rx) if (isSomeString!String && 
isRegexFor!(RegEx, String))`
1>Test.d(79): error : template instance `Test.main.rate!(res, " 
")` error instantiating



This is very annoying. It talks about regex, CTRegexWrapper...

so much BS for such a simple error. To me these error messages 
are counter productive. It's just a wall of crap that I have to 
sift through and analyze and then reason to the bug.


1>Test.d(66): error : cannot implicitly convert expression `l` of 
type `immutable(char)` to `string`


I realize the error is right there but notice how it is buried 
within several lines of BS.


See all the regex references? That is why I thought it was a 
problem with regex and it led me on a wild goose chase. I figured 
that it had to be a regex problem(again, because I was assuming l 
was a string). I realize it was my faulty logic, but it was 
greatly exacerbated by all the junk D prints out thinking it 
helps(maybe it does sometimes but sometimes it doesn't).











Re: Difference between range `save` and copy constructor

2020-02-16 Thread uranuz via Digitalmars-d-learn
Also I see the problemme that someone can think that it creates 
an input range, because he doesn't provide `save` method, but 
actually it creates forward range unexpectedly, because it is 
copyable. And it makes what is actually happening in code more 
difficult. Some algrorithm can take ranges by value, but others 
take them by reference. So result can be completely different. In 
first case range is being consumed, but in another in is not. 
Personally I prefer to take range by reference in all of my 
algrorithms except cases where I is always a class (because it's 
a reference already). But I still don't know what is the right 
way. There are no official guidelines about it. So every time 
it's a problemme. Although it looks like that range is a simple 
concept, but it's actually not.


Re: Difference between range `save` and copy constructor

2020-02-16 Thread uranuz via Digitalmars-d-learn
Actually, as I understand it, the main reason that save was 
introduced was so that classes could be forward ranges


I have use of ranges as a classes in my code that rely on classes 
and polymorthism, but it's usually an InputRange that implements 
Phobos interface:

https://dlang.org/phobos/std_range_interfaces.html#.InputRange

I have virtual opSlice operator that returns InputRange. And 
sometimes implementation of range is very different. So it's 
difficult to write one range as a struct. I have a pattern in my 
code that looks like the following:


interface IContainer
{
   InputRange opSlice();
}

class MyContainer1: IContainer
{
   class Range1: InputRange {
  //... one implementation
   }
   override InputRange opSlice() {
   return new Range1(this);
   }
}

class MyContainer2: IContainer
{
   class Range2: InputRange {
  //... another implementation
   }
   override InputRange opSlice() {
   return new Range2(this);
   }
}

In this example I need a range to be a class, but not a struct.

Another problemme is that `copy contructor` is defined only for 
structs, but not classes. For the class that uses another class 
instance of the `same` type to initialize from it would be a 
regular constructor with parameter.
A copy constructor in struct semantics requires that the source 
would be actually `the same` type. But for classes source could 
be instance of another class that is inherited from current 
class. And we cannot prove statically that it's actually the same 
type.
And also if we talk about range interface constructor cannot be a 
part of it. So we cannot add `copy contructor` (if we would have 
it for class) to interface and check for it's presence in generic 
code. So here we have this workaround with `save` method...
I don't like that primitive concept has two ways to do the same 
thing. And it's unclear what is the primary way of doing this 
(copy constructor or save). It introduce the situation when half 
of the code would require range being copyable, but another part 
would require it to to have a save method. Not the situation is 
that there are a lot of algorothms in Phobos that are not working 
with ranges that have disabled postblit, but have `save` method 
that could be used to make a copy.

Still I want to be able to create ranges as classes...


Re: How to get to body of HTTP 500 error with std.net.curl.get()?

2020-02-16 Thread ikod via Digitalmars-d-learn

On Saturday, 15 February 2020 at 20:38:51 UTC, Anonymouse wrote:

On Saturday, 15 February 2020 at 16:25:42 UTC, Gregor Mückl


When testing to confirm I ran into a bug[2] where the body is 
sometimes empty, but outside of fringe cases it should work.


[1]: https://code.dlang.org/packages/requests
[2]: https://github.com/ikod/dlang-requests/issues/115


Just a note - this is not a bug, server really send empty body:

< HTTP/1.1 500 Internal Server Error
< cache-control: private
< server: Microsoft-IIS/10.0
< x-aspnetmvc-version: 5.1
< access-control-allow-origin: *
< x-aspnet-version: 4.0.30319
< request-context: 
appId=cid-v1:7585021b-2db7-4da6-abff-2cf23005f0a9

< access-control-expose-headers: Request-Context
< x-powered-by: ASP.NET
< date: Sat, 15 Feb 2020 20:44:03 GMT
< content-length: 0
< 0 bytes of body received