Re: Min, max of enum

2017-01-25 Thread Stefan Koch via Digitalmars-d-learn
On Thursday, 26 January 2017 at 05:58:26 UTC, Profile Anaysis 
wrote:
Since we do not have attributes for enums, I use _ in front of 
the names for meta values.


[...]


This can be done with Ctfe mixins and __traits,

look at __traits(allMembers)


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.





Re: Are there plans to make mono D work with current version?

2017-01-25 Thread evilrat via Digitalmars-d-learn

On Thursday, 26 January 2017 at 01:58:51 UTC, Adam Wilson wrote:


I'd recommend VSCode with Code-D works very well for me.

https://github.com/Pure-D/code-d


And with Microsoft C++ tools (ms-vscode.cpptools) it can debug D 
too with x64 or -m32mscoff


Re: Trying to understand multidimensional arrays in D

2017-01-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, January 26, 2017 01:47:53 Profile Anaysis via Digitalmars-d-
learn wrote:
> 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;

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

int* foo;

is a pointer to an int. It's read outward from the variable name, so you get
the pointer and then what it points to. Similarly,

int** foo;

is a pointer to a pointer to an int. In C/C++, a static array would be
written like

int arr[4][3];

and again, it's read outward from the type. It's a static array of 4 static
arrays of 3 ints. This gets increasingly confusing as the types get more
complicated, but it's critical for understanding how function pointers are
written in C/C++. For D, it's a lot less critical, because we have a cleaner
function pointer declaration syntax, but the same basic rules mostly apply
(const, immutable, and shared is where they start breaking the rules a bit,
but they're pretty straightforward and consistent with just pointers and
arrays). That

int arr[4][3];

in C/C++ can then be accessed like so

arr[3][2] = 5;

and that would get the 3rd element in the first array and the second element
in the second array without exceeding the bounds of the array. D follows the
same declaration rules except that it has the array bounds all on the
left-hand side of the variable. So, in C/C++, you have

int arr[4][3];

whereas in D, the same array would be

int[3][4] arr;

and you would still access it like so

arr[3][2] = 5;

without exceeding the bounds of the array, whereas

arr[2][3] = 5;

_would_ exceed the bounds of the array, because the second array has 3
elements in it, and that asks for the 4th.

This tends to be very confusing at first, because most folks usually expect
the indices to always in the same order, when they're not. They are so long
as the sizes is always on the right-hand side, which occurs with dynamic
arrays, but in D, static arrays go on the left. C/C++ would have the exact
same ordering problem as D if it put the sizes on the left, because it uses
basically the same rules for how types are written. But they put it on the
right, separating from the type, which makes the indices clearer but splits
the type in two. So, both approaches have their pros and cons.

In any case, the idea that the type is read outward from the variable name
extends to types in general. In particular, if you have

int[][4][4] arr;

as in your example, you have a static array of 4 static arrays of 4 dynamic
arrays of int. You can append to the innermost static array

arr[3][3] ~= [1, 2, 3];

but you can't append to arr. If you want a dynamic array of static arrays,
then you need to do

int[4][4][] arr;

Then you can append a 4x4 static array to arr. However, your attempts at
creating a static array were not actually creating static arrays.

auto arr = new int[4];

and

auto arr = new int[](4);

both allocate a dynamic array of length 4. The code semantics are identical.
However, once we go beyond one dimension, it starts mattering - and getting
confusing. Take this

auto arr = new int[][](4, 5);
static assert(is(typeof(arr) == int[][]));
assert(arr.length == 4);

arr is a dynamic array of length 4 that contains dynamic arrays of length 5
of int. This on the other hand

auto arr = new int[4][](5);
static assert(is(typeof(arr) == int[4][]));
assert(arr.length == 5);

makes it so that arr is dynamic array of length 5 that contains static
arrays of length 4 of int.

auto arr = new int[4][5];
static assert(is(typeof(arr) == int[4][]));
assert(arr.length == 5);

has the exact same semantics. So, the right-most number is always the length
of the outer, dynamic array, and whether the interior is more dynamic arrays
or static arrays depends on whether the numbers are between the brackets or
the parens.

Another thing to note is that when you have int[][], it is a dynamic array,
whereas int[4][4] is a static array. So, whenever you see the compiler give
you the type int[][], it's talking about a dynamic array, not a static
array. The numbers have to be there for it to be a static array. When
looking at the type of an array (as opposed to a expression using new),
numbers between the subscripts mean a static array, whereas a lack of
numbers means a dynamic array, and the type of a dynamic array does not
change depending on its length.

Also, even if you had declared matrix_history correctly

int[4][4][] matrix_history;

this code would be wrong

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

because int[][](4, 4) is allocating a dynamic array of dynamic arrays of
ints, not a static array of 4 static arrays of 4 ints.

In addition, AFAIK, you can't just new up a static array of 4 static arrays
of int. You can new up dynamic arrays but not static arrays. The static
arrays need to be in something to be on the heap. But that's not really what
you wanted 

Re: Trying to understand multidimensional arrays in D

2017-01-25 Thread Ivan Kazmenko via Digitalmars-d-learn
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.


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.)


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.



How does cast(SomeObj) (cast(void*) ptrFromC) work?

2017-01-25 Thread David Zhang via Digitalmars-d-learn
I was trying to figure out why calling an object's function from 
a wndProc that modified the object's state didn't actually change 
anything. Wrapping the GetWindowLongPtr in a cast(void*) seems to 
make it work. What am I missing about this? I though that object 
references were really just pointers with special 
restrictions/behaviors?


Old:
window = cast(Win32Window) GetWindowLongPtr(hwnd, 
GWLP_USERDATA);


New:
window = cast(Win32Window) (cast(void*) 
GetWindowLongPtr(hwnd, GWLP_USERDATA));


Re: Are there plans to make mono D work with current version?

2017-01-25 Thread Adam Wilson via Digitalmars-d-learn

On 1/25/17 5:22 PM, Lucas wrote:

On Wednesday, 25 January 2017 at 23:00:05 UTC, James Buren wrote:

On Wednesday, 25 January 2017 at 22:37:30 UTC, Lucas wrote:

[...]


Most likely, you are dealing with this issue:
https://github.com/aBothe/Mono-D/issues/648

MonoDevelop 5.x is the latest version supported. They haven't gotten
around to making it compatible with anything newer due to various
reasons, mainly it being that MonoDevelop has  completed changed the
plugin API again.

If you really need Mono-D, you are stuck with MonoDevelop 5.x for now.


Too bad. What are the D IDE options currently? I might just downgrade to
MonoDevelop 5.x


I'd recommend VSCode with Code-D works very well for me.

https://github.com/Pure-D/code-d

--
Adam Wilson
IRC: LightBender
import quiet.dlang.dev;


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.






Re: Are there plans to make mono D work with current version?

2017-01-25 Thread Lucas via Digitalmars-d-learn

On Wednesday, 25 January 2017 at 23:00:05 UTC, James Buren wrote:

On Wednesday, 25 January 2017 at 22:37:30 UTC, Lucas wrote:

[...]


Most likely, you are dealing with this issue: 
https://github.com/aBothe/Mono-D/issues/648


MonoDevelop 5.x is the latest version supported. They haven't 
gotten around to making it compatible with anything newer due 
to various reasons, mainly it being that MonoDevelop has  
completed changed the plugin API again.


If you really need Mono-D, you are stuck with MonoDevelop 5.x 
for now.


Too bad. What are the D IDE options currently? I might just 
downgrade to MonoDevelop 5.x


Re: Why is [0] @safer than array.ptr?

2017-01-25 Thread Jerry via Digitalmars-d-learn
On Tuesday, 24 January 2017 at 12:01:35 UTC, Jonathan M Davis 
wrote:
So, while it makes sense to say that .ptr can't be used in 
@safe code, it really doesn't make sense to suggest [0] as 
an alternative.


- Jonathan M Davis


Sure I see your point. But I feel like deprecations should also 
list what one can do instead. So in that regard the suggestion 
makes sense.






Re: Why is [0] @safer than array.ptr?

2017-01-25 Thread David Nadlinger via Digitalmars-d-learn
On Wednesday, 25 January 2017 at 22:59:55 UTC, Jonathan M Davis 
wrote:
Yes, but my point is that you're normally only going to use 
.ptr to pass something to a C function, and even if you're 
doing more with it in D, odds are, you're going to be doing 
pointer arithmetic.


Wrong again. If this were the case, we wouldn't have needed to 
make it a deprecation at all, since all uses would have been 
mistakes. A non-negligible amount of real-world D code actually 
uses single-object pointers. Look up the change history if you 
are interested – and indeed, making sure one understands the 
topic sufficiently well to meaningfully contribute before typing 
out a wall-length sermon would collectively save us a good chunk 
of time.


And when you combine it with marking C function @trusted, this 
is actually pretty bad.


Ex falso quodlibet – once you have a piece of code mistakenly 
marked @trusted, all guarantees are out of the window even 
without suspicious-looking client code. @safe-ty is about 
mechanically verifiable code, not faith-based programming.


 — David




Re: Why is [0] @safer than array.ptr?

2017-01-25 Thread Adam D. Ruppe via Digitalmars-d-learn
On Wednesday, 25 January 2017 at 23:09:11 UTC, David Nadlinger 
wrote:

This is a fallacy:


Ah, yes indeed, that was mentioned earlier in the thread too, it 
just slipped my mind again.


Re: Why is [0] @safer than array.ptr?

2017-01-25 Thread David Nadlinger via Digitalmars-d-learn
On Wednesday, 25 January 2017 at 22:54:32 UTC, Adam D. Ruppe 
wrote:
On Wednesday, 25 January 2017 at 22:46:10 UTC, David Nadlinger 
wrote:

This is because every pointer in SafeD is dereferencable.


But null pointers are allowed in SafeD and arr.ptr is either 
arr[0] or null


This is a fallacy:

---
@safe: // Deprecated, though.

ubyte oops(ubyte[] b) {
return *b.ptr;
}

void main() {
oops(new ubyte[0]);
// - or -
auto b = new ubyte[42];
oops(b[$ .. $]);
}
---

 — David


Re: Why is [0] @safer than array.ptr?

2017-01-25 Thread David Nadlinger via Digitalmars-d-learn
On Wednesday, 25 January 2017 at 18:12:18 UTC, Jonathan M Davis 
wrote:
Fine, but in the vast majority of cases, you're calling .ptr, 
because you're going to be passing the pointer to C code, in 
which case, doing [0] buys you very little, since the C 
code is inevitably going to be reading more than that one 
element,


In that case, calling the C function isn't going to be @safe 
anyway, so you might as well use .ptr.


So, telling the programmer to use [0] instead of arr.ptr is 
just plain bizarre.


What you call bizarre is a simple, actionable explanation (which 
is especially important as the behaviour was necessarily a 
backwards-incompatible change). If [0] doesn't actually apply 
to your code, then it was mistakenly @safe before.


 — David


Re: Are there plans to make mono D work with current version?

2017-01-25 Thread James Buren via Digitalmars-d-learn

On Wednesday, 25 January 2017 at 22:37:30 UTC, Lucas wrote:
Looking forward to get back to programming in D, I went to set 
up to my favorite environment: Mono D. After lots of download, 
Mono, Gtk#, MSBuild tools, VS 13 commnunity... I get an error 
saying it won't load my D language binding because my current 
Mono version is higher than D language binding's supports.


Are there any plans to make it work in the current version or 
any workaround or should I really downgrade everything?


I'm asking this here because it's likely to the author of the 
mono D read that forum (thank you very much for the extension, 
by the way)


Most likely, you are dealing with this issue: 
https://github.com/aBothe/Mono-D/issues/648


MonoDevelop 5.x is the latest version supported. They haven't 
gotten around to making it compatible with anything newer due to 
various reasons, mainly it being that MonoDevelop has  completed 
changed the plugin API again.


If you really need Mono-D, you are stuck with MonoDevelop 5.x for 
now.




Re: Why is [0] @safer than array.ptr?

2017-01-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, January 25, 2017 22:46:10 David Nadlinger via Digitalmars-d-
learn wrote:
> On Tuesday, 24 January 2017 at 11:38:16 UTC, Jonathan M Davis
>
> wrote:
> > It seems _slightly_ better from a safety perspective but only
> > slightly.
>
> Wrong – one is correct, the other is not. This is because every
> pointer in SafeD is dereferencable. Pointer arithmetic is not
> allowed in SafeD, so your concerns about reading from other
> memory do not apply.

Yes, but my point is that you're normally only going to use .ptr to pass
something to a C function, and even if you're doing more with it in D, odds
are, you're going to be doing pointer arithmetic. All [0] does over
arr.ptr is check the first element. It makes it @safe, but then everything
else you're going to be doing after that almost certainly won't be @safe.
And when you combine it with marking C function @trusted, this is actually
pretty bad. It makes it trivial to do something like

extern(C) int cFunc(int* ptr, size_t length) @trusted;

auto result = cFunc([0], 12);

and have it be considered @safe, when it's not @safe at all. Now, most code
would then do

auto result = cFunc([0], arr.length);

so in practice, it won't usally be a problem, but it makes it easy to have
code treated like it's completely @safe when in fact it isn't. Now, really,
the fix there is to not mark the C function as @trusted and require that the
caller make sure they pass in arguments that are @safe, but at least if they
were doing

auto result = cFunc(arr.ptr, arr.length);

the compiler would have caught that it was @system even with the C function
being marked as @trusted, whereas if you do [0], it wouldn't.

So, yes, if all you're planning to do is look at the pointer to the first
element in the array, then [0] is safer, but odds are quite low that
that's actually what you're going to do, and in all of the other cases, you
might as well just use .ptr. So, telling folks to go use [0] instead of
.ptr doesn't seem very helpful to me.

- Jonathan M Davis




Re: Why is [0] @safer than array.ptr?

2017-01-25 Thread Adam D. Ruppe via Digitalmars-d-learn
On Wednesday, 25 January 2017 at 22:46:10 UTC, David Nadlinger 
wrote:

This is because every pointer in SafeD is dereferencable.


But null pointers are allowed in SafeD and arr.ptr is either 
arr[0] or null




Re: Why is [0] @safer than array.ptr?

2017-01-25 Thread David Nadlinger via Digitalmars-d-learn
On Tuesday, 24 January 2017 at 11:38:16 UTC, Jonathan M Davis 
wrote:
It seems _slightly_ better from a safety perspective but only 
slightly.


Wrong – one is correct, the other is not. This is because every 
pointer in SafeD is dereferencable. Pointer arithmetic is not 
allowed in SafeD, so your concerns about reading from other 
memory do not apply.


 — David


Are there plans to make mono D work with current version?

2017-01-25 Thread Lucas via Digitalmars-d-learn
Looking forward to get back to programming in D, I went to set up 
to my favorite environment: Mono D. After lots of download, Mono, 
Gtk#, MSBuild tools, VS 13 commnunity... I get an error saying it 
won't load my D language binding because my current Mono version 
is higher than D language binding's supports.


Are there any plans to make it work in the current version or any 
workaround or should I really downgrade everything?


I'm asking this here because it's likely to the author of the 
mono D read that forum (thank you very much for the extension, by 
the way)


Re: returning 'ref inout(T)' - not an lvalue?

2017-01-25 Thread bitwise via Digitalmars-d-learn
On Wednesday, 25 January 2017 at 21:04:50 UTC, Adam D. Ruppe 
wrote:

On Wednesday, 25 January 2017 at 20:42:52 UTC, bitwise wrote:

Is it not possible to return a ref from an inout function?


It isn't the inout that's getting you, it is the const object 
in main().


const(List!int) c;

Make that mutable and it works. Why? Cuz the `C list` in the 
iterator keeps that const with it I'm not sure why that 
kills it though, the error tells me it is an internal cast that 
is breaking things but I don't see why that logically would.


This was intentional, because I thought that due to transitivity, 
'alias T' would also be const, and opIndex would return const(T) 
when created from a const(List!T).


I just tried the following though, and it outputs 'int' rather 
than 'const(T)' for a const(List!T):


alias T = typeof(list.data[0]);
pragma(msg, T.stringof);

This is not what I thought would happen.

I actually changed it up like this, and things seem to work:

alias T = CopyTypeQualifiers!(C, typeof(list.data[0]));

ref inout(T) opIndex(int i) inout{
return list.data[pos + i];
}

This might arguably be a bug, but you could work around it by 
checking for that const This and offering a different method 
that just returns const instead of ref.


Given what the solution was, I think the error message could be 
improved, but I'm not sure what the right approach would be.



T[] data = new T[1];


BTW what do you think this line does? I ask because most people 
who use it don't get what they expect out of it


Should be an array of 'T' with all elements set to T.init right?
This was just an example - for some reason, I thought it would 
make things clearer.


  Thanks



Re: returning 'ref inout(T)' - not an lvalue?

2017-01-25 Thread Adam D. Ruppe via Digitalmars-d-learn

On Wednesday, 25 January 2017 at 20:42:52 UTC, bitwise wrote:

Is it not possible to return a ref from an inout function?


It isn't the inout that's getting you, it is the const object in 
main().


const(List!int) c;

Make that mutable and it works. Why? Cuz the `C list` in the 
iterator keeps that const with it I'm not sure why that kills 
it though, the error tells me it is an internal cast that is 
breaking things but I don't see why that logically would.


This might arguably be a bug, but you could work around it by 
checking for that const This and offering a different method that 
just returns const instead of ref.



T[] data = new T[1];


BTW what do you think this line does? I ask because most people 
who use it don't get what they expect out of it


Re: Safely moving structs in D

2017-01-25 Thread bitwise via Digitalmars-d-learn
On Tuesday, 24 January 2017 at 11:46:47 UTC, Jonathan M Davis 
wrote:
On Monday, January 23, 2017 22:26:58 bitwise via 
Digitalmars-d-learn wrote:

[...]


Moving structs is fine. The postblit constructor is for when 
they're copied. A copy is unnecessary if the original isn't 
around anymore - e.g. passing an rvalue to a function can move 
the value; it doesn't need to copy it. Even passing an lvalue 
doesn't need to result in a copy if the lvalue is not 
referenced at any point after that function call. However, if 
you're going to end up with two distinct copies, then they need 
to actually be copies, and a postblit constructor will be 
called.


[...]


Awesome, thanks - this makes sense.


returning 'ref inout(T)' - not an lvalue?

2017-01-25 Thread bitwise via Digitalmars-d-learn

Compiling the code below gives these errors:

main.d(92): Error: 
cast(inout(int))this.list.data[cast(uint)(this.pos + i)] is not 
an lvalue
main.d(101): Error: template instance 
main.Iterator!(const(List!int)) error instantiating

main.d(108): instantiated from here: first!(const(List!int))

struct Iterator(C)
{
C list;
int pos;

alias T = typeof(list.data[0]);

this(C list, int pos) {
this.list = list;
this.pos = pos;
}

ref inout(T) opIndex(int i) inout {
return list.data[pos + i];
}
}

class List(T)
{
T[] data = new T[1];

auto first(this This)() {
return Iterator!This(this, 0);
}
}

int main(string[] argv)
{
const(List!int) c;
auto it = c.first;
}

Is it not possible to return a ref from an inout function?




Re: Why is [0] @safer than array.ptr?

2017-01-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, January 25, 2017 10:52:51 Kagamin via Digitalmars-d-learn 
wrote:
> On Tuesday, 24 January 2017 at 12:01:35 UTC, Jonathan M Davis
>
> wrote:
> > So, while it makes sense to say that .ptr can't be used in
> > @safe code, it really doesn't make sense to suggest [0] as
> > an alternative.
>
> When you ensure pointers point to existing data, you can
> dereference them in safe code, otherwise you can't.

Fine, but in the vast majority of cases, you're calling .ptr, because you're
going to be passing the pointer to C code, in which case, doing [0] buys
you very little, since the C code is inevitably going to be reading more
than that one element, and [0] hasn't verified anything beyond the first
element. So, telling the programmer to use [0] instead of arr.ptr is
just plain bizarre. Doing [0] makes sense when you're just going to be
messing with that one element in D code, but that's pretty much it.
Otherwise, you might as well just use arr.ptr, because it's up to the
programmer to verify the @safety of what's going on at that point anyway.

- Jonathan M Davis



Re: Learning resources

2017-01-25 Thread Dlearner via Digitalmars-d-learn

On Tuesday, 24 January 2017 at 22:53:14 UTC, bachmeier wrote:

On Tuesday, 24 January 2017 at 20:15:38 UTC, Dlearner wrote:

[...]


This sounds like exactly what you want: 
https://www.packtpub.com/application-development/d-cookbook  
It's not on sale right now, but if you've got the money, it's 
definitely worth it.


While it's not a cookbook, this one is good too: 
https://www.packtpub.com/application-development/learning-d


Some others if you haven't seen them:
http://ddili.org/ders/d.en/index.html
https://wiki.dlang.org/Tutorials
http://rosettacode.org/wiki/Category:D


I now have those books, and the Rosetta Code site seems to be the 
kind of worked exercises I like.  Thank you for this!


Re: Can compiler profile itself?

2017-01-25 Thread Stefan Koch via Digitalmars-d-learn
On Tuesday, 24 January 2017 at 23:25:12 UTC, Profile Anaysis 
wrote:
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.


[...]


yes the compiler can be used to profile itself.
build it with make ENABLE_PROFILE=1

If your code is overly slow you are probably using recursive 
variaidic templates.


Re: Why is [0] @safer than array.ptr?

2017-01-25 Thread Kagamin via Digitalmars-d-learn
On Tuesday, 24 January 2017 at 12:01:35 UTC, Jonathan M Davis 
wrote:
So, while it makes sense to say that .ptr can't be used in 
@safe code, it really doesn't make sense to suggest [0] as 
an alternative.


When you ensure pointers point to existing data, you can 
dereference them in safe code, otherwise you can't.