Re: foreach / mutating iterator - How to do this?

2018-06-25 Thread Robert M. Münch via Digitalmars-d-learn

On 2018-06-25 15:29:23 +, Robert M. Münch said:

I have two foreach loops where the inner should change the iterator 
(append new entries) of the outer.


foreach(a, candidates) {
foreach(b, a) {
if(...) candidates ~= additionalCandidate;
}
}

The foreach docs state that the collection must not change during iteration.

So, how to best handle such a situation then? Using a plain for loop?


Answering myself: If you implement an opApply using for() or while() 
etc. with a mutating aggregate, foreach can be used indirectly with 
mutating aggregates. Works without any problems.


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



Re: Debugging compile time memory usage

2018-06-25 Thread Bauss via Digitalmars-d-learn

On Tuesday, 26 June 2018 at 00:59:24 UTC, Nicholas Wilson wrote:

On Sunday, 24 June 2018 at 14:16:26 UTC, Kamil Koczurek wrote:

[...]


If you were able to compile it with LDC and not DMD, then that 
is most likely due to the LDC executable being 64-bit (limited 
to available system RAM+swaps) and the DMD executable being 
32-bit (limited to 4GB).


If you want to use DMD, build a 64-bit version yourself and 
complain on general that the releases are not 64-bit.


Is there a specific reason why DMD isn't shipped as 64bit by 
default? Literally most machines are 64bit these days, so why do 
we limit ourselves to 32bit?


Re: template sequence parameters treats member functions differently?

2018-06-25 Thread aliak via Digitalmars-d-learn
On Monday, 25 June 2018 at 18:59:37 UTC, Steven Schveighoffer 
wrote:

On 6/25/18 2:51 PM, aliak wrote:
On Monday, 25 June 2018 at 15:06:42 UTC, Steven Schveighoffer 
wrote:


I don't see any reason why the alias is to the function and 
not the contexted function. I don't see how it's any 
different from the ones which use inner functions.


I can only agree - me no see either. And having no clue as to 
how the compiler is implemented, I cannot even conjecture :)




Well, it's worth an enhancement request in any case.

-Steve


doneo: https://issues.dlang.org/show_bug.cgi?id=19026


Re: Debugging compile time memory usage

2018-06-25 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 24 June 2018 at 14:16:26 UTC, Kamil Koczurek wrote:
I recently wrote a brainfuck compiler in D, which loads the BF 
source at compile time, performs some (simple) optimizations, 
translates everything to D and puts it into the source code 
with a mixin.


I did manage to get some pretty good performance, but for some 
programs in brainfuck I have to use LDC instead of DMD because 
the latter runs out of memory. Is there a way for me to 
optimize my code in such a way that DMD will be able to compile 
it?


D code: https://pastebin.com/fg1bqwnd
BF program that works: 
https://github.com/erikdubbelboer/brainfuck-jit/blob/master/mandelbrot.bf
BF program that makes DMD crash: 
https://github.com/fabianishere/brainfuck/blob/master/examples/hanoi.bf


After putting BF code in code.bf and D in main.d, I compile it 
with the following command: dmd main.d -J./


Error msg: unable to fork: Cannot allocate memory
DMD version: DMD64 D Compiler v2.080.0-dirty


If you were able to compile it with LDC and not DMD, then that is 
most likely due to the LDC executable being 64-bit (limited to 
available system RAM+swaps) and the DMD executable being 32-bit 
(limited to 4GB).


If you want to use DMD, build a 64-bit version yourself and 
complain on general that the releases are not 64-bit.


Re: Can I parse this kind of HTML with arsd.dom module?

2018-06-25 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 24 June 2018 at 03:46:09 UTC, Dr.No wrote:
to make it work. But if anyone else know how to fix this, will 
be very welcome too!


try it now.

thanks to Sandman83 on github.


Re: Nullable!T with T of class type

2018-06-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, June 25, 2018 19:40:30 kdevel via Digitalmars-d-learn wrote:
> Just stumbled over the following design:
>
> class S {...}
>
> class R {
>
>Nullable!S s;
>
> }
>
> s was checked in code like
>
> R r;
>
> if (r.s is null)
>throw new Exception ("some error message");
>
> At runtime the following was caught:
>
>  fatal error: caught Throwable: Called `get' on null Nullable!S
>
> Why can't this programming error be detected at compile time?

If you have a function that accepts Nullable!T, when that function is
called, how on earth is it going to know whether the argument it received
was null at compile time? That depends entirely on the argument, which could
have come from anywhere. So, in the general case, the compiler can't
possibly determine whether a variable is null or not at compile time.

And as far as just within a function goes, Nullable is a library type.
There's nothing special about it. The compiler has no magic knowledge about
what it does or how it functions. So, how would it know that

R r;
r.foo();

was bad code? And honestly, this sort of problem actually gets surprisingly
thorny even if you tried to bake this into the compiler for a built-in type.
Sure, it would be straightforward for the compiler to see that

int* i;
*i = 42;

is dereferencing null, but as soon as you start adding if statements,
function calls, etc. it quickly becomes impossible for the compiler to
accurately determine whether the pointer is null or not. Any such attempt
will inevitably end up with false positives, forcing you to do stuff like
assign variables values when you know that it's unnecessary - it would
complicate the compiler considerably to even make the attempt. It's far
simpler to just treat it as a runtime error. Even more restricted languages
such as Java do that. Java does try to force you to initialize stuff
(resulting in annoying false positives at times), but in general, it still
can't guarantee when a variable is null or not and is forced to insert
runtime null checks.

> Is it possible
> to "lower" the Nullable operations if T is a class type such that
> there
> is only one level of nullification?

It's been discussed before, but doing so would make the behavior of Nullable
depend subtly on what type it contained and risks bugs in generic code.
Also, there _is_ code out there which depends on the fact that you can have
a Nullable!MyClass where the variable has a value and that value is a null
reference. If you really don't want the extra bool, then just don't use
Nullable. Class references are already naturally nullable.

- Jonathan M Davis



Re: foreach / mutating iterator - How to do this?

2018-06-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, June 25, 2018 17:29:23 Robert M. Münch via Digitalmars-d-learn 
wrote:
> I have two foreach loops where the inner should change the iterator
> (append new entries) of the outer.
>
> foreach(a, candidates) {
>   foreach(b, a) {
>   if(...) candidates ~= additionalCandidate;
>   }
> }
>
> The foreach docs state that the collection must not change during
> iteration.
>
> So, how to best handle such a situation then? Using a plain for loop?

Either that or create a separate array containing the elements you're adding
and then append that to candidates after the loop has terminated. Or if all
you're really trying to do is run an operation on a list of items, and in
the process, you get more items that you want to operate on but don't need
to keep them around afterwards, you could just wrap the operation in a
function and use recursion. e.g.

foreach(a, candidates)
{
doStuff(a);
}

void func(T)(T a)
{
foreach(b, a)
{
if(...)
func(additionalCandidate);
}
}

But regardless, you can't mutate something while you're iterating over it
with foreach, so you're either going to have to manually control the
iteration yourself so that you can do it in a way that guarantees that it's
safe to add elements while iterating, or you're going to have to adjust what
you're doing so that it doesn't need to add to the list of items while
iterating over it.

The big issue with foreach is that if it's iterating over is a range, then
it copies it, and if it's not a range, it slices it (or if it defines
opApply, that gets used). So,

foreach(e; range)

gets lowered to

foreach(auto __c = range; !__c.empty; __c.popFront())
{
auto e = __c.front;
}

which means that range is copied, and it's then unspecified behavior as to
what happens if you try to use the range after passing it to foreach (the
exact behavior depends on how the range is implemented), meaning that you
really shouldn't be passing a range to foreach and then still do anything
with it.

If foreach is given a container, then it slices it, e.g.

foreach(e; container)

foreach(auto __c = container[]; !__c.empty; __c.popFront())
{
auto e = __c.front;
}

so it doesn't run into the copying problem, but it's still not a good idea
to mutate the container while iterating. What happens when you try to mutate
the container while iterating over a range from that container depends on
the container, and foreach in general isn't supposed to be able to iterate
over something while it's mutated.

Dynamic and associative arrays get different lowerings than generic ranges
or containers, but they're also likely to run into problems if you try to
mutate them while iterating over them.

So, if using a normal for loop instead of foreach fixes your problem, then
there you go. Otherwise, rearrange what you're doing so that it doesn't need
to add anything to the original list of items in the loop. Either way,
trying to mutate what you're iterating over is going to cause bugs, albeit
slightly different bugs depending on what you're iterating over.

- Jonathan M Davis




Nullable!T with T of class type

2018-06-25 Thread kdevel via Digitalmars-d-learn

Just stumbled over the following design:

   class S {...}

   class R {
  :
  Nullable!S s;
  :
   }

s was checked in code like

   R r;
   :
   if (r.s is null)
  throw new Exception ("some error message");

At runtime the following was caught:

fatal error: caught Throwable: Called `get' on null Nullable!S

Why can't this programming error be detected at compile time? Is 
it possible
to "lower" the Nullable operations if T is a class type such that 
there

is only one level of nullification?

BTW: https://dlang.org/library/std/typecons/nullable.html 
contains duplicate sections:


Function nullable
Function nullable
Struct Nullable
Struct Nullable



Re: template sequence parameters treats member functions differently?

2018-06-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/25/18 2:51 PM, aliak wrote:

On Monday, 25 June 2018 at 15:06:42 UTC, Steven Schveighoffer wrote:


I don't see any reason why the alias is to the function and not the 
contexted function. I don't see how it's any different from the ones 
which use inner functions.


I can only agree - me no see either. And having no clue as to how the 
compiler is implemented, I cannot even conjecture :)




Well, it's worth an enhancement request in any case.

-Steve


Re: template sequence parameters treats member functions differently?

2018-06-25 Thread aliak via Digitalmars-d-learn
On Monday, 25 June 2018 at 15:06:42 UTC, Steven Schveighoffer 
wrote:

On 6/24/18 5:19 PM, aliak wrote:

[...]


No, because the alias is an alias to the function, not the 
delegate.


The act of taking the address creates the delegate, where the 
delegate's ptr is the context pointer (i.e. s), and the funcptr 
is the function that accepts the pointer (i.e. S.f).


When you pass in s.f to an alias, you are actually passing in 
S.f. It's the fact that you are looking in the *namespace* of s 
when you do the alias. The &s.f is special for the compiler, 
and can't be deferred to later.


Ahh, I see. Ah well. So not really much i can do here with this 
then I guess. Thanks for explaining though!




BUT, I'm thinking this may be fixable, as it's inconsistent 
with inner functions:


auto foo(alias x)() { return x(); }

struct S
{
   int bar() { return 42; }

   // int baz() { return foo!bar; } // nope
}

void main()
{
   S s;

   int bar() { return 42; }

   assert(foo!bar() == 42); // ok
   // assert(foo!(s.bar) == 42); // nope

   int baz() { return s.bar; }
   assert(foo!baz() == 42); // ok!
}

I don't see any reason why the alias is to the function and not 
the contexted function. I don't see how it's any different from 
the ones which use inner functions.


-Steve


I can only agree - me no see either. And having no clue as to how 
the compiler is implemented, I cannot even conjecture :)




Futures

2018-06-25 Thread Russel Winder via Digitalmars-d-learn
Hi,

I am sure std.parallelism and vibe.d both have futures/channels/executors
systems as there appears not to be anything in Phobos as a futures system. Or
am I wrong here?

What is needed is a futures system with a single threaded executor system that
can be integrated with GtkD so as to make something for D akin to what is
happening in gtk-rs.
 
-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk


signature.asc
Description: This is a digitally signed message part


Re: overload .

2018-06-25 Thread aliak via Digitalmars-d-learn

On Monday, 25 June 2018 at 15:39:09 UTC, Mr.Bingo wrote:

On Monday, 25 June 2018 at 13:58:54 UTC, aliak wrote:
A.x is translated in to A.opDispatch!"x" with no args. So I 
guess you can overload or you can static if on a template 
parameter sequence:


import std.stdio;
struct S {
auto opDispatch(string name, Args...)(Args args) {
static if (!Args.length) {
return 3;
} else {
// set something
}
}
}
void main()
{
S s;
s.x = 3;
writeln(s.x);
}

Cheers,
- Ali


Ok, for some reason using two different templated failed but 
combining them in to one passes:


auto opDispatch(string name, T)(T a)
auto opDispatch(string name)()

Maybe it is a bug in the compiler that it only checks one 
opDispatch?


Two opDispatchs as in:

import std.stdio: writeln;
struct S {
void opDispatch(string name, T)(T t) {
writeln(t);
}

auto opDispatch(string name)() {
writeln("ret");
return 4;
}
}

void main() {
S s;
s.x;
s.x = 4;
}

??

The above seems to work fine. Or maybe you meant something else?



Re: Making sense of recursion

2018-06-25 Thread ag0aep6g via Digitalmars-d-learn

On 06/25/2018 07:45 PM, zbr wrote:


void mergeSort(int[] arr, int l, int r)
{
    if (l < r)   // 1
    {
   int m = l+(r-l)/2;    // 2
   mergeSort(arr, l, m); // 3
   mergeSort(arr, m+1, r);   // 4
   merge(arr, l, m, r);  // 5
    }    // 6
}   // 7

mergeSort(arr, 0, 4);

When I see this, I visualize the recursion to perform this way:

mergeSort(arr, 0, 4):
     0 < 4 ? true: mergeSort(0, 2):
     0 < 2 ? true: mergeSort(0, 1):
     0 < 1 ? true: mergeSort(0, 0):
     0 < 0 ? false: //reach the end of mergeSort / reach 
line 6 and then 7


I don't see the computer ever reaching line 4 and 5? Obviously I'm wrong 
but where is my mistake?


You seem to think that a recursive call takes over completely, and that 
the caller ceases to exist. That's not so. mergeSort does call "itself", 
but that means there's two active calls now. And when it calls "itself" 
again, there's three. And so on. When an inner call returns, the outer 
one resumes with the next line as usual.


It's not just a list of recursive calls, it's a tree:

mergeSort(0, 3)
mergeSort(0, 1) // line 3
mergeSort(0, 0) // line 3
mergeSort(1, 1) // line 4
merge // line 5
mergeSort(2, 3) // line 4
mergesort(2, 2) // line 3
mergesort(3, 3) // line 4
merge // line 5
merge // line 5


Re: Making sense of recursion

2018-06-25 Thread Colin via Digitalmars-d-learn

On Monday, 25 June 2018 at 17:45:01 UTC, zbr wrote:
Hi, this question is not specifically D related but I'll just 
ask anyway. Consider the following snippet:


[...]


Your mistake is in your visualization :-)

But... more like:

0 < 4 ? true : mergeSort(0,2) && mergeSort(3, 4)
And so on.

I.e, the it's not either or to run the second mergeSort, they 
both happen.


Making sense of recursion

2018-06-25 Thread zbr via Digitalmars-d-learn
Hi, this question is not specifically D related but I'll just ask 
anyway. Consider the following snippet:


void mergeSort(int[] arr, int l, int r)
{
   if (l < r)   // 1
   {
  int m = l+(r-l)/2;// 2
  mergeSort(arr, l, m); // 3
  mergeSort(arr, m+1, r);   // 4
  merge(arr, l, m, r);  // 5
   }// 6
}   // 7

mergeSort(arr, 0, 4);

When I see this, I visualize the recursion to perform this way:

mergeSort(arr, 0, 4):
0 < 4 ? true: mergeSort(0, 2):
0 < 2 ? true: mergeSort(0, 1):
0 < 1 ? true: mergeSort(0, 0):
0 < 0 ? false: //reach the end of mergeSort / 
reach line 6 and then 7


I don't see the computer ever reaching line 4 and 5? Obviously 
I'm wrong but where is my mistake?


Thanks.


Re: foreach / mutating iterator - How to do this?

2018-06-25 Thread H. S. Teoh via Digitalmars-d-learn
On Mon, Jun 25, 2018 at 05:29:23PM +0200, Robert M. Münch via 
Digitalmars-d-learn wrote:
> I have two foreach loops where the inner should change the iterator
> (append new entries) of the outer.
> 
> foreach(a, candidates) {
>   foreach(b, a) {
>   if(...) candidates ~= additionalCandidate;
>   }
> }
> 
> The foreach docs state that the collection must not change during
> iteration.
> 
> So, how to best handle such a situation then? Using a plain for loop?
[...]

Yes.


T

-- 
The fact that anyone still uses AOL shows that even the presence of options 
doesn't stop some people from picking the pessimal one. - Mike Ellis


Re: Code failing unknown reason out of memory, also recursive types

2018-06-25 Thread Mr.Bingo via Digitalmars-d-learn

On Monday, 25 June 2018 at 14:41:28 UTC, rikki cattermole wrote:
Let me get this straight, you decided to max out your memory 
address space /twice over/ before you hit run time, and think 
that this would be a good idea?


Well, that cause was suppose to allocate a dynamic array instead 
of a tuple. Somehow it got reverted. Works when allocating the 
dynamic array.


How bout the compiler predict how big a variable is going to be 
allocated and if it exceeds memory then give an error instead of 
an out of memory error. If it would have gave me a line number I 
would have saw the problem immediately.


Re: overload .

2018-06-25 Thread Mr.Bingo via Digitalmars-d-learn

On Monday, 25 June 2018 at 13:58:54 UTC, aliak wrote:

On Monday, 25 June 2018 at 13:37:01 UTC, Mr.Bingo wrote:


One can overload assignment and dispatch so that something like

A.x = ... is valid when x is not a typical member but gets 
resolved by the above functions.


Therefore, I can create a member for assignment. How can I 
create a member for getting the value?


A.x = 3; // Seems to get translated in to A.opDispatch!("x")(3)

works but

foo(A.x); // fails and the compiler says x does not exist


I need something consistent with opDot. I am trying to create 
"virtual"(not as in function) fields and I can only get 
assignment but not accessor.


A.x is translated in to A.opDispatch!"x" with no args. So I 
guess you can overload or you can static if on a template 
parameter sequence:


import std.stdio;
struct S {
auto opDispatch(string name, Args...)(Args args) {
static if (!Args.length) {
return 3;
} else {
// set something
}
}
}
void main()
{
S s;
s.x = 3;
writeln(s.x);
}

Cheers,
- Ali


Ok, for some reason using two different templated failed but 
combining them in to one passes:


auto opDispatch(string name, T)(T a)
auto opDispatch(string name)()

Maybe it is a bug in the compiler that it only checks one 
opDispatch?






foreach / mutating iterator - How to do this?

2018-06-25 Thread Robert M. Münch via Digitalmars-d-learn
I have two foreach loops where the inner should change the iterator 
(append new entries) of the outer.


foreach(a, candidates) {
foreach(b, a) {
if(...) candidates ~= additionalCandidate;
}
}

The foreach docs state that the collection must not change during iteration.

So, how to best handle such a situation then? Using a plain for loop?

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



Re: template sequence parameters treats member functions differently?

2018-06-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/24/18 5:19 PM, aliak wrote:
Hi, I'm having some issues with template sequence parameters, it seems 
they are not typed as delegates inside a template, but are outside. I.e.


template T(V...) {
     alias T = typeof(&V[0]);
}

struct S { void f() {} }
S s;

pragma(msg, T!(s.f)); // void function()
pragma(msg, typeof(&s.f)); // void delegate()

How come the output is different? Is it supposed to be the same?


No, because the alias is an alias to the function, not the delegate.

The act of taking the address creates the delegate, where the delegate's 
ptr is the context pointer (i.e. s), and the funcptr is the function 
that accepts the pointer (i.e. S.f).


When you pass in s.f to an alias, you are actually passing in S.f. It's 
the fact that you are looking in the *namespace* of s when you do the 
alias. The &s.f is special for the compiler, and can't be deferred to later.


BUT, I'm thinking this may be fixable, as it's inconsistent with inner 
functions:


auto foo(alias x)() { return x(); }

struct S
{
   int bar() { return 42; }

   // int baz() { return foo!bar; } // nope
}

void main()
{
   S s;

   int bar() { return 42; }

   assert(foo!bar() == 42); // ok
   // assert(foo!(s.bar) == 42); // nope

   int baz() { return s.bar; }
   assert(foo!baz() == 42); // ok!
}

I don't see any reason why the alias is to the function and not the 
contexted function. I don't see how it's any different from the ones 
which use inner functions.


-Steve


Re: Code failing unknown reason out of memory, also recursive types

2018-06-25 Thread rikki cattermole via Digitalmars-d-learn
Let me get this straight, you decided to max out your memory address 
space /twice over/ before you hit run time, and think that this would be 
a good idea?


Code failing unknown reason out of memory, also recursive types

2018-06-25 Thread Mr.Bingo via Digitalmars-d-learn

import std.stdio;


union Vector(T, size_t N = size_t.max)
{
	import std.range, std.typecons, std.meta, std.algorithm, 
std.conv, std.math;
	static if (N == size_t.max)		// For size_t.max sets N to be 
infinite/dynamic;

{
mixin("Tuple!("~"T,".repeat(N).join()~") data;");
@property size_t Length() { return rect.length; }

@property double norm(size_t n = 2)()
{
			return (iota(0,data.length).map!(a => 
data[a].pow(n))).pow(1/cast(double)n);

}

}
else
{
mixin("Tuple!("~"T,".repeat(N).join()~") data;");
@property size_t Length() { return N; }


@property double norm(size_t n = 2)()
{
			mixin("return ("~(iota(0,N).map!(a => 
"data["~to!string(a)~"].pow(n)").join("+"))~").pow(1/cast(double)n);");

}

}

auto opDispatch(string s, Args...)(Args v)
if (s.length > 1 && s[0] == 'x')
{
static if (N == size_t.max)
if (data.length < to!int(s[1..$]))
	for(int i = 0; i < to!int(s[1..$]) - data.length; i++) data 
~= 0;


static if (Args.length == 0)
mixin(`return data[`~s[1..$]~`];`);
else static if (Args.length == 1)
mixin(`data[`~s[1..$]~`] = v[0];  `);   

}




alias data this;
}

void main()
{
import std.math, std.variant;

Vector!(Algebraic!(Vector!int, int)) v;
//v.x1 = 3;
//v.x2 = 4;
//v.x3 = 5;
//writeln(v.x3);
//writeln(v.norm);
}

Trying to create a vector of vectors where any entry can be 
another vector of vectors or an int.





Re: overload .

2018-06-25 Thread aliak via Digitalmars-d-learn

On Monday, 25 June 2018 at 13:37:01 UTC, Mr.Bingo wrote:


One can overload assignment and dispatch so that something like

A.x = ... is valid when x is not a typical member but gets 
resolved by the above functions.


Therefore, I can create a member for assignment. How can I 
create a member for getting the value?


A.x = 3; // Seems to get translated in to A.opDispatch!("x")(3)

works but

foo(A.x); // fails and the compiler says x does not exist


I need something consistent with opDot. I am trying to create 
"virtual"(not as in function) fields and I can only get 
assignment but not accessor.


A.x is translated in to A.opDispatch!"x" with no args. So I guess 
you can overload or you can static if on a template parameter 
sequence:


import std.stdio;
struct S {
auto opDispatch(string name, Args...)(Args args) {
static if (!Args.length) {
return 3;
} else {
// set something
}
}
}
void main()
{
S s;
s.x = 3;
writeln(s.x);
}

Cheers,
- Ali


Re: VisualD / fatal error C1905: Front-End and Back-End are not compatible (have to use the same processor)

2018-06-25 Thread Robert M. Münch via Digitalmars-d-learn
With the latest releasae I still have the same problem. I really don't 
have any idea what the cause could be or how to fix it... Anyone?


Viele Grüsse. Robert M. Münch


On 2018-05-21 17:46:45 +, Robert M. Münch said:

A project I can compile via the command line and dub, gives an error in 
VisualD. I created the VisualD configuration through dub:


fatal error C1905: Front-End und Back-End sind nicht kompatibel 
(müssen den gleichenProzessor verwenden).


This translates to: "Front-End and Back-End are not compatible (have to 
use the same processor)"


Well, I don't have a clue what this should mena, nor how this could 
happen. It sounds a bit like if the compiler & linker are not useing 
the same architecture (I want to use x64) but I didn't find any options 
to check/change this.


Any ideas?



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



overload .

2018-06-25 Thread Mr.Bingo via Digitalmars-d-learn



One can overload assignment and dispatch so that something like

A.x = ... is valid when x is not a typical member but gets 
resolved by the above functions.


Therefore, I can create a member for assignment. How can I create 
a member for getting the value?


A.x = 3; // Seems to get translated in to A.opDispatch!("x")(3)

works but

foo(A.x); // fails and the compiler says x does not exist


I need something consistent with opDot. I am trying to create 
"virtual"(not as in function) fields and I can only get 
assignment but not accessor.






Re: Wrapping a forward range in another forward range

2018-06-25 Thread Rudy Raab via Digitalmars-d-learn

On Sunday, 24 June 2018 at 21:28:06 UTC, aliak wrote:

On Sunday, 24 June 2018 at 20:33:32 UTC, Rudy Raab wrote:
So I have an XLSX (MS Excel 2007+ file format) library that I 
wrote  (https://github.com/TransientResponse/dlang-xlsx) that 
I recently converted from std.xml to dxml. That went well and 
it still works (much faster too).


[...]


I think it's the isSomeChar!(ElementType!R), not the 
isRandomAccessRange (because string isSomeString and 
!isSomeChar)?


Cheers,
- Ali


Changing it to isSomeString!(ElementType!R) moves the error to my 
empty() function:

```
source\xlsx.d(205,22): Error: template std.range.primitives.empty 
cannot deduce function from argument types 
!()(XLSheet!(string[])), candidates are:

C:\D\dmd2\windows\bin\..\..\src\phobos\std\range\primitives.d(2090,16):
std.range.primitives.empty(T)(auto ref scope const(T) a) if 
(is(typeof(a.length) : size_t) || isNarrowString!T)
```

I tried implementing a length() function (the number of rows 
remaining in the range, which is known at runtime), but the error 
remains.


Re: Determine if CTFE or RT

2018-06-25 Thread Mr.Bingo via Digitalmars-d-learn

On Monday, 25 June 2018 at 10:49:26 UTC, Simen Kjærås wrote:
On Monday, 25 June 2018 at 09:36:45 UTC, Martin Tschierschke 
wrote:
I am not sure that I understood it right, but there is a way 
to detect the status of a parameter:


My question was different, but I wished to get a ctRegex! or 
regex used depending on the expression:


 import std.regex:replaceAll,ctRegex,regex;

 auto reg(alias var)(){
   static if (__traits(compiles, {enum ctfeFmt = var;}) ){
// "Promotion" to compile time value
enum ctfeReg =  var ;
pragma(msg, "ctRegex used");
return(ctRegex!ctfeReg);

   }else{
return(regex(var));
pragma(msg,"regex used");
}
   }
}
So now I can always use reg!("") and let the compiler 
decide.


To speed up compilation I made an additional switch, that when 
using DMD (for development)

alway the runtime version is used.

The trick is to use the alias var in the declaration and check 
if it can be assigned to enum.
The only thing is now, that you now always use the !() compile 
time parameter to call the function. Even, when in the end is 
translated to an runtime call.


reg!("") and not reg("...").


Now try reg!("prefix" ~ var) or reg!(func(var)). This works in 
some limited cases, but falls apart when you try something more 
involved. It can sorta be coerced into working by passing 
lambdas:



template ctfe(T...) if (T.length == 1) {
import std.traits : isCallable;
static if (isCallable!(T[0])) {
static if (is(typeof({enum a = T[0]();}))) {
enum ctfe = T[0]();
} else {
alias ctfe = T[0];
}
} else {
static if (is(typeof({enum a = T[0];}))) {
enum ctfe = T[0];
} else {
alias ctfe = T[0];
}
}
}

string fun(string s) { return s; }

unittest {
auto a = ctfe!"a";
string b = "a";
auto c = ctfe!"b";
auto d = ctfe!("a" ~ b); // Error: variable b cannot be 
read at compile time

auto e = ctfe!(() => "a" ~ b);
auto f = ctfe!(fun(b)); // Error: variable b cannot be read 
at compile time

auto g = ctfe!(() => fun(b));
}

--
  Simen


This doesn't work, the delegate only hides the error until you 
call it.


auto also does not detect enum. Ideally it should be a manifest 
constant if precomputed... this allows chaining of optimizations.


auto x = 3;
auto y = foo(x);


the compiler realizes x is an enum int and then it can also 
precompute foo(x).


Since it converts to a runtime type immediately it prevents any 
optimizations and template tricks.







Re: Determine if CTFE or RT

2018-06-25 Thread Simen Kjærås via Digitalmars-d-learn
On Monday, 25 June 2018 at 09:36:45 UTC, Martin Tschierschke 
wrote:
I am not sure that I understood it right, but there is a way to 
detect the status of a parameter:


My question was different, but I wished to get a ctRegex! or 
regex used depending on the expression:


 import std.regex:replaceAll,ctRegex,regex;

 auto reg(alias var)(){
   static if (__traits(compiles, {enum ctfeFmt = var;}) ){
// "Promotion" to compile time value
enum ctfeReg =  var ;
pragma(msg, "ctRegex used");
return(ctRegex!ctfeReg);

   }else{
return(regex(var));
pragma(msg,"regex used");
}
   }
}
So now I can always use reg!("") and let the compiler 
decide.


To speed up compilation I made an additional switch, that when 
using DMD (for development)

alway the runtime version is used.

The trick is to use the alias var in the declaration and check 
if it can be assigned to enum.
The only thing is now, that you now always use the !() compile 
time parameter to call the function. Even, when in the end is 
translated to an runtime call.


reg!("") and not reg("...").


Now try reg!("prefix" ~ var) or reg!(func(var)). This works in 
some limited cases, but falls apart when you try something more 
involved. It can sorta be coerced into working by passing lambdas:



template ctfe(T...) if (T.length == 1) {
import std.traits : isCallable;
static if (isCallable!(T[0])) {
static if (is(typeof({enum a = T[0]();}))) {
enum ctfe = T[0]();
} else {
alias ctfe = T[0];
}
} else {
static if (is(typeof({enum a = T[0];}))) {
enum ctfe = T[0];
} else {
alias ctfe = T[0];
}
}
}

string fun(string s) { return s; }

unittest {
auto a = ctfe!"a";
string b = "a";
auto c = ctfe!"b";
auto d = ctfe!("a" ~ b); // Error: variable b cannot be read 
at compile time

auto e = ctfe!(() => "a" ~ b);
auto f = ctfe!(fun(b)); // Error: variable b cannot be read 
at compile time

auto g = ctfe!(() => fun(b));
}

--
  Simen


Re: Determine if CTFE or RT

2018-06-25 Thread ag0aep6g via Digitalmars-d-learn

On 06/25/2018 07:47 AM, Mr.Bingo wrote:
The docs say that CTFE is used only when explicit, I was under the 
impression that it would attempt to optimize functions if they could be 
computed at compile time. The halting problem has nothing to do with 
this. The ctfe engine already complains when one recurses to deep, it is 
not difficult to have a time out function that cancels the computation 
within some user definable time limit... and since fail can simply fall 
through and use the rtfe, it is not a big deal.


The problem then, if D can't arbitrarily use ctfe, means that there 
should be a way to force ctfe optionally!


A D compiler is free to precompute whatever it sees fit, as an 
optimization. It's just not called "CTFE" then, and `__ctfe` will be 
false during that kind of precomputation.


For example, let's try compiling this code based on an earlier example 
of yours:



int main()
{
return foo(3) + foo(8);
}
int foo(int i)
{
   return __ctfe && i == 3 ? 1 : 2;
}


`dmd -O -inline` compiles that to:


 <_Dmain>:
   0:   55  push   rbp
   1:   48 8b ecmovrbp,rsp
   4:   b8 04 00 00 00  moveax,0x4
   9:   5d  poprbp
   a:   c3  ret


As expected, `ldc2 -O` is even smarter:


 <_Dmain>:
   0:   b8 04 00 00 00  moveax,0x4
   5:   c3  ret


Both compilers manage to eliminate the calls to `foo`. They have been 
precomputed. `__ctfe` was false, though, because the term "CTFE" only 
covers the forced/guaranteed kind of precomputation, not the optimization.


Re: Determine if CTFE or RT

2018-06-25 Thread Martin Tschierschke via Digitalmars-d-learn

On Monday, 25 June 2018 at 08:05:53 UTC, Mr.Bingo wrote:

On Monday, 25 June 2018 at 07:02:24 UTC, Jonathan M Davis wrote:
On Monday, June 25, 2018 05:47:30 Mr.Bingo via 
Digitalmars-d-learn wrote:
The problem then, if D can't arbitrarily use ctfe, means that 
there should be a way to force ctfe optionally!


If you want to use CTFE, then give an enum the value of the 
expression you want calculated. If you want to do it in place, 
then use a template such as


template ctfe(alias exp)
{
enum ctfe = exp;
}

so that you get stuff like func(ctfe!(foo(42))). I would be 
extremely surprised if the compiler is ever changed to just 
try CTFE just in case it will work as an optimization. That 
would make it harder for the programmer to understand what's 
going on, and it would balloon compilation times. If you want 
to write up a DIP on the topic and argue for rules on how CTFE 
could and should function with the compiler deciding to try 
CTFE on some basis rather than it only being done when it must 
be done, then you're free to do so.


https://github.com/dlang/DIPs

But I expect that you will be sorely disappointed if you ever 
expect the compiler to start doing CTFE as an optimization. 
It's trivial to trigger it explicitly on your own, and 
compilation time is valued far too much to waste it on 
attempting CTFE when in the vast majority of cases, it's going 
to fail. And it's worked quite well thus far to have it work 
only cases when it's actually needed - especially with how 
easy it is to make arbitrary code run during CTFE simply by 
doing something like using an enum.


- Jonathan M Davis


You still don't get it!

It is not trivial! It is impossible to trigger it! You are 
focused far too much on the optimization side when it is only 
an application that takes advantage of the ability for rtfe to 
become ctfe when told, if it is possible.


I don't know how to make this any simpler, sorry... I guess 
we'll end it here.


I am not sure that I understood it right, but there is a way to 
detect the status of a parameter:


My question was different, but I wished to get a ctRegex! or 
regex used depending on the expression:


 import std.regex:replaceAll,ctRegex,regex;

 auto reg(alias var)(){
   static if (__traits(compiles, {enum ctfeFmt = var;}) ){
// "Promotion" to compile time value
enum ctfeReg =  var ;
pragma(msg, "ctRegex used");
return(ctRegex!ctfeReg);

   }else{
return(regex(var));
pragma(msg,"regex used");
}
   }
}
So now I can always use reg!("") and let the compiler decide.

To speed up compilation I made an additional switch, that when 
using DMD (for development)

alway the runtime version is used.

The trick is to use the alias var in the declaration and check if 
it can be assigned to enum.
The only thing is now, that you now always use the !() compile 
time parameter to call the function. Even, when in the end is 
translated to an runtime call.


reg!("") and not reg("...").







Re: Determine if CTFE or RT

2018-06-25 Thread Mr.Bingo via Digitalmars-d-learn

On Monday, 25 June 2018 at 07:02:24 UTC, Jonathan M Davis wrote:
On Monday, June 25, 2018 05:47:30 Mr.Bingo via 
Digitalmars-d-learn wrote:
The problem then, if D can't arbitrarily use ctfe, means that 
there should be a way to force ctfe optionally!


If you want to use CTFE, then give an enum the value of the 
expression you want calculated. If you want to do it in place, 
then use a template such as


template ctfe(alias exp)
{
enum ctfe = exp;
}

so that you get stuff like func(ctfe!(foo(42))). I would be 
extremely surprised if the compiler is ever changed to just try 
CTFE just in case it will work as an optimization. That would 
make it harder for the programmer to understand what's going 
on, and it would balloon compilation times. If you want to 
write up a DIP on the topic and argue for rules on how CTFE 
could and should function with the compiler deciding to try 
CTFE on some basis rather than it only being done when it must 
be done, then you're free to do so.


https://github.com/dlang/DIPs

But I expect that you will be sorely disappointed if you ever 
expect the compiler to start doing CTFE as an optimization. 
It's trivial to trigger it explicitly on your own, and 
compilation time is valued far too much to waste it on 
attempting CTFE when in the vast majority of cases, it's going 
to fail. And it's worked quite well thus far to have it work 
only cases when it's actually needed - especially with how easy 
it is to make arbitrary code run during CTFE simply by doing 
something like using an enum.


- Jonathan M Davis


You still don't get it!

It is not trivial! It is impossible to trigger it! You are 
focused far too much on the optimization side when it is only an 
application that takes advantage of the ability for rtfe to 
become ctfe when told, if it is possible.


I don't know how to make this any simpler, sorry... I guess we'll 
end it here.


Re: Determine if CTFE or RT

2018-06-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, June 25, 2018 05:47:30 Mr.Bingo via Digitalmars-d-learn wrote:
> The problem then, if D can't arbitrarily use ctfe, means that
> there should be a way to force ctfe optionally!

If you want to use CTFE, then give an enum the value of the expression you
want calculated. If you want to do it in place, then use a template such as

template ctfe(alias exp)
{
enum ctfe = exp;
}

so that you get stuff like func(ctfe!(foo(42))). I would be extremely
surprised if the compiler is ever changed to just try CTFE just in case it
will work as an optimization. That would make it harder for the programmer
to understand what's going on, and it would balloon compilation times. If
you want to write up a DIP on the topic and argue for rules on how CTFE
could and should function with the compiler deciding to try CTFE on some
basis rather than it only being done when it must be done, then you're free
to do so.

https://github.com/dlang/DIPs

But I expect that you will be sorely disappointed if you ever expect the
compiler to start doing CTFE as an optimization. It's trivial to trigger it
explicitly on your own, and compilation time is valued far too much to waste
it on attempting CTFE when in the vast majority of cases, it's going to
fail. And it's worked quite well thus far to have it work only cases when
it's actually needed - especially with how easy it is to make arbitrary code
run during CTFE simply by doing something like using an enum.

- Jonathan M Davis