Re: trick to make throwing method @nogc

2017-02-25 Thread Profile Anaysis via Digitalmars-d-learn

On Saturday, 25 February 2017 at 19:59:29 UTC, ikod wrote:

Hello,

I have a method for range:

struct Range {
immutable(ubyte[]) _buffer;
size_t _pos;

@property void popFront() pure @safe {
enforce(_pos < _buffer.length, "popFront from empty 
buffer");

_pos++;
}
}

I'd like to have @nogc here, but I can't because enforce() is 
non-@nogc.
I have a trick but not sure if it is valid, especially I don't 
know if optimization will preserve code, used for throwing:


import std.string;

struct Range {
immutable(ubyte[]) _buffer;
size_t  _pos;

this(immutable(ubyte[]) s) {
_buffer = s;
}
@property void popFront() pure @safe @nogc {
if (_pos >= _buffer.length ) {
auto _ = _buffer[$]; // throws RangeError
}
_pos++;
}
}

void main() {
auto r = Range("1".representation);
r.popFront();
r.popFront(); // throws
}

Is it ok to use it? Is there any better solution?

Thanks!


You can wrap a gc function in a nogc call using a function 
pointer that casts it to a nogc. You do this first by casting to 
void* then back to the same signature as the function + @nogc. 
This "tricks" the compiler in to calling the gc function from a 
nogc function. The problem is, of course, it is not safe if the 
gc is turned off as it will result in a memory leak. This may or 
may not be an issue with enforce depending on if it allocates 
before or after the check.






Re: simple static if / traits question...

2017-02-23 Thread Profile Anaysis via Digitalmars-d-learn

There are a few options:

1. static if(audio)
2. version(audio)
3. if (audio)

It looks like you are trying to create the version(audio) 
semantic(if exists then use, else don't).


Ultimately, though, if you are trying to make a binary that 
can either use audio or not depending on where it is ran, 
you'll have to stick to using actual run time variables and 
probably be a bit more organized about it.


option 1 is the one I was shooting for. does the static if 
(audio) just check for the existence of audio, or does it also 
check to see if audio is true as well?




Yes, but it checks at compile time. So the code will be evaluated 
by the compiler and if audio is true, it will only compile in the 
code in the if block.


e.g,

static if (audio) { do something }

will be identical, in the binary, to

do something

if audio is true.

The static if is an if statement and works like any ordinary if 
statement, but since you are using static(known at compile time) 
information then static if can actually be computed/evaluated at 
compile time(since all the inputs are know and cannot be changed)




Re: simple static if / traits question...

2017-02-22 Thread Profile Anaysis via Digitalmars-d-learn

On Wednesday, 22 February 2017 at 21:27:47 UTC, WhatMeWorry wrote:



I'm doing conditional compilation using static ifs like so:

enum bool audio   = true;



// if audio flag is present and set to true, add to code build

static if ( (__traits(compiles, audio)) && audio)   

playSound(soundSys, BLEEP );


This works, but I thought there might be a simpler way. For 
instance,

after perusing std.traits, I thought I would find something like
isPresent(audio) or isSymbol(audio) templates.

Or am I being obtuse here?

Thanks.


You do realize that audio is a compile time constant? This means 
that in the binary, everything that depends on it is evaluated(as 
it can be, since it is known). This means that whatever app you 
are using will not be able to be able to "adapt" to the system 
changes. In this case, if the system has audio there is no way 
for the binary to use it because you compiled it out(if audio = 
false).


In such a case you do not want to use a static or compile time 
variable unless you plan on creating multiple binaries.


If your example above was just for demo then yes, you can do that 
but compiles is not what you want. Compiles only checks if the 
statement that follows is compilable as valid D code and it 
doesn't have anything to do with the value of the variables.



There are a few options:

1. static if(audio)
2. version(audio)
3. if (audio)

It looks like you are trying to create the version(audio) 
semantic(if exists then use, else don't).


Ultimately, though, if you are trying to make a binary that can 
either use audio or not depending on where it is ran, you'll have 
to stick to using actual run time variables and probably be a bit 
more organized about it.







Re: scope with if

2017-02-17 Thread Profile Anaysis via Digitalmars-d-learn

On Friday, 17 February 2017 at 20:06:19 UTC, berni wrote:

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.


could be useful to have something like

scope(final)

that would be the "final scope"



Re: Can't iterate over range

2017-02-04 Thread Profile Anaysis via Digitalmars-d-learn

On Saturday, 4 February 2017 at 14:35:37 UTC, ag0aep6g wrote:

On 02/04/2017 12:31 PM, Profile Anaysis wrote:
I am trying to iterate over the combinations of a set using 
the code


https://rosettacode.org/wiki/Power_set#D

I have an array which I call powerSet on and I get a result of
MapResult. I have tried to foreach or front/popFront and even 
each() on
it but I can never get the result as the same array type that 
I started

with.


To create an array from a range, you can use std.array.array:

http://dlang.org/phobos/std_array.html#.array

What is MapResult(the algorithm that generates the result 
lazily?)


Yes, it's a struct that gives you one element at a time, lazily 
generated.



and
how do we easily iterate over the results like we would with 
an array?


foreach and empty/front/popFront should both work. If you can't 
get them to work, show what you tried.


well, I simply took the code from the page I linked and did a 
front() on the MapResult and it say the type was wrong. I thought 
it would give me the type I put in which was an array.


I guess maybe I needed to convert it to an array though... but I 
didn't try. I moved on it iterating over it manually.


someStruct[] X;
someStruct[] x = powerSet(X).popFront();

gave me an error. Was saying I was getting another MapResult, 
which I thought it shouldn't but maybe I just needed to convert 
it to an array.






Can't iterate over range

2017-02-04 Thread Profile Anaysis via Digitalmars-d-learn
I am trying to iterate over the combinations of a set using the 
code


https://rosettacode.org/wiki/Power_set#D

I have an array which I call powerSet on and I get a result of 
MapResult. I have tried to foreach or front/popFront and even 
each() on it but I can never get the result as the same array 
type that I started with.


What is MapResult(the algorithm that generates the result 
lazily?) and how do we easily iterate over the results like we 
would with an array?





module specification for variables

2017-02-04 Thread Profile Anaysis via Digitalmars-d-learn
I'd like to have a global variable in a module but it must be 
accessed by the module name outside of the module.


Sort of like a static variable in a class.

private blocks it completely and public will allow it to be 
imported in to the global scope. Haven't tried protected but I 
assume that is meaningless.


Basically it is a sort of module initialization variable that 
only needs to be set once(usually) outside the module. So I do 
not want it to be imported in to other modules scope in any way, 
ever(there is no need so why create potential issues).


module x;

special int X;  // special = some keyword that makes this work as 
I intend. e.g., "no_import int X;"



module y;

void main()
{
import x;
x.X = 3;
// X = 3; fails.
}


I know you can say that one can used a named import and all that 
but that isn't the point(I want all the other stuff imported as 
it would be)



I could create a static class, for example, and go through 
that... but seems like a hoop to jump through.


Re: Fiber overhead

2017-02-03 Thread Profile Anaysis via Digitalmars-d-learn

On Saturday, 4 February 2017 at 06:54:01 UTC, Ali Çehreli wrote:

On 02/03/2017 08:47 PM, Profile Anaysis wrote:

What is the overhead of using a fiber?


The performance overhead of call() and yield() are comparable 
to function calls because it's simply a few register 
assignments in each case. (Change the stack pointer, etc.)


Memory overhead is memory for call stack, size of which can be 
determined by the programmer.


Ali


Thanks, that was what I was hoping.


Fiber overhead

2017-02-03 Thread Profile Anaysis via Digitalmars-d-learn

What is the overhead of using a fiber?


Re: Yield from function?

2017-01-31 Thread Profile Anaysis via Digitalmars-d-learn

On Tuesday, 31 January 2017 at 11:31:28 UTC, Ali Çehreli wrote:

On 01/31/2017 03:00 AM, Profile Anaysis wrote:

> [...]
[...]
> [...]
return type.

Options:

[...]


Thanks again!


Re: Yield from function?

2017-01-31 Thread Profile Anaysis via Digitalmars-d-learn

On Tuesday, 31 January 2017 at 06:32:02 UTC, Ali Çehreli wrote:

On 01/30/2017 08:12 PM, Profile Anaysis wrote:


import std.stdio, std.concurrency, core.thread;

class Search : Fiber
{
this() { super(); }
int res = 0;
void start()
{
Fiber.yield();
res = 1;
}
}

void main()
{

auto search = new Search();

search.call(); writeln(search.res);
search.call(); writeln(search.res);
search.call(); writeln(search.res); // crashes after 3rd 
call(first

two work fine)
}


That's because the fiber is not in a callable state. (You can 
check with search.state.) Here is one where the fiber function 
lives (too) long:


import std.stdio, std.concurrency, core.thread;

class Search : Fiber
{
this() { super(); }
int res = 0;
void start() {
while (true) {
Fiber.yield();
++res;
}
}
}

void main()
{
auto search = new Search();

foreach (i; 0 .. 5) {
search.call();
writeln(search.res);
}
}

Ali


Just curious, how can I use start() recursively?

I would like to iterate over a recursive structure and yield for 
each "solution". I could use a stack to store the values but the 
whole point of the fiber was to avoid that.



void start() {
   while (true) {
  Fiber.yield();
  ++res;
   }
}


Seems I can't create start with a parameter and non-void return 
type. This seems to make it about useless to use a fiber 
recursively because no pushing and popping on the stack occur.


class Search : Fiber
{
this() { super(); }
bool End = false;

int res = 0;

void start() {
while (!End)
{

int Foo(int x)
{
Fiber.yield();
if (x < 10)
{
res = Foo(x++);
return res;
}
else
return x;

}


}
}


void main()
{

auto search = new Search();
foreach (i; 0 .. 5)
{
 search.call();
 writeln(search.res);
}


search.End = true;
}


My goal is simple, to yield a solution at each step in the 
recursive process.


Maybe I can use another fiber using the lambda syntax?


Re: Yield from function?

2017-01-31 Thread Profile Anaysis via Digitalmars-d-learn

On Tuesday, 31 January 2017 at 06:32:02 UTC, Ali Çehreli wrote:

On 01/30/2017 08:12 PM, Profile Anaysis wrote:

[...]


That's because the fiber is not in a callable state. (You can 
check with search.state.) Here is one where the fiber function 
lives (too) long:


import std.stdio, std.concurrency, core.thread;

class Search : Fiber
{
this() { super(); }
int res = 0;
void start() {
while (true) {
Fiber.yield();
++res;
}
}
}

void main()
{
auto search = new Search();

foreach (i; 0 .. 5) {
search.call();
writeln(search.res);
}
}

Ali


Thanks.


Re: Yield from function?

2017-01-30 Thread Profile Anaysis via Digitalmars-d-learn

On Monday, 30 January 2017 at 18:48:10 UTC, Ali Çehreli wrote:

On 01/30/2017 03:03 AM, Profile Anaysis wrote:
> I need to yield from a complex recursive function too allow
visualizing
> what it is doing.
>
> e.g., if it is a tree searching algorithm, I'd like to yield
for each
> node so that the current state can be shown visually.

I used tree iteration as a Generator example here:

  http://ddili.org/ders/d.en/fibers.html

It's in the code where the function 'byNode' appears. (The 
example builds on an earlier tree iteration code in the same 
chapter.)


Ali


I tried your lambda based fib example and it works as 
expected(using a function)


But when I try the class version it crashes without a call stack 
or any info(somewhere in the fiber module and an access 
violation).


import std.stdio, std.concurrency, core.thread;

class Search : Fiber
{
this() { super(); }
int res = 0;
void start()
{   
Fiber.yield();
res = 1;
}
}

void main()
{

auto search = new Search();

search.call(); writeln(search.res);
search.call(); writeln(search.res);
	search.call(); writeln(search.res); // crashes after 3rd 
call(first two work fine)

}


Any ideas what why it is crashing like this?


Re: Yield from function?

2017-01-30 Thread Profile Anaysis via Digitalmars-d-learn

On Monday, 30 January 2017 at 22:34:11 UTC, TheFlyingFiddle wrote:
On Monday, 30 January 2017 at 11:03:52 UTC, Profile Anaysis 
wrote:
I need to yield from a complex recursive function too allow 
visualizing what it is doing.


e.g., if it is a tree searching algorithm, I'd like to yield 
for each node so that the current state can be shown visually.


I realize that there are several ways to do this but D a yield 
version without additional threads would be optimal. I don't 
need concurrency or speed, just simple.


If you don't want to use fibers then an alternative to yeilds 
is to use callbacks during iteration.


Example:
struct Tree(T)
{
   T value;
   Tree!(T)[] children;
}

void iterDepth(T)(Tree!(T) tree, void delegate(Tree!T) cb)
{
cb(tree);
foreach(child; tree.children)
{
iterDepth(child, cb);
}
}

unittest
{
auto tree = ... //Make the tree somehow
iterDepth(tree, (node)
{
writeln(node.value);
});
}

Callbacks have their set of problems but it's one of the 
simpler ways to do this.


This can't be easily because it requires the callback to contain 
the main program(if it depends on the results). Since I am 
already in a multi-threaded environment it would not be easy to 
marshal the data around.


If I run it in it's own thread then it won't block but seems like 
a lot of work for a simple thing.


Yield from function?

2017-01-30 Thread Profile Anaysis via Digitalmars-d-learn
I need to yield from a complex recursive function too allow 
visualizing what it is doing.


e.g., if it is a tree searching algorithm, I'd like to yield for 
each node so that the current state can be shown visually.


I realize that there are several ways to do this but D a yield 
version without additional threads would be optimal. I don't need 
concurrency or speed, just simple.


Bug in generator

2017-01-30 Thread Profile Anaysis via Digitalmars-d-learn
the code from 
https://dlang.org/library/std/concurrency/generator.html


gives a seg fault at the end.

import std.concurrency;
import std.stdio;


void main()
{
auto tid = spawn(
{
while (true)
{
writeln(receiveOnly!int());
}
});

auto r = new Generator!int(
{
foreach (i; 1 .. 10)
yield(i);
});

foreach (e; r)
{
tid.send(e);
}
}


0x7FF7BDDA05E5 in 
std.concurrency.receiveOnly!int.receiveOnly.__lambda3 at 
\..\..\src\phobos\std\concurrency.d(805)
0x7FF7BDDA1997 in void std.concurrency.Message.map!(pure 
@nogc @safe void 
function(std.concurrency.OwnerTerminated)*).map(pure @nogc @safe 
void function(std.concurrency.OwnerTerminated)*) at 
\..\..\src\phobos\std\concurrency.d(163)
0x7FF7BDDA0B04 in 
D3std11concurrency10MessageBox160__T3getTDFNaNbNiNfiZvTPFNaNiNfC3std11concurrency14LinkTerminatedZvTPFNaNiNfC3std11concurrency15OwnerTerminatedZvTPFS3std7variant18__T8VariantNVmi20Z8VariantNZvZ3getMFDFNaNbNiNfiZvPFNaNiNfC3std11concurrency14LinkTerminatedZvPFNaNiNfC3std11concurrency15OwnerTerminatedZvPFS3std7variant18__T8VariantNVmi20Z8VariantNZvZ13onStandardMsgMFKS3std11concurrency7MessageZb
0x7FF7BDDA0EA0 in 
D3std11concurrency10MessageBox160__T3getTDFNaNbNiNfiZvTPFNaNiNfC3std11concurrency14LinkTerminatedZvTPFNaNiNfC3std11concurrency15OwnerTerminatedZvTPFS3std7variant18__T8VariantNVmi20Z8VariantNZvZ3getMFDFNaNbNiNfiZvPFNaNiNfC3std11concurrency14LinkTerminatedZvPFNaNiNfC3std11concurrency15OwnerTerminatedZvPFS3std7variant18__T8VariantNVmi20Z8VariantNZvZ13onLinkDeadMsgMFKS3std11concurrency7MessageZb at \..\..\src\phobos\std\concurrency.d(1988)
0x7FF7BDDA0F4A in 
D3std11concurrency10MessageBox160__T3getTDFNaNbNiNfiZvTPFNaNiNfC3std11concurrency14LinkTerminatedZvTPFNaNiNfC3std11concurrency15OwnerTerminatedZvTPFS3std7variant18__T8VariantNVmi20Z8VariantNZvZ3getMFDFNaNbNiNfiZvPFNaNiNfC3std11concurrency14LinkTerminatedZvPFNaNiNfC3std11concurrency15OwnerTerminatedZvPFS3std7variant18__T8VariantNVmi20Z8VariantNZvZ12onControlMsgMFKS3std11concurrency7MessageZb at \..\..\src\phobos\std\concurrency.d(2000)
0x7FF7BDDA0FFA in 
D3std11concurrency10MessageBox160__T3getTDFNaNbNiNfiZvTPFNaNiNfC3std11concurrency14LinkTerminatedZvTPFNaNiNfC3std11concurrency15OwnerTerminatedZvTPFS3std7variant18__T8VariantNVmi20Z8VariantNZvZ3getMFDFNaNbNiNfiZvPFNaNiNfC3std11concurrency14LinkTerminatedZvPFNaNiNfC3std11concurrency15OwnerTerminatedZvPFS3std7variant18__T8VariantNVmi20Z8VariantNZvZ4scanMFKS3std11concurrency36__T4ListTS3std11concurrency7MessageZ4ListZb at \..\..\src\phobos\std\concurrency.d(2016)
0x7FF7BDDA094C in bool std.concurrency.MessageBox.get!(pure 
nothrow @nogc @safe void delegate(int), pure @nogc @safe void 
function(std.concurrency.LinkTerminated)*, pure @nogc @safe void 
function(std.concurrency.OwnerTerminated)*, void 
function(std.variant.VariantN!(20uL).VariantN)*).get(pure nothrow 
@nogc @safe void delegate(int), pure @nogc @safe void 
function(std.concurrency.LinkTerminated)*, pure @nogc @safe void 
function(std.concurrency.OwnerTerminated)*, void 
function(std.variant.VariantN!(20uL).VariantN)*) at 
\..\..\src\phobos\std\concurrency.d(2115)
0x7FF7BDDA0579 in std.concurrency.receiveOnly!int.receiveOnly 
at \..\..\src\phobos\std\concurrency.d(806)

0x7FF7BDD9F50D in main.main.__lambda1 at main.d(82)
0x7FF7BDDA46C2 in std.concurrency._spawn!(void 
function())._spawn.exec at 
\..\..\src\phobos\std\concurrency.d(538)

0x7FF7BDDE9302 in void core.thread.Thread.run()
0x7FF7BDDD5CBD in thread_entryPoint
0x7FF7BDE5D96D in thread_start__ptr64)> at 
d:\th\minkernel\crts\ucrt\src\appcrt\startup\thread.cpp(115)

0x7FF9EB178364 in BaseThreadInitThunk
0x7FF9EBD570D1 in RtlUserThreadStart


Also, if one tries to create a global generator an error about 
PAGESIZE not being a compile time value is given.




Min, max of enum

2017-01-25 Thread Profile Anaysis via Digitalmars-d-learn
Since we do not have attributes for enums, I use _ in front of 
the names for meta values.


I need to get the non-meta values for the enum so I can iterate 
over it and use it properly.


enum myEnum
{
_Meta1 = 0,
A,B,C,
_Meta3 = 43,
D = 3,
}

The num, for all practical purposes does not contain _Meta1, 
and_Meta3. But in code I use to!myEnum(intI) and having the meta 
values complicate things(simple shifting may or may not work).


I also need to create array indexers based on myEnum that don't 
include the meta characters.


What I do a lot is convert integers in to fields of the enum.

If I do not include any Meta, then it is straight forward 
to!myEnum(i), but with them it is not, so doing things like


int[myEnum] x;

x[to!myEnum(i))] is difficult because the conversion will be 
invalid for meta. I'd have to do some work on i to get the 0-n 
representation to map properly in to the enum... basically 
avoiding the meta fields.


This would all be solved with attributes for enums, but that, I 
suppose is a pipe dream.


Any ideas how I can make this easy?






Re: Trying to understand multidimensional arrays in D

2017-01-25 Thread Profile Anaysis via Digitalmars-d-learn
On Thursday, 26 January 2017 at 03:02:32 UTC, Jonathan M Davis 
wrote:
On Thursday, January 26, 2017 01:47:53 Profile Anaysis via 
Digitalmars-d- learn wrote:

 [...]


Like in C/C++, types are mostly read outward from the variable 
name in D. In both C/C++ and D,


[...]


Actually, I think the notation is simply wrong.


// Matrix order testing
auto x = new int[][][][](1,2,3,4);
auto y = new int[1][2][][](3,4);

for(int i = 0; i < 1; i++)
for(int j = 0; j < 2; j++)
for(int k = 0; k < 3; k++)
for(int l = 0; l < 4; l++)   
{
x[i][j][k][l] = i*j*k*l;
//x[l][k][j][i] = i*j*k*l;

//y[i][j][k][l] = i*j*k*l;
//y[l][k][j][i] = i*j*k*l;
y[k][l][j][i] = i*j*k*l;
}


It is inconsistent with dynamic arrays and mixing them creates a 
mess in the order of indices.


I best someone was asleep at the wheel when programming the code 
for static arrays. (probably someone different than who 
programmed the dynamic arrays)


This is a bug IMO.(unfortunately one that can't be fixed ;/)




Re: Trying to understand multidimensional arrays in D

2017-01-25 Thread Profile Anaysis via Digitalmars-d-learn
On Thursday, 26 January 2017 at 03:02:32 UTC, Jonathan M Davis 
wrote:
On Thursday, January 26, 2017 01:47:53 Profile Anaysis via 
Digitalmars-d- learn wrote:

 [...]


Like in C/C++, types are mostly read outward from the variable 
name in D. In both C/C++ and D,


[...]


Thanks. I'll just have to play around with them a bit until it 
sinks in. I think my problem was declaring them wrong which would 
always lead to weird errors.


I am using static arrays because the size of the matrix is fixed. 
I need to allocate them though because that is what my 
matrix_history contains.


I guess I can do that with new int[n][n] type of thing? (I think 
I tried that before.


Anyways, probably would work fine now but I already move don to 
wrapping it in a struct. It provides more flexibility in my case.





Re: Trying to understand multidimensional arrays in D

2017-01-25 Thread Profile Anaysis via Digitalmars-d-learn

On Thursday, 26 January 2017 at 02:29:07 UTC, Ivan Kazmenko wrote:
On Thursday, 26 January 2017 at 01:47:53 UTC, Profile Anaysis 
wrote:

does this mean that have

int[][4][4] matrix_history;

backwards?

int[4][4][] matrix_history;

this creates even a more set of problems.


In short, you are right, `int[4][4][]` is a dynamic array of 
`int[4][4]`.  In turn, `int[4][4]` is a static length-4 array 
of `int[4]`, and that is a static length-4 array of `int`.  
It's quite logical once you learn how to read it: if T is a 
type, then T[] is a dynamic array of that type, and T[4] is a 
static length-4 array of that type.


So, if I have `int[2][5][7] a;` somewhere, the very last 
element is `a[6][4][1]`.  If you are inclined to think in terms 
of this difference, the simple rule of thumb would be that the 
order of dimensions in the declaration is reversed.


Thanks, knowing the last element is important ; Basically I just 
need to know the proper index. For me, having the array declared 
in symbolic form that matches the indexing, like in C/C++, is 
quicker, easier to remember, and harder to forget. I don't really 
care too much beyond that. They could be declared any way... but 
I find myself getting confused in D because of little things like 
this that don't carry over while almost everything else is.



Also, note that if you want to have, for example, a dynamic 
array of 5 dynamic arrays of the same length 7 (modeling a C 
rectangular array, or a D static array, but with possibility to 
change the length of each row, as well as the number of rows), 
you would go with

`auto a = new int [] [] (5, 7);` (initialization)
The static array of 5 static arrays of length 7 is still
`int [7] [5] a;` (type declaration)
So the reverse only happens in type declarations.




(On the contrary, declarations in C or C++ looks rather 
unintuitive from this perspective: `T a[4][5][6]` is means that 
`a` is an array of 4 arrays of 5 arrays of 6 arrays of `T`.  
Note how we have to read left-to-right but then wrap around the 
string to get the meaning.)


lol, I don' tknow what the last sentence means. wrap around the 
string? Do you mean look at the variable?


For me the interpretation above is the most logical because it is 
a sequential operation in my mind, if you will. x of y of z and 
the chain can be cut off anywhere and the interpretation still be 
the same.


Since I am a native speaker of English, which is a left to right 
language, it just makes sense. I, am, of coursed biased because I 
started with C/C++ rather than D.




Additionally, reading about various kinds of arrays in D might 
help:

https://dlang.org/spec/arrays.html

And more in-depth material about array slicing:
http://dlang.org/d-array-article.html

Ivan Kazmenko.





Trying to understand multidimensional arrays in D

2017-01-25 Thread Profile Anaysis via Digitalmars-d-learn

I'm a bit confused by how D does arrays.

I would like to create a array of matrices but I do not seem to 
get the correct behavior:


int[][4][4] matrix_history;

What I would like is to have a 4x4 matrix and have a history of 
it. Just n 4x4 matrices but each matrix is a fixed size but there 
can be an arbitrary(dynamic) number.


I would like, for example,

matrix_history[0] to be the first 4x4 matrix,
matrix_history[1] to be the second 4x4 matrix,
...

and I would, in fact, like to be able to append a matrix like

matrix_history ~= some_4x4matrix.

I try to assign like

matrix_history[total-1] = new int[][](8,8);

or append

matrix_history ~= new int[][](4,4);

but the append fails with

Error: cannot append type int[][] to type int[][4][4]

which is confusing because the type per entry in the matrix 
history is of type int[][].


e.g., I could wrap the int[][] in a struct and then just have a 
singular array of these matrices and, to me, the logic should be 
the same. e.g.,


struct matrix
{
int[4][4] data;
}

then

matrix[] matrix_history.

and

matrix_history ~= new matrix;

so, the logic should be the same between two. This method works 
but the more direct method doesn't seem to.


If I do

auto x = matrix_history[0];

x is not a int[4][4] but of type int[4](as reported by the 
debugger), which is very confusing.


it seems that the way D indexes multidimensional arrays is not 
logical nor consistent from my perspective.


auto x = matrix_history[0] returns an array of size 4.
auto x = matrix_history[0][0] returns an 2d array of size 4x4.
auto x = matrix_history[0][0][0] returns an int(as expected).


does this mean that have

int[][4][4] matrix_history;

backwards?

int[4][4][] matrix_history;

this creates even a more set of problems.

I guess I will have to revert to wrapping the matrix in a struct 
to get the natural extension of single arrays unless someone can 
clue me in on what is going on.






Can compiler profile itself?

2017-01-24 Thread Profile Anaysis via Digitalmars-d-learn
I am trying to compile some code and it takes around 6 seconds. 
Even if I change one line in one module, it takes the same time. 
There are about 20 different d modules.


I used to get around 1-2 second compile times several months ago 
on different projects.


I did upgrade a few things and it seems that something has made 
things slow.


Can we ask the compiler what seems to be taking the most time(a 
module, a template, etc...)?


If the compiler can profile itself then it would be very easy to 
figure out what is slowing things down in compilation.


I feel that I should be able to compile all the modules 
separately and only have to recompile the module that I 
changed... and that it should be quite fast(e.g., if the module 
contains nothing but the main and a write statement, regardless 
of all the other stuff in the project, I'd expect that to be 
fast).


For example, If I do the

import std.stdio;

int main(string[] argv)
{
writeln("Hello D-World!");
return 0;
}

it takes <1s.

Yet if I import a bunch of modules it takes 6+s and the time 
never reduces on subsequent builds.


I am using Visual D.

Visual D has a separate compile and link feature but when I try 
it for dmdx64 I get


Internal error: backend\mscoffobj.c 2016

It does work for x32 but the speed does not change.

I'm convinved that dmd is recompiling everything each time... and 
this doesn't seem very fast IMO when less than 0.1% of the 
project has changed.










Re: Is it possible to "cache" results of compile-time executions between compiles?

2017-01-24 Thread Profile Anaysis via Digitalmars-d-learn
On Tuesday, 24 January 2017 at 21:36:50 UTC, Profile Anaysis 
wrote:

...


Maybe with all this talk of the new CTFE engine being developed, 
a similar mechanism can be used optionally? This could help with 
debugging also.


In debug mode, the cfte mixin's are written to disk with hash, if 
they are not a string themselves. (could be done with all cfte's, 
I suppose, but not sure about performance and consistency)


Then debuggers can use the outputed cfte's for proper analysis, 
line breaking, etc...












Re: Is it possible to "cache" results of compile-time executions between compiles?

2017-01-24 Thread Profile Anaysis via Digitalmars-d-learn
On Tuesday, 24 January 2017 at 16:49:03 UTC, TheFlyingFiddle 
wrote:
On Tuesday, 24 January 2017 at 16:41:13 UTC, TheFlyingFiddle 
wrote:

Everything turned out s much better than expected :)
Added bonus is that mixin output can be viewed in the generated 
files :D


Could you post your solution?

I suggest we get a real caching module like above that has the 
extra feature of hashing the mixin strings.


This way the caching mechanism can validate if the mixin strings 
have changed. Put the hash in a comment in the output file that 
used to test if the input string has the same hash. If it does, 
simply use the output file, else, regenerate.


Adds some overhead but keeps things consistent.


(Since I'm not sure what Cache!() is, I'm assuming it doesn't do 
this)