Re: Problem with using std.math: abs and std.complex: abs at the same time

2019-09-19 Thread berni via Digitalmars-d-learn
On Thursday, 19 September 2019 at 11:16:12 UTC, Simen Kjærås 
wrote:

Might I ask what specifically you're working on?


Of course. It's about issue 15881 (and 15763), namely approxEqual 
not always doing, what people think it should do. (As a side 
note: I stumbled over this, when I wanted to file a bug report, 
because I thought it's not doing, what it should do. In my case I 
was comparing the distance of geographic items in a town. 
approxEqual decided, that two items which where at opposite ends 
of the town, are at the same place. Seen from a global 
perspective, this might indeed be true, but here it was not, what 
I was looking for.)


Well, some people (including me) think, that approxEqual should 
be a replacement for == for floatingpoint numbers, to accept 
small errors, that inevitantly creep in. But approxEqual accepts 
rather large errors with it's default values. (Probably because 
it's first use was to write some unittests for other functions in 
phobos, where this is sufficent to make the unittests pass, but 
not optimal, as errors might stay undetected). As it's not easy 
to define "small", I searched in the internet, if others have 
investigated on this and came up with [1], which, in my eyes, is 
a very good summary.


Now I'm working on a replacement for approxEqual with the 
constraints given in [1]. My first try (PR #7173) was a little 
bit too fast and would have caused quite some trouble, so I 
closed it and replaced it with two new PRs (#7180 and #7187) as 
suggested by n8sh.


[1] https://www.python.org/dev/peps/pep-0485/


Re: Problem with using std.math: abs and std.complex: abs at the same time

2019-09-19 Thread berni via Digitalmars-d-learn
On Thursday, 19 September 2019 at 07:26:17 UTC, Simen Kjærås 
wrote:
That does indeed fail to compile, and there's no easy way to 
introduce the module-level abs() function to the scope. Again 
though, MergeOverloads to the rescue:


I'm not sure, if MergeOverloads will be accepted into std/math.d. 
Meanwhile I've created a pull request (#7187), that does not 
handle complex numbers although the algorithm would be identical. 
Maybe handling complex numbers in math.d can be added later (or 
maybe it's better to put this in std/complex.d anyway, but then 
code duplication would be necessary).


Re: segmentation fault when running void main() {}

2019-09-18 Thread berni via Digitalmars-d-learn

On Wednesday, 18 September 2019 at 13:57:53 UTC, ag0aep6g wrote:

You're probably hitting this issue:
https://issues.dlang.org/show_bug.cgi?id=19116


Yes, sounds similar. I tried PR 9981, but that didn't work on my 
machine. Similar message, just an other file, that cannot be 
compiled (dmd/backend/optabgen.d if it matters).


The hello-example in issue 19116 didn't work either. Got a lot of

/usr/bin/ld: hello.o/(.eh_frame+0x47): undefined reference to 
´__dmd_peronsality_v0´


and the like.


Re: Problem with using std.math: abs and std.complex: abs at the same time

2019-09-18 Thread berni via Digitalmars-d-learn
On Wednesday, 18 September 2019 at 12:37:28 UTC, Simen Kjærås 
wrote:
How to resolve this, though? The simplest solution is to not 
use selective imports:


import std.math;
import std.complex;

writeln(abs(complex(1.0,1.0)));
writeln(abs(1.0));


That works. But: I'm trying to write some code for math.d and 
when I put this code inside math.d it doesn't work anymore. Also 
removing "import std.math" or moving it after the other import, 
did not help.




Problem with using std.math: abs and std.complex: abs at the same time

2019-09-18 Thread berni via Digitalmars-d-learn

The following code doesn't compile:


import std.stdio;

void main()
{
   import std.complex: abs, complex;
   import std.math: abs;

   auto a = complex(1.0,1.0);
   auto b = 1.0;

   writeln(abs(a));
   writeln(abs(b));
}


The error message depends on the order of the two import 
statements. Seems like the second import is actually ignored.


I hoped for a mechanism similar to overloading, which makes the 
compiler decide, which "abs" to use, depending on the type of the 
operand. Is there a way to do this? (As the code appears inside a 
template, something like std.math.abs() with static import 
doesn't work out well.)


Re: static if (is (T==Complex))

2019-09-18 Thread berni via Digitalmars-d-learn

On Wednesday, 18 September 2019 at 11:25:21 UTC, Norm wrote:

I usually do something like the following:


Ah great. I was looking for "is(T == Complex!R, R)". :-) Thanks!


static if (is (T==Complex))

2019-09-18 Thread berni via Digitalmars-d-learn

Is it possible to simplfy this?

static if (is (T==Complex!double) || is (T==Complex!float) || is 
(T==Complex!real))


Re: segmentation fault when running void main() {}

2019-09-18 Thread berni via Digitalmars-d-learn
On Tuesday, 17 September 2019 at 18:13:06 UTC, Adam D. Ruppe 
wrote:
Did you make sure the old version was totally uninstalled 
before the new version was attempted to be built? This thing 
often happens because of a compiler/runtime version mismatch, 
typically because the old version didn't get fully removed 
first.


Well, there was no old version. It's been the first time I tried 
to install D on than computer. Meanwhile I removed my first 
attempt, using the install script mentioned on the download page. 
And I removed also gdc and ldc (the last one also not working). 
But that didn't help...


segmentation fault when running void main() {}

2019-09-17 Thread berni via Digitalmars-d-learn
I'm not sure, if this is the right place to ask, but I couldn't 
find a better one either.


I'm trying to install D on my old 32-bit machine (debian stable). 
First I tried to install a precompiled version and now I followed 
[1]. In both cases, I always get a segmentation fault when I try 
to run a compiled program.


With make -f posix.mak AUTO_BOOTSTRAP=1 I got:


...
../generated/build 
HOST_DMD="../generated/host_dmd-2.079.1/dmd2/linux/bin32/dmd" 
OS=linux BUILD=release MODEL=32 AUTO_BOOTSTRAP="1" 
--called-from-make ../generated/linux/release/32/lexer.a

Segmentation fault
...


Any ideas, what's missing?

[1] https://wiki.dlang.org/Building_under_Posix


Re: default values depending on type of template variable

2019-09-11 Thread berni via Digitalmars-d-learn
On Wednesday, 11 September 2019 at 09:05:47 UTC, Ali Çehreli 
wrote:

Like this?


Yet an other template! That's great! :-)



default values depending on type of template variable

2019-09-11 Thread berni via Digitalmars-d-learn
I'd like to write a template, that takes a different default 
value depending on the type of a variable. I tried this, but it 
doesn't work:



void main()
{
   double a = 1e-8;
   double b = 1e-10;
   float c = 1e-4;
   float d = 1e-6;

   assert(!test(a));
   assert(test(b));
   assert(!test(c));
   assert(test(d));
}

auto test(T, U)(T value, U limit=1e-9)
{
   return value

Although being called with a double in the first two tests, the 
second overload is always used and therefore the first test 
fails. And without this overload, the last test obviously doesn't 
pass.


Is there a way, to provide default values for template parameters 
depending on the type of an other parameter?


Re: Learning delegates

2019-09-08 Thread berni via Digitalmars-d-learn

On Sunday, 8 September 2019 at 10:04:57 UTC, Joel wrote:
I'm trying to understand delegates. Is there any good ways I 
can get a better understanding of them?


I wrote a foreach loop using opApply. A side effect of that was, 
that after I managed to do this I understood delegates. :-)


Re: getting rid of immutable (or const)

2019-09-06 Thread berni via Digitalmars-d-learn

On Friday, 6 September 2019 at 08:47:07 UTC, Kagamin wrote:
Physical objects work like reference types. A place on 
bookshelf is at one coordinate and a book is at another 
coordinate, you don't copy the book, you fill a place on 
bookshelf with a reference to the book.


So it's more like a piece of paper, where there is place for a 
note. And when assigning, I erase that note (whatever it was) and 
write the new note at that place. Got it! :-)


Re: getting rid of immutable (or const)

2019-09-06 Thread berni via Digitalmars-d-learn

On Thursday, 5 September 2019 at 21:22:12 UTC, Ali Çehreli wrote:
If it makes for the type to have immutable (or const) members, 
then fine; with the understanding that objects of that type 
cannot be assigned or mutated any other way, we can define them 
like that. What I meant is, because we want to use such a type 
in an AA and we don't want the element to change should not 
dictate the type's members. Using in an AA should be yet 
another usage of the type.


Got it. ;-)


> if immutable were that useless, why would it exist
> at all?

immutable is useful: You can have immutable objects, immutable 
AAs (different from what we are discussing here), etc.


So, what I'm just trying all the time is not to have a struct 
with immutable elements but a immutable struct-object with 
mutable elements. I think, that's what I confused all the time.


As a general rule, I never make members const or immutable; 
this is a guideline that I carried over from C++.


I have almost no experience with C++, but I just accept that as a 
good advise. After all that discussion here, it seems to be sound.


Thank you very much too! I think I made a big jump forward in 
understanding the concept of immutability in the last 24 hours. 
:-)


Re: getting rid of immutable (or const)

2019-09-06 Thread berni via Digitalmars-d-learn

On Thursday, 5 September 2019 at 20:10:03 UTC, ag0aep6g wrote:
You're not putting an immutable int into an AA. You're copying 
the value of an immutable int to a mutable one.


but I can't do that with a struct, having an immutable member. 
When I remove that immutable inside of the struct it works. ?!?


`Point` is effectively the same as `immutable long`. A better 
simile would be this: `immutable(int)[int] a; a[1] = 17;`. And 
now you get the same error. You can't overwrite the element, 
because its immutable.


Ah, the point is not, that my object contains an immutable 
element, but that the base type of the AA is a type with an 
immutable element! I understand now. Thanks a lot!


Re: getting rid of immutable (or const)

2019-09-05 Thread berni via Digitalmars-d-learn

On Thursday, 5 September 2019 at 15:48:40 UTC, Ali Çehreli wrote:
That's the misunderstanding: The existing object is assigned 
over. The address is the same:


void main() {
  int[int] aa;
  aa[1] = 1;
  const oldPointer = (1 in aa);
  aa[1] = 11;
  assert(oldPointer is (1 in aa));  // Passes
}


First, I thought, I've got understood it now, but then I wrote 
this little program and the result was not, what I thought it 
would be:



void main()
{
int[int] a;

immutable int b = 17;
a[1] = b;  // <-- expecting error 
here

const oldPointer = (1 in a);
immutable int c = 10;
a[1] = c;
assert(oldPointer is (1 in a));

Point[int] d;

immutable Point e = Point(17);
d[1] = e;   // <-- but error is here
}

struct Point
{
immutable int x;
}


What's the difference? I can put an immutable int in an AA and I 
can overwrite it (pointer is still the same), but I can't do that 
with a struct, having an immutable member. When I remove that 
immutable inside of the struct it works. ?!?


While writing this, I had an other idea, namely, that changing 
d[1] would make e to be something different (x inside Point is 
mutable this time):



Point e = Point(17);
d[1] = e;
d[1] = Point(19);
writeln(e);


But it's still 17.



const or immutable members make structs unassignable.


But why? Here:


Point[3] f;
f[0] = Point(3);


I understand, that I cannot change f[0], because it's allready 
got a default value and that value would be overwritten. But in 
an aa, that member does not exist before putting the Point in 
there, hence there is nothing, that could be overwritten...


Whether the members of a type are const or immutable should not 
be dictated by where the objects of that type will be used. If 
it makes sense otherwise, sure...


I'm not sure if I understand that right. It's sort of an advice 
on how to decide if one want's to make a member immutable or not, 
is it?


If you are worried about existing elements being modified, you 
can provide a different container that wraps an AA, but 
provides an opIndex that returns 'ref const(T)'. That would 
solve the immutability of the elements in the container.


No, I don't worry about such things. My program runs smoothly 
when I don't make that members immutable. And I could perfectly 
live with that But that's the maxim I used the last three years: 
"If avoidable, don't use 'immutable' at all, it only causes 
problems." But that is not satisfiable. Because if immutable were 
that useless, why would it exist at all? So I would like to 
understand, what's happening; being able to predict, what works 
and what not. At the moment it's almost always the opposite of 
what I think it should be...




Re: getting rid of immutable (or const)

2019-09-05 Thread berni via Digitalmars-d-learn

On Thursday, 5 September 2019 at 13:27:55 UTC, drug wrote:

[...]when you put it into an AA you modify old value


Why?!? :-o When putting it into an AA it will be copied to a 
different place in memory, but the value is still the same, it's 
not modified. Sorry, but I still think, there is something 
fundamentally wrong about how I think about immutability.


But if you just want to initialize an AA by immutable members 
then this can be usefull to read 
https://dlang.org/spec/hash-map.html#runtime_initialization


Well, yes and no. I want to initialize an AA with structs that 
contain immutable members. And that AA resides at runtime inside 
of a function body. I don't see, how this can be done with he 
approach given by the link. :-(


Re: getting rid of immutable (or const)

2019-09-05 Thread berni via Digitalmars-d-learn

On Thursday, 5 September 2019 at 12:15:51 UTC, drug wrote:
One solution could be using either pointer to `const(Point)` or 
class here (to avoid pointer using) 
https://run.dlang.io/is/rfKKAJ


OK. This are two solutions and although I'll probably not going 
to use any of those (due to other reasons), I still don't 
understand, why the original approach does not work. If I've got 
a book an put it in a box and later I'll get it out again, it's 
still the same book. So why has a struct changed when I put it 
into an AA and get it out again? It's not supposed to change...


Re: getting rid of immutable (or const)

2019-09-05 Thread berni via Digitalmars-d-learn

On Thursday, 5 September 2019 at 11:22:15 UTC, drug wrote:

05.09.2019 14:17, berni пишет:

Point[long] q;

q[1] = Point(3);


Leads to:

test.d(7): Error: cannot modify struct q[1L] Point with 
immutable members



But why do you try to modify immutable data? What is your 
point? Could you describe you use case?


That's probably, what I don't understand. I've got a Point, which 
should not be modified. I put it in a container (q) and later I 
get it out there again. It should still be the same Point as 
before. I modify the container, not the Point, don't I?


Re: getting rid of immutable (or const)

2019-09-05 Thread berni via Digitalmars-d-learn

On Thursday, 5 September 2019 at 10:47:56 UTC, Simen Kjærås wrote:

https://dlang.org/library/std/range/retro.html


Yeah, that worked. Thanks. :-)


Don't worry about asking questions


OK. Then here's the next one:


Point[long] q;

q[1] = Point(3);


Leads to:

test.d(7): Error: cannot modify struct q[1L] Point with 
immutable members





Re: getting rid of immutable (or const)

2019-09-05 Thread berni via Digitalmars-d-learn

On Thursday, 5 September 2019 at 08:56:42 UTC, berni wrote:

[..]


And one more question:


import std.algorithm: reverse;
writeln(q.reverse);


Here the compiler complains with:

test.d(8): Error: template std.algorithm.mutation.reverse 
cannot deduce function from argument types !()(Point[]), 
candidates are:
/usr/include/dmd/phobos/std/algorithm/mutation.d(2483):
std.algorithm.mutation.reverse(Range)(Range r) if 
(isBidirectionalRange!Range && (hasSwappableElements!Range || 
hasAssignableElements!Range && hasLength!Range && 
isRandomAccessRange!Range || isNarrowString!Range && 
isAssignable!(ElementType!Range)))


I allready tried to use q.dup.reverse but that didn't work either.

How to get this working? (I hope I don't annoy you by asking that 
much questions, but I've got the feeling, that I've got only two 
choices: To shy away from using immutable (like I did in the last 
three years) or ask a lot of questions in the hope of 
understanding what's going on...


Re: getting rid of immutable (or const)

2019-09-05 Thread berni via Digitalmars-d-learn

On Thursday, 5 September 2019 at 08:44:35 UTC, berni wrote:

This doesn't compile:

[...]

Any idea, how to get around this?


Found the answer myself: q.map!(a=>a.x).minElement; :-)




Re: getting rid of immutable (or const)

2019-09-05 Thread berni via Digitalmars-d-learn

On Thursday, 5 September 2019 at 08:16:08 UTC, Daniel Kozak wrote:

in this case you can just use:

auto q = cast()p.x;


Ahh, great! :-)

But that directly gets me to the next question:


import std.stdio;

void main()
{
Point[] q = [Point(1),Point(3),Point(2)];

import std.algorithm.searching: minElement;
writeln(q.minElement!(a=>a.x).x);
}

struct Point
{
   @property immutable long x;
}


This doesn't compile:

/usr/include/dmd/phobos/std/algorithm/searching.d(1365): Error: 
cannot modify struct extremeElement Point with immutable members
/usr/include/dmd/phobos/std/algorithm/searching.d(1307): Error: 
template instance `test.main.extremum!(__lambda1, "a < b", 
Point[], Point)` error instantiating
/usr/include/dmd/phobos/std/algorithm/searching.d(3445):
instantiated from here: extremum!(__lambda1, "a < b", Point[])
test.d(8):instantiated from here: minElement!((a) => 
a.x, Point[])


Any idea, how to get around this?


getting rid of immutable (or const)

2019-09-05 Thread berni via Digitalmars-d-learn

I still struggle with the concept of immutable and const:


import std.stdio;

void main()
{
auto p = Point(3);
auto q = p.x;
writeln(typeof(q).stringof);
}

struct Point
{
@property immutable long x;
}


The type of q is immutable(long). But I need a mutable q. I found 
two ways:


a) long q = p.x;
b) auto q = cast(long)p.x;

Either way I've to specify the type "long" which I dislike (here 
it's not a real burdon, but with more complicated types it might 
be). Is there a way, to make q mutable without having to write 
the type explicitly?


Re: Is removing elements of AA in foreach loop safe?

2019-09-04 Thread berni via Digitalmars-d-learn
On Tuesday, 3 September 2019 at 20:06:27 UTC, Ferhat Kurtulmuş 
wrote:
I know, it is foreach loop in question. How about using a 
reverse for loop like:


for (size_t i = arr.length ; i-- > 0 ; ){
arr.remove(i);
}


This would be good, if it where for slices. But with associative 
arrays, this doesn't work. :-(


Re: adding delegate to opApply

2019-09-03 Thread berni via Digitalmars-d-learn

On Monday, 2 September 2019 at 14:20:11 UTC, Paul Backus wrote:

If you have an existing delegate that you want to use with 
opApply, the easiest way is like this:


void delegate(Thing) myDelegate = ...;

foreach(thing; things) {
myDelegate(thing);
}
// Equivalent to: things.opApply((Thing t) => myDelegate(t))


Thanks for your answer. It's not exactly, what I was looking for, 
but meanwhile I think, the whole idea was not reasonable. I 
meanwhile returned to using a normal function call instead of 
opApply, which makes it easy to pass a delegate as one of the 
parameters.


adding delegate to opApply

2019-09-02 Thread berni via Digitalmars-d-learn
I've tried to make a small example, but it's not easy to get this 
reduced further. At least I didn't manage. The following program 
can also be found at https://run.dlang.io/is/p6l7xN


void main()
{
auto foo = Ways([Way([8,2,3,0]),Way([4,6,2]),Way([4,7,2,6])]);

foo.remove_odds();

assert(foo==Ways([Way([8, 2]), Way([4, 6, 2]), Way([4]), 
Way([0]), Way([2, 6])]));

}

struct Ways
{
Way[] ways;

void remove_odds()
{
Way[] new_ways;

foreach (ref way;ways)
foreach (point, void delegate(void delegate(Way way)) 
remove;way)

if (point%2==1)
remove(delegate(Way way) {new_ways ~= way;});

ways ~= new_ways;
}
}

struct Way
{
int[] points;

auto opApply(int delegate(int, void delegate(void 
delegate(Way way))) work)

{
size_t[] remove;
void delegate(Way) add_new_way;

foreach (index,point;points)
if (auto result=work(point,(void delegate(Way) 
anw){remove~=index; add_new_way=anw;}))

return result;

import std.algorithm.sorting: sort;
foreach (index;remove.sort!("a>b"))
{
add_new_way(Way(points[index+1..$]));
points = points[0..index];
}

return 0;
}
}

I need to pass the delegate add_new_way somehow to opApply. Here 
I managed this, by adding this delegate to the remove-delegate 
and safe it away for further use. This works, because if remove 
is never called, add_new_way is not used either. But it's a 
little bit awkward. Is there a better way, to achieve this? (Note 
1: In the real world, point%2==1 is a more complex function call. 
Note 2: The order of elements in Way[] way doesn't matter, if 
that makes things easier.)


Maybe it's possible to work with something like 
std.algorithm.iteration.splitter instead of those loops and 
opApply. But splitter takes an element or a range, not a 
predicate.


Re: Is removing elements of AA in foreach loop safe?

2019-08-30 Thread berni via Digitalmars-d-learn

On Friday, 30 August 2019 at 15:00:59 UTC, Paul Backus wrote:
Whether you actually get an error at runtime depends on the 
load factor of the AA. If it drops below a certain threshold, 
the AA will be resized [1], and its original memory will be 
freed [2].


It could still work, depending on how the foreach loop is 
implemented. If the keys were stored away before starting the 
loop it would work. But for one thing, it isn't implemented that 
way and for the other, one shouldn't rely on it, because the 
implementation could change. What I hoped for, was, that the 
specs enforce somewhere, that this is to be implemented in a safe 
manner.


I'll replace this loops by something better, e.g. the mentioned 
filter. But I've never worked with AAs and filters yet. Will see, 
if I manage to do that. Else I'll probably just copy the keys and 
use them for an independent loop.




Is removing elements of AA in foreach loop safe?

2019-08-29 Thread berni via Digitalmars-d-learn
Iterating of some structure and removing elements thereby is 
always errorprone and should be avoided. But: In case of AA, I've 
got the feeling, that it might be safe:



foreach (k,v;ways)
if (v.empty)
ways.remove(k);


Do you agree? Or is there a better way to achieve this?


Re: Sort Associative Array by Key

2019-08-28 Thread berni via Digitalmars-d-learn

On Tuesday, 27 August 2019 at 16:25:00 UTC, Samir wrote:
As I've mentioned on the list before, I really struggle to 
understand how some of the std.algorithm functions such as 
`map` work when combined with things like `array`, `sort` and 
especially `zip` but really appreciate the support I find here 
on the forum.


A few months ago I stuggled with that too. Meanwhile I think I 
got it.


Let's examine just the first step in this sequence:


writeln(foo.byPair);


This leads to

[Tuple!(string, "key", int, "value")("BZP", 5), Tuple!(string, 
"key", int, "value")("VXE", 8), Tuple!(string, "key", int, 
"value")("JLC", 2)]


Well, this look like an array of tuples, each tuple containing a 
key and a value. I assume, that you understand tuples, I think, 
they are not the problem here. The problem arises, because the 
result of "foo.byPair" isn't an array. Actually writeln converts 
the result to an array, before printing it (or at least it 
pretends to do so). You can see this with:



writeln(typeof(foo.byPair).stringof);


Which is:


MapResult!(__lambda2, Result)


Ooops, what's that? Having a look at the documentation isn't very 
instructive (at least at beginners level):



auto byPair(AA)(AA aa)
if (isAssociativeArray!AA);


That's almost all you get. Almost, because the description 
mentions, that the return value is a forward range. Ah, it's a 
range. I'm not sure, how much you know about ranges. If you want 
to understand that stuff, you should study them. E.g. try to 
write some ranges of your own.


When thinking of a range, I imagine it as sort of a voucher for 
something like an array. You can use that voucher to get elements 
from that array. In case of an forward range, you are restricted 
to get the elements ony by one from the beginning. You get them 
by using the function front(), which all ranges provide. Let's 
try it:



auto something = foo.byPair;
writeln(something.front);


And we get:


Tuple!(string, "key", int, "value")("BZP", 5)


That's indeed the first of our elements. We don't know yet, what 
this range is doing behind the sceens. But I can tell you: When 
calling byPair it hasn't done much: It just signed that voucher 
and handed it out to you (that's called lazy evaluation, contrary 
to eager evaluation). Maybe you never use that voucher. In that 
case it would be wasted time to calculate all the elements, that 
are never used.


The moment you call front, that range starts to do some of the 
work. It assembles the first item of the range and hand's this 
out to you. Then it stops again - the other items are not yet 
calculated. That's done, when you call front again (but before 
you need to call popFront, to remove the first item, else you 
would get the item, you allready have, once again). And so on.


Now we know, how to use this range and that's what "array" does: 
It calls front and popFront as long as there are more elements 
(this can be checked by calling empty on the range), and puts 
them into an array. But what we don't understand yet is that 
strange type of the range: MapResult!(__lambda2, Result).


For that, we should have a look at the implementation (I'm using 
http://dpldocs.info/experimental-docs/std.array.byPair.html for 
that, because it has a link to the documentation at the bottom), 
we find out, that byPair is implemented using byKeyValue and map:



return aa.byKeyValue
   .map!(pair => tuple!("key", "value")(pair.key, 
pair.value));


byKeyValue is defined in object, which has no source code - I 
guess it's implemented directly in the compiler somehow. By using 
typeof, we find out that the type is "Result" and by using 
writeln we find out, that the result of byKeyValue looks like an 
array of Pairs of pointers. Again it's a range, that we can use 
like above.


This range (think again of a voucher) is now send to map. Map 
needs, beside this range, a function. You could write that 
function like:



auto make_tuple(Pair pair)
{
return tuple!("key", "value")(pair.key, pair.value);
}


Than the above could be written as


return aa.byKeyValue.map!(make_tuple);


Beside the fact, that I cannot find the definition of Pair (and 
therefore would need to make a template instead of the function), 
it's not necessary to write that function explicitly. There is a 
way, to write functions more compressed, namely by using =>, like 
it's done above. Those functions are called lambda-functions 
(because at some places a greek lambda symbol was used for the 
function parameter).


Now, map is lazy too. It just remembers that function, the 
"voucher" it got and hand's you an other voucher. That's all. 
This new voucher is called "MapResult", which is actually a 
struct with functions "front", "popFront" and "empty" (and some 
more, but we don't care). And this struct has two 
template-parameters, namely a function and a range. We know that 
range already, it's Result from byKeyValue. And that function, 
which has no name, got the name "__lambda2" from 

Re: += on associative arrays leads to surprising result

2019-08-27 Thread berni via Digitalmars-d-learn

On Tuesday, 27 August 2019 at 16:45:53 UTC, Samir wrote:
I never understood why the intial value of floats, doubles and 
reals was NaN.


That's for detecting uninitialised variables. If the result of a 
calculation is NaN, it's likely, that you forgot to initialise 
the variable.


+= on associative arrays leads to surprising result

2019-08-27 Thread berni via Digitalmars-d-learn

import std.stdio;

void main()
{
real[int] a;
a[0] += 100;
writeln(a);
}


results (independed of the used compiler) in


[0:100]


I was a little bit surprised, because a[0] += 100 should be the 
same as a[0] = a[0]+100, which leads to a range violation error. 
Furthermore, as we work with real, I'd expected the result to be 
NaN...


Is this a bug? I ask, because it would be quite convenient to use 
it the way it works now.


An alternative I found, would be to use object.update. But there 
I've to declare the 100 twice which results in code duplication:



a.update(0,()=>100.0L,(ref real v)=>v+100.0L);


Hence, my best solution needs two lines:


if (0 !in a) a[0] = 0;
a[0] += 100;


What's your oppinion on this?


Re: .fflush() in stdio.d

2019-08-26 Thread berni via Digitalmars-d-learn

On Monday, 26 August 2019 at 09:14:23 UTC, Jonathan M Davis wrote:
The dot makes it so that it's specifically referencing a 
module-level symbol (be it in that module or an imported 
module) instead of a local or member symbol.


Ah, thanks. Now it makes sense! :)


.fflush() in stdio.d

2019-08-26 Thread berni via Digitalmars-d-learn
Out of curiosity: Browsing the source of stdio.d I found that 
flush() is implemented by calling fflush from some C++ library. 
What I don't understand: Why is the call to fflush preceded by a 
dot?


Re: Merging two associative arrays

2019-08-24 Thread berni via Digitalmars-d-learn

On Saturday, 24 August 2019 at 19:55:48 UTC, a11e99z wrote:

auto ab = a.byPair.chain( b.byPair).assocArray ?


Not sure, if it is simpler, but a least without tmp. :) Thanks.


Merging two associative arrays

2019-08-24 Thread berni via Digitalmars-d-learn
I've got two associative arrays and want to get a new one, which 
is created out of both of them:


This works:

string[int] a = [1:"one", 7:"seven"];
string[int] b = [5:"five", 9:"nine"];

string[int] tmp = a.dup;
foreach (k,v;b) tmp[k] = v;

assert(tmp==[1:"one", 7:"seven", 5:"five", 9:"nine"]);

But is there something easier, especially without making that 
"tmp" explicit. I hoped for a~b, but that didn't work. (I 
allready know, that there aren't duplicated keys, if that 
matters.)


string to ubyte[]

2019-08-14 Thread berni via Digitalmars-d-learn
I've got a function which takes two strings and should return 
them as a ubyte[] with additional zero bytes in between and 
around. This works:



   ubyte[] convert_string_pair(string first, string second)
   {
   auto b = new ubyte[](0);
   b ~= 0x00 ~ first ~ 0x00 ~ second ~ 0x00;
   return b;
   }


But I think it would be more elegant to do it in a single return 
statement, but unfortunately this does not work:



   ubyte[] convert_string_pair(string first, string second)
   {
   return 0x00 ~ first ~ 0x00 ~ second ~ 0x00;
   }


The reason is, that this expression creates a string and not a 
ubyte[]...


Re: Help me decide D or C

2019-08-02 Thread berni via Digitalmars-d-learn

On Friday, 2 August 2019 at 14:05:20 UTC, SashaGreat wrote:

On Friday, 2 August 2019 at 12:28:45 UTC, berni wrote:

On Wednesday, 31 July 2019 at 18:38:02 UTC, Alexandre wrote:
Should I go for C and then when I become a better programmer 
change to D?

Should I start with D right now?


In my oppinion C should have been deprecated about 50 years 
ago ...


I stopped there. How could you have deprecated a language 50 
years ago since was first released in '72 (47 years ago).


Yes, that was intentional. What I wanted to say is, that I think, 
that it would have been better, if C was never invented at all... 
In that case, there would have been space for an other language 
for writing operating systems, without that much bugs in its 
design. (But one never knows afterwards...)




Re: Why does choose not work here

2019-08-02 Thread berni via Digitalmars-d-learn

On Thursday, 1 August 2019 at 21:26:10 UTC, Matt wrote:

Anyone have any other thoughts?


I tried to simplify your example a little bit:

import std.stdio;
import std.range;
import std.algorithm;

auto myFilter(R1, R2)(R1 a, R2 b)
{
return a.filter!(c => c==b.front);
}

struct A
{
int[] starts;

auto intervalRange() @property
{
return starts;
}
}

auto uniqIntervalsA(A primary, A* previous) @property
{
return choose(previous is null,
  primary.intervalRange,
  primary.intervalRange.filter!(a => 
a==previous.intervalRange.front));

}

auto uniqIntervalsB(A primary, A* previous) @property
{
return choose(previous is null,
  primary.intervalRange,
  
primary.intervalRange.myFilter(previous.intervalRange));

}

unittest
{
auto a1 = A([1]);

writeln(uniqIntervalsA(a1,));
writeln(uniqIntervalsA(a1,null));
writeln(uniqIntervalsB(a1,));
writeln(uniqIntervalsB(a1,null));
}

The strange thing is, that even if you replace "return 
a.filter!(c => c==b.front);" by "return a.filter!(c => true);" 
the problem remains (but now you can use lazy). As I'm not an 
expert myself, I'm not sure how to analyze this. But I think, 
both parameters to "choose" are evaluated (that is they are not 
lazy), but "myFilter" uses it's parameter immediately to give "b" 
a value, while "filter" just hands in an anonymous function 
without using it ever.


Hope, this helps to get further down the way to a solution...


Re: Help me decide D or C

2019-08-02 Thread berni via Digitalmars-d-learn

On Wednesday, 31 July 2019 at 18:38:02 UTC, Alexandre wrote:
Should I go for C and then when I become a better programmer 
change to D?

Should I start with D right now?


In my oppinion C should have been deprecated about 50 years ago 
and it's not worth while to learn it if you are not interested in 
the history of programming or you have to learn it, because you 
need to maintain software which is allready written in C. But 
that's my oppinion; others may have a different sight.


I would recommend to start immediately with D (using the book of 
Ali, which has allready been mentioned). When you've got mastered 
D you will not have any problems switching to an other language. 
And you don't need to know everything about D to write programs. 
For example you do not need to use templates in the beginning. 
You might find out a strange looking syntax for type conversion 
"to!string(17)" with this exclamation mark in between, which you 
can just accept and us as is, without having to understand what 
it's good for.


I would even go further and state, that learning C first will 
become a burden instead of a help.






Re: Help me decide D or C

2019-08-02 Thread berni via Digitalmars-d-learn

On Wednesday, 31 July 2019 at 18:38:02 UTC, Alexandre wrote:
Should I go for C and then when I become a better programmer 
change to D?

Should I start with D right now?


In my oppinion C should have been deprecated about 50 years ago 
and it's not worth while to learn it if you are not interested in 
the history of programming or you have to learn it, because you 
need to maintain software which is allready written in C. But 
that's my oppinion; others may have a different sight.


I would recommend to start immediately with D (using the book of 
Ali, which has allready been mentioned). When you've got mastered 
D you will not have any problems switching to an other language. 
And you don't need to know everything about D to write programs. 
For example you do not need to use templates in the beginning. 
You might find out a strange looking syntax for type conversion 
"to!string(17)" with this exclamation mark in between, which you 
can just accept and us as is, without having to understand what 
it's good for.


I would even go further and state, that learning C first will 
become a burden instead of a help.






Re: Is there something like a consuming take?

2019-07-09 Thread berni via Digitalmars-d-learn

Hurray, it works! :-)

https://run.dlang.io/is/2GMq34

I have to use classes to avoid copying when arguments are passed 
to a function. (And yes, there should of course be much more 
checks, especially when there are to few elements in the original 
range. And it could be speed improved and so on... I wanted to 
keep it simple.)





Re: Is there something like a consuming take?

2019-07-09 Thread berni via Digitalmars-d-learn

On Sunday, 7 July 2019 at 21:55:17 UTC, Jonathan M Davis wrote:
Having one range know about the other isn't enough. That just 
means that the take range would tell the other range that it 
had popped an element off, and then the other would know that 
it had to pop an element off. That still involves popping the 
same element on different ranges twice.


Sounds like you didn't understand what I meant. So I tried to 
implement what I had in mind and I have to confess, that there is 
something about ranges that I do not understand yet:



import std.stdio;
import std.array;

void main()
{
   auto a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];

   call(a,5);
}

void call(T)(ref T range, int c)
{
   struct Take
   {
   T* take_range;
   int count;

   @property bool empty=false;
   @property auto front() { return (*take_range).front; }
   void popFront()
   {
   (*take_range).popFront();
   if (--count<=0) empty=true;
   }

   T* get_range()
   {
   assert(count==0);
   while (!empty) popFront();
   return take_range;
   }
   }

   auto take = Take(,c);

//writeln(take);
   while (!take.empty) { write(take.front); take.popFront(); }

   auto original_range = take.get_range();

   writeln(*original_range);
}


Running this program leads to

12345[6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

as expected.

But when I replace that loop at the bottom by writeln(take) the 
assertion in get_range fails (count==5). As all the functions are 
called in the same order by both the loop and writeln, I confess, 
that writeln somehow manages to use a copy of "take" although 
this isn't a ForwardRange and copying should therefore not be 
possible.


You can try mucking around with your own implemention of take 
if you want, but I'd suggest that you're just better off taking 
the approach that it's expected that if you use take,


I't not about improving or doing things different. It's just 
about me understanding, what happens.






Re: Is there something like a consuming take?

2019-07-07 Thread berni via Digitalmars-d-learn

On Sunday, 7 July 2019 at 09:01:53 UTC, Jonathan M Davis wrote:
Without slicing, that's impossible without iterating over the 
elements multiple times.


That's what I thought too, but meanwhile I think it is possible. 
To get it working, the second range needs to know about the first 
one and when the second one is queried the first time it has to 
notify the first one, that it has to remove all remaining items 
from the underlying range (and in case it still needs them, save 
them) and never use it again.


The advantage of this setup over copying the items immediately is 
some sort of laziness. It might happen, that the second one will 
never query or it might happen, that the first one finished 
allready when the second one queries. In this cases no additional 
memory is needed.
Even if the second one is queried before the first one finished, 
the needed buffer might be much smaller.


Re: Is there something like a consuming take?

2019-07-06 Thread berni via Digitalmars-d-learn
I start to understand: A (lazy) range is something like a 
voucher: byChunk() does not provide the data immediately, but 
only a voucher to hand you a chunk (an array of 2 bytes in my 
example above) a time. This voucher is passed to joiner(), which 
keeps that voucher and hands me out a new voucher for a byte a 
time (called "a" in my example above). This voucher is now passed 
to take(), whick again keeps that voucher and hands me out yet an 
other voucher for a byte a time, but limits itself to 5 items.


Up to now nothing has happend, but the exchange of that vouchers. 
Now when writeln() is called, it shows take() that voucher and 
says: "Give me the first of your numbers". take() uses his 
voucher to do the same with joiner(), which uses its voucher to 
get the first chunk of byChunk(), takes the first byte of that 
chunk and hands it to take() and take() hands it to writeln().


Now writeln() uses it's voucher once again, to get the next byte. 
take() asks joiner() again, but this time joiner() does not ask 
byChunk(), because it still has one number left in the chunk it 
got when asking the last time. Now joiner() uses this second byte 
to hand it back. And so on.


After writeln() finished I'm doing something evil: I use a 
private copy of that voucher, that I allready handed to take() to 
use it myself. That's sort of stealing back. And hence the 
results are more or less unpredictable. Especially, when I use 
this copy, before take() finished it's job, as Jonathan M Davis 
points out.


My misthinking was to assume, that my copy of the voucher is 
still the same as the voucher, that take() owns after having 
handed out the 5 items, so I can use it to get the other items. 
If it where possible to ask take() to hand me back it's voucher, 
I could do it with this voucher, but I don't see a possibility to 
get that voucher back.


What I actually want to do, when using take(), is not to get a 
new voucher, but I want to keep my voucher and just use this 
voucher to get the first 5 items - take() doesn't do that, so 
I've got to write my own function which cannot be lazy.


Or better: I'd like to hand in my voucher and get back two 
vouchers, one for the first 5 bytes and one for the rest. That's 
actually, what I thought, take() is doing...


Re: Is there something like a consuming take?

2019-07-06 Thread berni via Digitalmars-d-learn

On Saturday, 6 July 2019 at 14:48:04 UTC, Adam D. Ruppe wrote:

[...]
So this is a case of input range behavior - always consuming 
the underlying file - combined with buffering of two elements 
at once, leaving 5,6 behind, and the reuse of the buffer 
meaning you see that 5,6 again on the next call.


Thanks for clearifing what happens. In my oppinion the behaviour 
of take() should be better defined. It's clear, that take() 
returns a range with the first n elements of the underlaying 
range (and that is done lazily). But it's not specified what 
happens with the underlaying range. As the behaviour is 
unpredictable (or at least hard to predict), one should assume, 
that the underlaying range is completely destroyed by take(). 
This makes take() much less usefull, than it could be, in my 
eyes. :-(





Re: Is there something like a consuming take?

2019-07-06 Thread berni via Digitalmars-d-learn

A small example showing this strange behaviour:


import std.stdio;
import std.algorithm.iteration;
import std.range;

enum BUFFER_SIZE = 1024;

void main(string[] args)
{
   auto a = (new File(args[1]))
   .byChunk(BUFFER_SIZE)
   .joiner;

   writeln(a.take(5));
   writeln(a);
}


Using a file, containing the bytes 1 to 10 I get:


[ 1, 2, 3, 4, 5 ]
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]


take does not consume.

When I now change BUFFER_SIZE to 2 I get:


[ 1, 2, 3, 4, 5 ]
[ 5, 6, 7, 8, 9, 10 ]


Now the first two buffers have been consumend and the third ([5, 
6]) not.


Feels like a bug in Phobos. But maybe I do not understand, what's 
happening and this is correct behaviour. Can anyone explain or 
confirm, that this is a bug?


Re: Is there something like a consuming take?

2019-07-06 Thread berni via Digitalmars-d-learn
Now it's getting weird. Meanwhile I encountered, that take() 
sometimes consumes and sometimes not. Where can I learn, what is 
the reason behind this behavior? And how can I handle this?


Re: struct inside struct: Is there a way to call a function of the outside struct from the inner struct?

2019-07-06 Thread berni via Digitalmars-d-learn
Now I found this: 
https://forum.dlang.org/thread/eobdqkkczquxoepst...@forum.dlang.org


Seems to be intentional, that this doesn't work. In my case I'm 
able to move d() into the outer struct...


Re: Is there something like a consuming take?

2019-07-06 Thread berni via Digitalmars-d-learn

On Saturday, 6 July 2019 at 11:48:51 UTC, a11e99z wrote:

sure
auto take_consuming( R )( ref R r, int cnt ) {
auto tmp = r.take( cnt ).array;
r = r.drop( cnt );
return tmp;
}
don't thank


Doesn't look like what I'm looking for, as it is exactly the same 
I allready found.


Maybe I need to explain, what I dislike with this approach: 
take() calls popFront n times and drop() calls popFront another n 
times giving a total of 2n times (depending on the underlying 
range, this might cause lot's of calulcations be done twice. The 
first version with the foreach loop calls popFront only n times.





Re: For loop with separator

2019-07-06 Thread berni via Digitalmars-d-learn

On Thursday, 4 July 2019 at 17:00:33 UTC, Q. Schroll wrote:
The prime example is printing the comma when printing a list: 
There is one between any two elements, but neither is one at 
front or behind the last one.


If it is just for printing commas in between, you can use 
range.join(", ")


https://dlang.org/phobos/std_array.html#.join




struct inside struct: Is there a way to call a function of the outside struct from the inner struct?

2019-07-06 Thread berni via Digitalmars-d-learn

struct A
{
void c() {}

struct B
{
void d()
{
c();
}
}
}


When compiling this with rdmd I get the message: "Error: this for 
c needs to be type A not type B". Is there a way to call c from d?


Is there something like a consuming take?

2019-07-06 Thread berni via Digitalmars-d-learn
I want to copy the first n items of a range to an array, removing 
these items from the range.


This works:


foreach (i;0..n)
{
   data ~= r.front;
   r.popFront();
}


but looks a little bit arkward.

I came up with this now:


data = r.take(n).array;


This works partly, because the values of r are not consumed. So I 
have to call afterwards:



r = r.drop(n);


Now I wonder, if it is possible to do this with one single call, 
something like


data = r.take_consuming(n).array;

Does there something like this exist?




Re: Files as buffered InputRange

2019-07-05 Thread berni via Digitalmars-d-learn

On Friday, 5 July 2019 at 18:45:01 UTC, Les De Ridder wrote:

On Friday, 5 July 2019 at 18:29:36 UTC, berni wrote:

On Friday, 5 July 2019 at 17:57:39 UTC, Les De Ridder wrote:

File.byChunk[1] should do the trick.

[1] https://dlang.org/library/std/stdio/file.by_chunk.html


Not sure, if this is, what I'm looking for. I'd like to do 
something like



buffered_file.map!(a=>2*a).writeln();


When I understand it right, with byChunk I'll have to take 
care about the end of the buffer, myself...


You could use `joiner` from std.algorithm, e.g.
buffered_file.byChunk(4096).joiner.map!(a => 2 * a).writeln;


That's it. Thanks!


Re: Files as buffered InputRange

2019-07-05 Thread berni via Digitalmars-d-learn

On Friday, 5 July 2019 at 17:57:39 UTC, Les De Ridder wrote:

File.byChunk[1] should do the trick.

[1] https://dlang.org/library/std/stdio/file.by_chunk.html


Not sure, if this is, what I'm looking for. I'd like to do 
something like



buffered_file.map!(a=>2*a).writeln();


When I understand it right, with byChunk I'll have to take care 
about the end of the buffer, myself...


Files as buffered InputRange

2019-07-05 Thread berni via Digitalmars-d-learn
I'd like to process a (binary) file as a buffered InputRange but 
I havn't found anything yet.  Is there anything or do I have to 
write it on my own?


Re: Checking if CTFE is used?

2018-12-18 Thread berni via Digitalmars-d-learn

On Tuesday, 18 December 2018 at 14:32:29 UTC, Adam D. Ruppe wrote:
CTFE is used if and only if it MUST be used by context. That's 
a runtime function, so no ctfe.


Do something like:

int[4] generate() {
   int[4] tmp;
   foreach(i; 0..4) tmp[i] = i;
   return tmp;
}


static immutable int[4] clue = generate();


Great, that worked. :-) My reasoning was, that CTFE is somewhat 
greedy, that is, everything that can be evaluated at compile time 
will be evaluated at compile time...


Many thanks for your replies. :-)


Re: Checking if CTFE is used?

2018-12-18 Thread berni via Digitalmars-d-learn

On Tuesday, 18 December 2018 at 13:53:01 UTC, Stefan Koch wrote:

Why would you need to know?


Well, first out of curiosity. But there are also other reasons: 
I've got a large immutable array. Without CTFE I'd use some php 
script and add it as a large literal. With CTFE I don't need that 
php script nor do I need to put that large literal in the source 
code. But I need to know, that indeed the array is calculated by 
the compiler, else the solution with the php script would result 
in faster code.



if(__ctfe) assert(0, "Yep, CTFE used");


That seems to work, but unfortunately, my script seems not to be 
evaluated at compile time... Here is a small example, similar to 
my code, where CTFE is not used:



import std.stdio;

class A
{
static immutable int[4] clue;

static this()
{
if(__ctfe) assert(0, "Yep, CTFE used");
foreach (i;0..4) clue[i] = i;
}
}



void main()
{
auto tmp = new A();
writeln(tmp.clue[2]);
}


Can you help me, finding the problem here?


Checking if CTFE is used?

2018-12-18 Thread berni via Digitalmars-d-learn
Is there a way to check if a function is indeed executed at 
compile time or not? (Other than going through the whole 
executable binaries...)


I tried


static this()
{
  if (__ctfe) pragma(msg,"works");
  // some other stuff
}


but unfortunatley this "if" is also executed at compile time, 
when I put it into a function that is only called at runtime. 
When I try "static if" instead the compiler complains about 
"__ctfe" being not known at compile time.


2D-all?

2018-12-14 Thread berni via Digitalmars-d-learn
I've got a lot of code with two-dimensional arrays, where I use 
stuff like:



assert(matrix.all!(a=>a.all!(b=>b>=0)));


Does anyone know if there is a 2D-version of all so I can write 
something like:



assert(matrix.all2D!(a=>a>=0));


how to remove duplicate code in functional style

2018-11-23 Thread berni via Digitalmars-d-learn
I've got the following code, which works, but obviously contains 
duplication. Is there a way to move that 
"dissection_available?...:..." to the place, where it should be?



return dissection_available
?solution.dup
 .transposed.map!(a=>a.map!(b=>"?#."[b]).array)
 
.zip(dissection.dup.transposed.map!(a=>a.map!(b=>"X#.?"[b]).array))

 .map!(a=>a[0].to!string~"  "~a[1].to!string)
 .join("\n")
 .to!string
:solution.dup
 .transposed.map!(a=>a.map!(b=>"?#."[b]).array)
 .join("\n")
 .to!string;


solution and dissection are of type const(int[][]).


Re: transposed with enforceNotJagged not throwing?

2018-09-22 Thread berni via Digitalmars-d-learn
On Saturday, 22 September 2018 at 12:52:45 UTC, Steven 
Schveighoffer wrote:
It was suggested when transposed was fixed to include opIndex, 
but never implemented.


Maybe I'm too naive, but isn't it easy to implement it just the 
same way, it is done with transverse? That is: putting the 
"static if"-part from the constructor there in the constructor of 
Transposed?




transposed with enforceNotJagged not throwing?

2018-09-22 Thread berni via Digitalmars-d-learn

I expect this small program to throw an Exception:


import std.stdio;
import std.range;

void main()
{
auto a = [[1,2],
  [4,5,3]];

a.transposed!(TransverseOptions.enforceNotJagged).writeln;
}


But it just outputs:


[[1, 4], [2, 5], [3]]


Is it a bug or is it me who's doing something wrong?


Re: std.process.execute without capturing stderr?

2018-09-21 Thread berni via Digitalmars-d-learn
On Thursday, 20 September 2018 at 14:10:44 UTC, Steven 
Schveighoffer wrote:

Hm... 2.079.0 had it:


Sorry, I made a mistake while testing and after I found out, that 
it was not available in the documentation at dpldocs.info I 
concluded, that it must be a really new feature. But now it seems 
to me, that dpldocs is outdated a little bit, isn't it?


Meanwhile I've got the latest version of dmd and made it working.


Re: std.process.execute without capturing stderr?

2018-09-20 Thread berni via Digitalmars-d-learn

On Thursday, 20 September 2018 at 07:36:06 UTC, Paul Backus wrote:
Looks like `Config.stderrPassThrough` [1] should do what you 
want:


const result = execute(args[1..$], null, 
Config.stdErrPassThrough);


[1] 
https://dlang.org/phobos/std_process.html#.Config.stderrPassThrough


In theory that looks good. Unfortunatley it's a relativly young 
feature which my compilers don't know about yet (dmd 2.079 and 
ldc based on an even older version of dmd). So in practice I'll 
probably have to wait until the next release cycle of debian in 
spring 2019... (maybe for the time being I'll update dmd and use 
dmd for this small part instead of ldc, but I yet don't know how 
to tell CMake to use dmd for this one file... But I'll probably 
figure this out.)




std.process.execute without capturing stderr?

2018-09-20 Thread berni via Digitalmars-d-learn
I need to execute a program and capture stdout, which I hoped 
std.process.execute would do. But unfortunatly this command also 
captures stderr, which I need to be ignored. When looking at the 
implementation of std.process.execute I see, that I can probably 
do this by removing "Redirect.stderrToStdout" in the function 
executeImpl. But for that I have to copy lots of functions from 
phobos in my own code. Is there an easier way to do that?


In case you wonder why I need this: I'm currently using a PHP 
frontend and a D backend. I'm calling the D routines with the PHP 
exec command which works fine, but unfortunately removes trailing 
whitespaces, that I need. Therefore I'd like to have a wrapper 
that replaces all whitespace by some escape sequences which than 
are restored in PHP. First I thought I can use sed for that, but 
unfortunately the return code gets lost here. I'm using stderr to 
show some progress information, which should be shown 
immediately. (I've you've got other ideas how to get arround this 
design flaw (as I see it) in php exec, I'd be happy too.)


I don't want to touch the D backend - that's not the place, where 
the problem lies and when I decide to change the frontend I've to 
remember to change the backend too, which I don't like.


Here my complete program:


import std.process;
import std.stdio;
import std.array;

int main(string[] args)
{
const result = execute(args[1..$]);
writeln(result[1].replace("\\","").replace(" ","\\s"));
return result[0];
}


Re: Cannot use UFCS in lambda?

2018-09-16 Thread berni via Digitalmars-d-learn
The problem is more general: you can only use top-level symbols 
in UFCS.


You can use an identity alias template to bypass this:
https://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/
(search for UFCS in the page).


Good to know. :-)


Cannot use UFCS in lambda?

2018-09-16 Thread berni via Digitalmars-d-learn

The following program does not compile:


import std.stdio;
import std.algorithm;

struct A
{
   struct S
   {
   int x;
   }

   const bool foo(in S s, in int k)
   {
   return s.xa.foo(3)).writeln;
   }
}

void main()
{
   A().bar();
}


I get (using rdmd):


test.d(18): Error: no property foo for type S
/usr/include/dmd/phobos/std/algorithm/iteration.d(1108):
instantiated from here: >FilterResult!(__lambda1, S[])

test.d(18):instantiated from here: filter!(S[])


When I replace the UFCS-Syntax in the lambda by a function call 
it works:



[S(1),S(2),S(3),S(4),S(5)].filter!(a=>foo(a,3)).writeln;


Where is my mistake?


Re: array to string functional?

2018-09-15 Thread berni via Digitalmars-d-learn
Can you post a complete, runnable example that illustrates your 
problem?


Strange as it is, now it works here too... - I don't know, what 
went wrong yesterday. Thanks anyway. :-)


Re: array to string functional?

2018-09-15 Thread berni via Digitalmars-d-learn
Anotherone I'm not getting to work: From some output with 
newlines I want to discard all lines, that start with a # and 
select part of the other lines with a regex. (I know the regex 
r".*" is quite useless, but it will be replaced by something more 
usefull.)


I tried the following, but non worked:

output.split("\n").filter!(a=>a.length>0 && 
a[0]!='#').matchFirst(r".*");


output.split("\n").filter!(a=>a.length>0 && 
a[0]!='#').array.matchFirst(r".*");


output.split("\n").filter!(a=>a.length>0 && 
a[0]!='#').array.map!(matchFirst(r".*"));


output.split("\n").filter!(a=>a.length>0 && 
a[0]!='#').array.map!(a=>matchFirst(a,r".*"));


Any ideas?


Re: array to string functional?

2018-09-14 Thread berni via Digitalmars-d-learn

On Saturday, 15 September 2018 at 03:25:38 UTC, Paul Backus wrote:

On Friday, 14 September 2018 at 20:43:45 UTC, SrMordred wrote:

What you want is std.range.chunks


auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];
a.map!(to!string)
 .join("")
 .chunks(4)
 .map!(to!string) //don´t know why the chunks are not 
already strings at this point ;/

 .writeln;


It's easier if you chunk before joining:

auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];

a.map!(to!string)
 .chunks(4)
 .map!join
 .writeln;


Oh, thanks. What I didn't know about was join. Now I wonder how I 
could have found out about it, without asking here? Even yet I 
know it's name I cannot find it, nighter in the language 
documentation nor in the library documentation.


array to string functional?

2018-09-14 Thread berni via Digitalmars-d-learn
a) I've got an int[] which contains only 0 und 1. And I want to 
end with a string, containing 0 and 1. So [1,1,0,1,0,1] should 
become "110101". Of course I can do this with a loop and ~. But I 
think it should be doable with functional style, which is 
something I would like to understand better. Can anyone help me 
here? (I think a.map!(a=>to!char(a+'0')) does the trick, but is 
this good style or is there a better way?)


b) After having this I'd like to split this resulting string into 
chunks of a fixed length, e.g. length 4, so "110101" from above 
should become ["1101","01"]. Again, is it possible to do that 
with functional style? Probably chunks from std.range might help 
here, but I don't get it to work.


All in all, can you fill in the magic functional chain below?


auto a = [1,0,1,1,1,0,1,0,1,1,1,1,0];

auto result = magic functional chain here :-)

assert(result==["1011","1010","","0"]);




enforce with return type RegexMatch!string

2018-09-11 Thread berni via Digitalmars-d-learn

I've got the folling function which returns a RegexMatch!string:


auto extract_list(const string entry)
{
// check if entry is valid

return matchAll(entry, some_regex);
}


I call this function using enforce(extract_list(some_argument)). 
I think, that enforce is quite useless in this version. But I'd 
like to add a check, if entry is valid in the 
extract_list-function, something like:



if (!matchFirst(entry, other_regex)) return null;


That doesn't work, because I cannot cast null to 
RegexMatch!string (I don't understand why). What works is to 
create a string[] from the result of matchAll (using map and 
array) and use that array instead of the range. Now I can return 
null too.


Is there a way to accomplish this?


Re: Is it possible to exit a contract?

2018-03-22 Thread berni via Digitalmars-d-learn

On Thursday, 22 March 2018 at 16:22:04 UTC, Ali Çehreli wrote:
Never thought of it before. :) I would put all that code into a 
function and call from the out block.


I rejected this, because I've got an unease feeling using extra 
functions in contract programming. Can't tell, where this feeling 
comes from; maybe just because I've too few experience with 
contract programming...




Is it possible to exit a contract?

2018-03-22 Thread berni via Digitalmars-d-learn

Part of my code looks like this:


out (result)
{
  if (result==true)
  {
lots of assertions...
  }
}


I would prefer an early exit like:


out (result)
{
  if (result==false) return;

  lots of assertions...
}


Is this possible somehow (return and break don't do the job...). 
The only thing I found is using goto, which I prefer over that 
gigantic if-block, but maybe there is something better, I don't 
know of?


Re: Building a project with CMAKE

2017-03-04 Thread berni via Digitalmars-d-learn

On Saturday, 4 March 2017 at 10:02:15 UTC, Johan Engelen wrote:
If you think you have a good testcase, it's nice for compiler 
devs like me to open a new thread about the difference that you 
found between the compilers (so that we can try and improve 
things).


I'm not sure, if my "testcase" is generally a good one.

Here is some background: In the last 10 years I developed about 
200 programs for checking logical puzzles (like sudoku), all 
written in java. About a year ago I decided to make these 
programs free software. But as I have to refactor them anyway and 
I dislike java meanwhile I decided to change the language when 
doing so.


I decided on a special puzzle type, called double mine (similar 
to minesweeper, but in every row and column, there have to be 
exactly two mines and mines may not touch, not even diagonally), 
to check out different languages. Speed was just one criterion 
when doing this.


At that time D wasn't among the candidates, because I did not 
know of this language at all. I added D later (with almost no 
knowledge about D) and checked out all three compilers.


If you think, this program could be usefull for you, I can email 
it to you...


Re: Building a project with CMAKE

2017-03-03 Thread berni via Digitalmars-d-learn

On Friday, 3 March 2017 at 20:10:25 UTC, Ali Çehreli wrote:
Which would put gdc in between the two. Is your experience 
different?


Actually, I've got not much experience. A few weeks ago I ran a 
test where ldc was in between dmd and gdc. But I missed the 
-release flags then. With that flag it's faster, but still slower 
than gdc on that one (B below). With an other testcase, where I 
compared them, gdc and ldc are on equals speed (A below).


A) dmd 52s, gdc 22s, ldc 22s
B) dmd 432s, gdc 280s, ldc 310s



Re: Building a project with CMAKE

2017-03-03 Thread berni via Digitalmars-d-learn

On Friday, 3 March 2017 at 13:21:56 UTC, Seb wrote:

Is there any specific reason why you can't use DMD or LDC?


gdc produces faster binaries. ;-) I've got installed the other 
two compilers too and they work.





Re: Building a project with CMAKE

2017-03-03 Thread berni via Digitalmars-d-learn

On Thursday, 2 March 2017 at 09:13:40 UTC, berni wrote:
Just a note: I now asked the same question on the cmake mailing 
list. Maybe, it's the better place to do so...


After some help of cmake people and a morning of more 
investigations, I'm quite sure I found a bug in gdc. Meanwhile 
I've got a small example that compiles with gdc but leads to a 
linking error when compiled with -O3.


Re: Building a project with CMAKE

2017-03-02 Thread berni via Digitalmars-d-learn

On Tuesday, 28 February 2017 at 17:09:28 UTC, berni wrote:

I'm using CMAKE to build my project. [...]


Just a note: I now asked the same question on the cmake mailing 
list. Maybe, it's the better place to do so...


Building a project with CMAKE

2017-02-28 Thread berni via Digitalmars-d-learn
I'm using CMAKE to build my project. With 
https://github.com/dcarp/cmake-d this works almost. The only 
thing I do not manage to get working is running cmake in release 
mode. When I use -DCMAKE_BUILD_TYPE=Release I get some linker 
errors, which I do not get, when compiling manually. (In both 
cases gdc/linux is used.)


I allready could figure out, that it's due to the -O3 compiler 
flag used in release mode. It looks like cmake compiles all *.d 
files separately and while doing so, removes some functions when 
optimizing them. Later, when linking everything together, they 
are missing. (But I'm not sure on this.)


Here is my project: https://github.com/crocopaw/croco/tree/devel

Anybody here who has experience with CMAKE and D and could help?


Re: Checking, whether string contains only ascii.

2017-02-23 Thread berni via Digitalmars-d-learn

On Thursday, 23 February 2017 at 17:44:05 UTC, HeiHon wrote:

Generally postscript files may contain binary data.
Think of included images or font data.
So in postscript files there should normally be no utf-8 
encoded text, but binary data are quite usual.

Think of postscript files as a sequence of ubytes.


As far as I know, images and font data have to be in clean7bit 
too (they are not human readable though). But postscript files 
can contain preview images, which can be binary. I know about 
this. I just tried to keep my question simple -- and actually I'm 
only testing part of the postscript file, where I know, that 
binary data must not occur.


Re: Checking, whether string contains only ascii.

2017-02-23 Thread berni via Digitalmars-d-learn

On Wednesday, 22 February 2017 at 21:23:45 UTC, H. S. Teoh wrote:

enforce(!s.any!"a > 127");


Puh, it's lot's of possibilities to choose of, now... I thought 
of something like the foreach-loop but wasn't sure if that is 
correct for all utf encodings. All in all, I think I take the 
any-approach, because it feels a little bit more like looking at 
the string at a whole and I like to use enforce.


Thanks for all your answers!



Re: how to pass stderr to core.stdc.stdio.fileno

2017-02-22 Thread berni via Digitalmars-d-learn
As I cannot find any PM-feature in this forum and don't know how 
to contact you else, I'm hijacking this thread to give you some 
feedback...


On Friday, 17 February 2017 at 19:16:44 UTC, Adam D. Ruppe wrote:
Yes, that is my documentation fork, it has a search feature if 
you do dpldocs.info/some_term and it tries to be easier to read 
and navigate, let me know how you like it!


I tried dpldocs.info/max looking for a function that gives the 
maximum of two or more values. I got a lot of results, but non of 
them was, what I was looking for. Meanwhile I found it, namely 
this one:


http://dpldocs.info/experimental-docs/std.algorithm.comparison.max.html

Maybe you can figure out, why this is not included in the search 
result?


Checking, whether string contains only ascii.

2017-02-22 Thread berni via Digitalmars-d-learn
In my program, I read a postscript file. Normal postscript files 
should only be composed of ascii characters, but one never knows 
what users give us. Therefore I'd like to make sure that the 
string the program read is only made up of ascii characters. This 
simplifies the code thereafter, because I then can assume, that 
codeunit==codepoint. Is there a simple way to do so?


Here a sketch of my function:


void foo(string postscript)
{
   // throw Exception, if postscript is not all ascii
   // other stuff, assuming codeunit=codepoint
}


Re: Force inline

2017-02-21 Thread berni via Digitalmars-d-learn

On Monday, 20 February 2017 at 13:48:30 UTC, ketmar wrote:
anyway, in my real-life code inlining never worth the MASSIVELY 
increased compile times: speedup is never actually noticeable. 
if "dmd -O" doesn't satisfy your needs, there is usually no 
reason to trying "-inline", it is better to switch to ldc/gdc.


Probably you're right. I'm using gdc anyway for non-developement 
compiles. I was just curious how much that -inline switch of dmd 
is worth. (Answer: Yet, almost nothing. And knowing, that it is 
buggy together with -O even less than that.)


When comparing dmd and gdc the results where both almost the 
same: 29 seconds. (As a reference: C++ is 22 seconds.) With gdc I 
got a good improvement when using -frelease additionally to -O3 
(now it's 24 seconds). The inline-pragma didn't change anything.


On Monday, 20 February 2017 at 17:12:59 UTC, H. S. Teoh wrote:

Having said all that, though, have you used a profiler to 
determine whether or not your performance bottleneck is really 
at the function in question?


Yes, I did. An well, yes I know: Good design is much more 
important, than speed optimization. And by obeying this, I found 
out, that by changing the order of the conditions used in that 
particular function, I could reduce the duration by 2 more 
seconds... (And in case you wonder, why I bother about 2 seconds: 
It's a small example for testing purpose. There are larger ones 
where this could easily be hours instead of seconds...)


Re: Force inline

2017-02-20 Thread berni via Digitalmars-d-learn

On Sunday, 19 February 2017 at 20:00:00 UTC, Daniel Kozak wrote:

Dne 19.2.2017 v 20:19 berni via Digitalmars-d-learn napsal(a):


Is it possible to force a function to be inlined?

Comparing a C++ and a D program, the main difference in speed 
(about 20-30%) is, because I manage to force g++ to inline a 
function while I do not find any means to do the same on D.

yes
https://wiki.dlang.org/DIP56


pragma(inline, true) doesn't work out well:


int bar;

void main(string[] args)
{
   if (foo()) {}
}

bool foo()
{
   pragma(inline, true)

   if (bar==1) return false;
   if (bar==2) return false;

   return true;
}


with


dmd -inline test.d


I get


test.d(8): Error: function test.foo cannot inline function


When I remove -inline, it compiles, but seems not to inline. I 
cannot tell from this small example, but with the large program, 
there is no speed gain.


It also compiles with -inline when I remove the "if (bar==2)...". 
I guess, it's now really inlining, but the function is 
ridiculously short...


I havn't tried the approach with templates yet, due to my lack of 
understanding templates.


Force inline

2017-02-19 Thread berni via Digitalmars-d-learn

Is it possible to force a function to be inlined?

Comparing a C++ and a D program, the main difference in speed 
(about 20-30%) is, because I manage to force g++ to inline a 
function while I do not find any means to do the same on D.


Re: segmentation fault with Object.factory()

2017-02-19 Thread berni via Digitalmars-d-learn
On Sunday, 19 February 2017 at 10:15:49 UTC, rikki cattermole 
wrote:

What's wrong here?


void main()
{
   A bar = cast(A)Object.factory(__MODULE__ ~ ".AA");
   bar.foo();
}


Oops. I overdid when trying to create a small example. With the 
module it works, but my original program had the module and still 
produced an segmentation fault. After some more investigations I 
found out, that it was not due to a mistake in the program, but 
because rdmd didn't recompile after I called it with an 
--extra-file added. Looks like a bug in rdmd... Here is a small 
example:


test.d:


module test;

import std.stdio;

void main()
{
   B tmp = cast(B)Object.factory("test2.BB");
   tmp.m1();
}

interface A   { abstract void m1(); }
interface B:A { abstract void m2(); }
class AA:A{ override void m1() { writeln("A"); } }


test2.d:


module test2;

import std.stdio;
import test;

class BB:AA,B { override void m2() { writeln("B"); } }


And here is what I get when compiling:


$> rdmd test.d
segmentation fault
$> rdmd --extra-file=test2.d test.d
segmentation fault
$> rm -rf /tmp/.rdmd-1000/
$> rdmd --extra-file=test2.d test.d
A
$> rdmd -version
rdmd build 20170122
[...]


Should I report this bug anywhere (or am I wrong again?)


segmentation fault with Object.factory()

2017-02-19 Thread berni via Digitalmars-d-learn

I get a segmentation fault, when I run this program:


void main()
{
   A bar = cast(A)Object.factory("AA");
   bar.foo();
}

class A{ abstract void foo(); }
class AA:A { override void foo() {} }


The call of bar.foo() is, where the segmentation fault occurs. 
When I use A bar = new AA(); instead of the factory it works.


What's wrong here?


Re: Hello, folks! Newbie to D, have some questions!

2017-02-18 Thread berni via Digitalmars-d-learn

I'm new here too (never heard of D before 2017).


c). The whole community seems infused with both the Feminism/SJW


I didn't tried out Rust, but that would draw me away too. 
(Incidentally it was a comment on alternatives for Rust, that 
pointed me to D.)


2. I am also curious as to what would be the best path for a 
complete beginner to D to learn it effectively?


I started with the online version of the book of Ali Çehreli but 
after a while I decided to buy it and was impressed on its size 
(more than 700 pages!). Meanwhile I'm halfway through.


At the same time I'm working on a project of mine, which I just 
started writing in C++ last december, because I couldn't find a 
better language and thought I had to bite the bullet. Meanwhile 
it's completely rewritten in D (but two lines of C code that I 
need to use a C-libraray). Whenever I came across a new concept 
in the book I tried to refactor that project using this concept.


This approach worked very well for me. (And I appreciate this 
Learn-forum, because else I'd not dare to ask my seemingly silly 
questions.)


You wrote:

... area thoroughly!The introspection ...


I just realised, how much I'm thinking in D allready when I saw 
this: At first glance I wondered, what this thoroughly-template 
is about... ;-)




Re: scope with if

2017-02-18 Thread berni via Digitalmars-d-learn

Just a note - I found something, that works:


import std.stdio;

void main(string[] args)
{
   immutable cond = args[1]=="a";
   if (cond) write("A");
   scope (exit) if (cond) write("B");

   write("C");
}


I'm using the immutable variable to avoid, that the condition 
changes later.


scope with if

2017-02-17 Thread berni via Digitalmars-d-learn

I wonder if it's possible to do something like this:


import std.stdio;

void main(string[] args)
{
   if (args[1]=="a")
   {
   write("A");
   scope (exit) write("B");
   }

   write("C");
}


I expected the output to be ACB not ABC. I understand, that the 
scope ends at the end of the if, but I wonder, if it's possible 
to have a "conditional scope" or something like this.


I found a workaround using "finally", but anyway I'm curious.


Re: how to pass stderr to core.stdc.stdio.fileno

2017-02-17 Thread berni via Digitalmars-d-learn

On Friday, 17 February 2017 at 19:16:44 UTC, Adam D. Ruppe wrote:
Yes, that is my documentation fork, it has a search feature if 
you do dpldocs.info/some_term and it tries to be easier to read 
and navigate, let me know how you like it!


What I've seen so far, looks quite good.

What I didn't understand was that large box below write in stdio. 
Maybe, it's because I'm not familiar with templates yet. But when 
I click on the question mark in the corner I get an empty search 
result, which, of course, doesn't explain anything.


Re: how to pass stderr to core.stdc.stdio.fileno

2017-02-17 Thread berni via Digitalmars-d-learn

On Friday, 17 February 2017 at 16:08:11 UTC, Adam D. Ruppe wrote:

Try

fileno(core.stdc.stdio.stderr);

to force it to use the C stderr object instead of the D one.

Alternatively, fileno(stderr.getFP()) should do it too.
http://dpldocs.info/experimental-docs/std.stdio.File.getFP.html


Many thanks! That worked. And also thanks for the link. I didn't 
know if this docs yet. :-)


Re: Strange behaviour of rdmd vs. dmd concerning main function

2017-02-17 Thread berni via Digitalmars-d-learn
Something similar happend now, but this time it works with dmd 
and rdmd produces the error:


The command that works is

dmd a.d b.o

where b.o is a precompiled c file, similar to 
https://github.com/dlang/druntime/blob/master/src/core/stdc/errno.c


When using rdmd it doesn't work anymore. When I make rdmd 
--chatty, I can find the reason: b.o is ommited in the call of 
dmd. How can I make rdmd pass this parameter to dmd too?


how to pass stderr to core.stdc.stdio.fileno

2017-02-17 Thread berni via Digitalmars-d-learn

The following code doesn't work:


int no = fileno(stderr);


The error message is:

test.d(7): Error: function core.stdc.stdio.fileno 
(shared(_IO_FILE)*) is not callable using argument types (File)


How can I cast stderr to something, that fileno() accepts?


Re: Better than "Clock.currStdTime()/10000000"

2017-02-15 Thread berni via Digitalmars-d-learn
On Wednesday, 15 February 2017 at 15:58:41 UTC, Jonathan M Davis 
wrote:

[...]
 MonoTime before = MonoTime.currTime;
 Thread.sleep(dur!"msecs"(1000));
 MonoTime after = MonoTime.currTime;
 Duration timeElapsed = after - before;

 writeln(timeElapsed);
}
```
I get: "1 sec, 26 μs, and 4 hnsecs"


This is the correct way to do it. [...]


Oh, thanks for noting this. As I finally needed the seconds as an 
int (or long) I had to use timeElapsed.total!"seconds" which I 
would not have found out without Seb's posting. :-)


Re: A bug?

2017-02-15 Thread berni via Digitalmars-d-learn

On Wednesday, 15 February 2017 at 16:11:36 UTC, drug wrote:
No, you recursively call main() and get segfault (due to stack 
overflow) as expected


I thought, that an stack overflow leeds to an exception. But 
that's not true, as I now see. Thanks for your answer.


A bug?

2017-02-15 Thread berni via Digitalmars-d-learn

I'm not sure if this is considered a bug:


import std.stdio;
import std.string;

int c = 0;

void main()
{

   try {
   write(++c," ");
   stdout.flush();
   int[10] tmp;
   throw new Exception(format("%s",tmp));
   } finally
   {
   main();
   }
}


Output:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Segmentation 
fault


  1   2   >