Re: really why module declarations?

2017-03-26 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, March 26, 2017 20:51:01 XavierAP via Digitalmars-d-learn wrote:
> I've perused both the spec[1] and Andrei's book, and I the idea I
> get is that module declarations are optional, recommended only in
> case of file names not being valid D names. But in the community
> (and Phobos) I see it's strongly recommended and used throughout.
>
> What's the reason? If the declaration overrides the path
> (provided the file is found) rather than enforcing path
> consistency by outputting a compile error, then what's the
> benefit of module declarations, if we have to be disciplined to
> keep it consistent with paths anyway?
>
> I'm busy starting my first big multi file D project, thanks for
> any feedback!
>
>
> [1] https://dlang.org/spec/module.html#ModuleDeclaration

What it really comes down to is that if you don't give the module name, the
compiler infers it, and it doesn't infer packages. So, if you have

foo/bar.d

where bar.d's contents are

==
void main()
{
pragma(msg, __MODULE__);
}
==

and you compile with dmd foo/bar.d, you're going to see

bar

printed, whereas if you have

==
module foo.bar

void main()
{
pragma(msg, __MODULE__);
}
==

then you'll see

foo.bar

printed. So, if all you're ever doing is one file programs, then it really
doesn't matter, but if you're doing anything with packages, you have to use
module declarations. You also have to use them if you want to document a
module.

As for "overiding" the path... the compiler and other tools use the module
path as the path on disk to look for the files - e.g. if you tell the
compiler that /usr/local/include/dlang/ is an import directory, it'll start
looking for modules in there, and if it's looking for foo.bar, that means
that it's looking for /usr/local/include/dlang/foo/bar.d. On some level, it
is possible to give a module name or package name that doesn't match the
exact file or folder names on disk, but really, that's just asking for
trouble. It'll work in some basic cases, but it'll fall flat on its face in
real projects.

rdmd goes a step further and will compile additional modules based on what's
imported (i.e. if a module is imported but wasn't previously compiled, it'll
compile it), and when a tool does something like that, it makes it that much
worse if your module path isn't equivalent to the path on disk.

- Jonathan M Davis



Re: how to define my own traits

2017-03-26 Thread Moritz Maxeiner via Digitalmars-d-learn

On Sunday, 26 March 2017 at 23:25:49 UTC, XavierAP wrote:
I've looked into Phobos to emulate it when defining my own 
trait template, and when I see this:


module std.range.primitives;
// ...
template isInputRange(R)
{
enum bool isInputRange = is(typeof(
(inout int = 0)
{
R r = R.init; // can define a range object
if (r.empty) {}   // can test for empty
r.popFront;   // can invoke popFront()
auto h = r.front; // can get the front of the range
}));

I wonder, why that unused parameter (inout int = 0)?


`git blame` is your friend. It's all documented in the commit 
logs:
The original version does not have that parameter [1]. Then, to 
fix using isInputRange on an inout argument [2] a dummy parameter 
was introduced to force the delegate inside isInputRange to be 
typed as inout as well [3].

Later, the dummy parameter's name was dropped [4].

In my project () { /* ... */ } works the same for a custom 
trait.


Have you tried it without the dummy parameter on the example 
given in the bug report [2]?


[1] 
https://github.com/dlang/phobos/commit/49f646271bf6c843fcdd90249baa875bf43be0a1#diff-b7fc67b6fcb7d1a521918d06ffe03587R50

[2] https://issues.dlang.org/show_bug.cgi?id=7824
[3] 
https://github.com/dlang/phobos/commit/ed00f6c28c602bd5c3b197e555c44d3b53ef76ba
[4] 
https://github.com/dlang/phobos/commit/db1d909d7adb1b28ec0ba1895f56da0cc01a937b


how to define my own traits

2017-03-26 Thread XavierAP via Digitalmars-d-learn
I've looked into Phobos to emulate it when defining my own trait 
template, and when I see this:


module std.range.primitives;
// ...
template isInputRange(R)
{
enum bool isInputRange = is(typeof(
(inout int = 0)
{
R r = R.init; // can define a range object
if (r.empty) {}   // can test for empty
r.popFront;   // can invoke popFront()
auto h = r.front; // can get the front of the range
}));

I wonder, why that unused parameter (inout int = 0)?
In my project () { /* ... */ } works the same for a custom trait.


Re: really why module declarations?

2017-03-26 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 26 March 2017 at 20:51:01 UTC, XavierAP wrote:
I've perused both the spec[1] and Andrei's book, and I the idea 
I get is that module declarations are optional, recommended 
only in case of file names not being valid D names. But in the 
community (and Phobos) I see it's strongly recommended and used 
throughout.


What's the reason? If the declaration overrides the path 
(provided the file is found) rather than enforcing path 
consistency by outputting a compile error, then what's the 
benefit of module declarations, if we have to be disciplined to 
keep it consistent with paths anyway?


I'm busy starting my first big multi file D project, thanks for 
any feedback!



[1] https://dlang.org/spec/module.html#ModuleDeclaration


In addition to what Adam has said, they allow you to treat the 
module as a symbol during compilation. You _can_ do that with the 
implicitly generated one, but you can't do things that requires 
the declared symbol, e.g. attach UDAs which is how dcompute 
distinguishes device modules from host modules and possibly 
reflect of the symbols (although you can use __MODULE__ for that).


Re: really why module declarations?

2017-03-26 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 26 March 2017 at 22:10:07 UTC, XavierAP wrote:
I was curious but I guess it's long to explain the different 
things that can go wrong if one doesn't declare module names.


You'll just get a name conflict eventually. Either two modules 
with the same name, or "module `foo` must be imported as 
`foo.bar`" errors when stuff fails to line up, then you'll need 
to go in and change all the imports to fix it. Real hassle to do 
later, real easy to do now.


Followup question: if I am inside module myproj.pack1.mod1 and 
want to import myproj.pack1.mod2... should I import 
myproj.pack1.mod2; or import mod2; ?


Always use the full module name in import. If you want to 
abbreviate it, do


module something = myproj.pack.mod2;

then you can refer to it as `something` throughout the usage 
points in that file.


Re: really why module declarations?

2017-03-26 Thread XavierAP via Digitalmars-d-learn

On Sunday, 26 March 2017 at 20:58:24 UTC, Adam D. Ruppe wrote:


Module declarations are only optional in the most trivial case 
that is rarely useful in real world code. I recommend you 
ALWAYS use them (and always put a ddoc comment on them!), and 
moreover that you avoid top name modules (use 
`myproject.modname` instead of `modname`) to avoid conflicts.


OK I was already doing it all this in the multi-file project. I 
was curious but I guess it's long to explain the different things 
that can go wrong if one doesn't declare module names.


Followup question: if I am inside module myproj.pack1.mod1 and 
want to import myproj.pack1.mod2... should I import 
myproj.pack1.mod2; or import mod2; ?


Re: Howto catch SocketOSException?

2017-03-26 Thread Jolly James via Digitalmars-d-learn

On Sunday, 26 March 2017 at 18:50:13 UTC, bauss wrote:

On Sunday, 26 March 2017 at 11:46:39 UTC, Jolly James wrote:

[...]


Chances are it's invoked in another thread and thus you can't 
catch it like that.


To sum it up.

Ex.

void thisFunctionThrows() { ... }

void ableToCatch() {
try {
thisFunctionThrows();
}
catch (Exception e) {
// We can catch the exception ...
}
}

void notAbleToCatch() {
try {
spawn(&thisFunctionThrows);
}
catch (Exception e) {
// We cannot catch the exception ...
}
}

void ableToCatchToo() {
spawn(&ableToCatch); // We're able to handle the exception, 
because the try/catch is handled in the thread that calls the 
function that throws.

}


If you want try to help me, mabye this helps you:
https://github.com/CyberShadow/ae/blob/master/net/asockets.d#L1237


Re: Loading assimp

2017-03-26 Thread ag0aep6g via Digitalmars-d-learn

On 03/26/2017 11:31 PM, Dlearner wrote:

SDL_Surface* surface = IMG_Load(filename.ptr);
if (surface is null) {
writeln("surface is null: ", to!string(IMG_GetError()));
} else {
writeln(filename);
}

From console:
surface is null: Couldn't open Models/Nanosuit/helmet_diff.pngÇ2ÿ

I'm assuming the previous textures didn't experience this, but I have no
idea what could be the problem here, especially as the filename seems
fine when I writeln it.
:(


How do you construct `filename`? Looks like it's not properly 
null-terminated.


If you followed my (short-sighted) `dup` advice, that doesn't do 
null-termination. Since the original strings are null-terminated, just 
slicing one more character should do the trick. I'd put an assert that 
verifies that the last character is '\0'.


I.e.:

string z = x.data[0 .. x.length + 1].idup;
assert(z[$ - 1] == '\0');


Generally, don't pass just the pointer of a string unless you know for 
sure that it's properly null-terminated.


If you're using a slice directly, without `dup`-ing, then the original 
aiString would seem to be broken already.


Re: Loading assimp

2017-03-26 Thread Dlearner via Digitalmars-d-learn

On Sunday, 26 March 2017 at 12:40:42 UTC, Dlearner wrote:


...
About half the textures seem to load fine.  Some progress!


I don't know why, but when I get to the 8th texture, the filename 
has some garbage attached.


SDL_Surface* surface = IMG_Load(filename.ptr);
if (surface is null) {
writeln("surface is null: ", to!string(IMG_GetError()));
} else {
writeln(filename);
}

From console:
surface is null: Couldn't open Models/Nanosuit/helmet_diff.pngÇ2ÿ

I'm assuming the previous textures didn't experience this, but I 
have no idea what could be the problem here, especially as the 
filename seems fine when I writeln it.

:(


Re: really why module declarations?

2017-03-26 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 26 March 2017 at 20:51:01 UTC, XavierAP wrote:
I've perused both the spec[1] and Andrei's book, and I the idea 
I get is that module declarations are optional, recommended 
only in case of file names not being valid D names.


Module declarations are only optional in the most trivial case 
that is rarely useful in real world code. I recommend you ALWAYS 
use them (and always put a ddoc comment on them!), and moreover 
that you avoid top name modules (use `myproject.modname` instead 
of `modname`) to avoid conflicts.


If you don't, you are depending on implicit magic and just hoping 
that there's no conflict from third party libraries, and those 
lead to problems, almost guaranteed before long.


if we have to be disciplined to keep it consistent with paths 
anyway?


That's false, the path is irrelevant to the D language, ONLY the 
module declaration gives the canonical name. The path is just a 
helper for automatic tools to find the module given an import, 
but my preference is to ditch those things and actually just list 
your modules by name anyway. Then everything works reliably and 
consistently.


really why module declarations?

2017-03-26 Thread XavierAP via Digitalmars-d-learn
I've perused both the spec[1] and Andrei's book, and I the idea I 
get is that module declarations are optional, recommended only in 
case of file names not being valid D names. But in the community 
(and Phobos) I see it's strongly recommended and used throughout.


What's the reason? If the declaration overrides the path 
(provided the file is found) rather than enforcing path 
consistency by outputting a compile error, then what's the 
benefit of module declarations, if we have to be disciplined to 
keep it consistent with paths anyway?


I'm busy starting my first big multi file D project, thanks for 
any feedback!



[1] https://dlang.org/spec/module.html#ModuleDeclaration


Re: Howto catch SocketOSException?

2017-03-26 Thread bauss via Digitalmars-d-learn

On Sunday, 26 March 2017 at 11:46:39 UTC, Jolly James wrote:

On Sunday, 26 March 2017 at 11:35:00 UTC, Jolly James wrote:

[...]


Found out something: You cannot catch any exception thrown in 
the listen()-method in general.



■ Original code:

[...]



■ Modified one:

[...]



■ Not working try-catch:

[...]


Chances are it's invoked in another thread and thus you can't 
catch it like that.


To sum it up.

Ex.

void thisFunctionThrows() { ... }

void ableToCatch() {
try {
thisFunctionThrows();
}
catch (Exception e) {
// We can catch the exception ...
}
}

void notAbleToCatch() {
try {
spawn(&thisFunctionThrows);
}
catch (Exception e) {
// We cannot catch the exception ...
}
}

void ableToCatchToo() {
spawn(&ableToCatch); // We're able to handle the exception, 
because the try/catch is handled in the thread that calls the 
function that throws.

}


Re: Loading assimp

2017-03-26 Thread Dlearner via Digitalmars-d-learn

On Sunday, 26 March 2017 at 11:10:55 UTC, ag0aep6g wrote:

On Sunday, 26 March 2017 at 10:34:21 UTC, Dlearner wrote:
I came back to this project and realised my mistakes (Importer 
is a class for the C++ API, and we're using the C API).

So I fixed all my errors, but now I get an access violation.
As far as I can tell, it seems to be an issue with 
`aiGetMaterialTexture`.  It is meant to return an aiString 
with a filename (default value of "$texture.png"), I believe.  
But I get:


aiString(13, x"67 6C 61 73 73 5F 64 69 66 2E 70 6E 67 00 FF FF 
FF ... FF"c)

[shortened for brevity]


The data is "glass_dif.png", followed by a null terminator, 
followed by a bunch of 0xFFs. 13 is the length of 
"glass_dif.png". Judging from the definition of aiString [1], 
the 0xFFs are just unused space. So, this looks good.


I'm meant to add this on to a directory string so I can load 
an image, but obviously this wouldn't work.


To convert an aiString to a D string, it should be possible to 
slice the data with the length:


aiString x;
const(char)[] y = x.data[0 .. x.length];

You have to be cautiots of lifetime requirements, of course. If 
needed, you can make a copy with dup (mutable copy) or idup 
(immutable copy):


const(char)[] y = x.data[0 .. x.length].dup;
string z = x.data[0 .. x.length].idup;


[1] http://www.assimp.org/lib_html/structai_string.html


Ahh this did help!  I practically followed your advice, then 
fixed a somewhat unrelated range violation, and got a similar 
"object.Error@(0): Access Violation".  But in the console I got:

filename: Models/Nanosuit/glass_dif.png
filename: Models/Nanosuit/leg_dif.png
filename: Models/Nanosuit/leg_showroom_spec.png
filename: Models/Nanosuit/hand_dif.png
filename: Models/Nanosuit/hand_showroom_spec.png
filename: Models/Nanosuit/arm_dif.png
filename: Models/Nanosuit/arm_showroom_spec.png
filename: Models/Nanosuit/helmet_diff.png

About half the textures seem to load fine.  Some progress!


Re: Howto catch SocketOSException?

2017-03-26 Thread Jolly James via Digitalmars-d-learn

On Sunday, 26 March 2017 at 11:35:00 UTC, Jolly James wrote:

On Sunday, 26 March 2017 at 02:41:46 UTC, Adam D. Ruppe wrote:

On Sunday, 26 March 2017 at 02:24:56 UTC, Jolly James wrote:
You can ignore the loop()-method. It is not called as the 
application will never reach this statement, because it 
cannot, because it crashes already in the listen()-method in 
consequence of the exception that does not get caught by the 
try-catch block.


Try putting it in the try anyway and see what happens.

It is an async socket library, they can do weird things.\


Unfortunately not working either. I should not forget to 
mention that the exception also raises when the code does not 
contain the loop()-call.


Found out something: You cannot catch any exception thrown in the 
listen()-method in general.



■ Original code:
auto addressInfos = getAddressInfo(addr, to!string(port), 
AddressInfoFlags.PASSIVE, SocketType.STREAM, ProtocolType.TCP);



■ Modified one:

AddressInfo[] addressInfos;

try
{
	addressInfos = getAddressInfo(addr, to!string(port), 
AddressInfoFlags.PASSIVE, SocketType.STREAM, ProtocolType.TCP);

}
catch(SocketOSException e)
{
throw new Exception("Invalid address: " ~ addr, e);
}



■ Not working try-catch:

try
{
tcp.listen(2345, "127.0.0.1c");
socketManager.loop();
}
catch (Exception e)
{
return;
}


Re: Howto catch SocketOSException?

2017-03-26 Thread Jolly James via Digitalmars-d-learn

On Sunday, 26 March 2017 at 02:41:46 UTC, Adam D. Ruppe wrote:

On Sunday, 26 March 2017 at 02:24:56 UTC, Jolly James wrote:
You can ignore the loop()-method. It is not called as the 
application will never reach this statement, because it 
cannot, because it crashes already in the listen()-method in 
consequence of the exception that does not get caught by the 
try-catch block.


Try putting it in the try anyway and see what happens.

It is an async socket library, they can do weird things.\


Unfortunately not working either. I should not forget to mention 
that the exception also raises when the code does not contain the 
loop()-call.


Re: Loading assimp

2017-03-26 Thread ag0aep6g via Digitalmars-d-learn

On Sunday, 26 March 2017 at 10:34:21 UTC, Dlearner wrote:
I came back to this project and realised my mistakes (Importer 
is a class for the C++ API, and we're using the C API).

So I fixed all my errors, but now I get an access violation.
As far as I can tell, it seems to be an issue with 
`aiGetMaterialTexture`.  It is meant to return an aiString with 
a filename (default value of "$texture.png"), I believe.  But I 
get:


aiString(13, x"67 6C 61 73 73 5F 64 69 66 2E 70 6E 67 00 FF FF 
FF ... FF"c)

[shortened for brevity]


The data is "glass_dif.png", followed by a null terminator, 
followed by a bunch of 0xFFs. 13 is the length of 
"glass_dif.png". Judging from the definition of aiString [1], the 
0xFFs are just unused space. So, this looks good.


I'm meant to add this on to a directory string so I can load an 
image, but obviously this wouldn't work.


To convert an aiString to a D string, it should be possible to 
slice the data with the length:


aiString x;
const(char)[] y = x.data[0 .. x.length];

You have to be cautiots of lifetime requirements, of course. If 
needed, you can make a copy with dup (mutable copy) or idup 
(immutable copy):


const(char)[] y = x.data[0 .. x.length].dup;
string z = x.data[0 .. x.length].idup;


[1] http://www.assimp.org/lib_html/structai_string.html


Re: Loading assimp

2017-03-26 Thread Dlearner via Digitalmars-d-learn
I came back to this project and realised my mistakes (Importer is 
a class for the C++ API, and we're using the C API).

So I fixed all my errors, but now I get an access violation.
As far as I can tell, it seems to be an issue with 
`aiGetMaterialTexture`.  It is meant to return an aiString with a 
filename (default value of "$texture.png"), I believe.  But I get:


aiString(13, x"67 6C 61 73 73 5F 64 69 66 2E 70 6E 67 00 FF FF FF 
... FF"c)

[shortened for brevity]

I'm meant to add this on to a directory string so I can load an 
image, but obviously this wouldn't work.


I thought it might be a problem with converting from D-strings to 
C-strings.  I sent a string to `aiImportFile` as 
`toStringz(path)`.

I tested this with some writeln debugging:

```
auto temp = path.toStringz;
writeln("toStringz: ", temp);
writeln("string: ", temp.to!string);
```

This gave:
toStringz: 4770B6
string: Models/Nanosuit/nanosuit.obj

So maybe this is a problem with using aiStrings?  I'm quite 
confused.  Sorry if this is more of an assimp question than a D 
question, but I don't know if it's me misusing D language 
features or not.


Re: union.sizeof

2017-03-26 Thread zabruk70 via Digitalmars-d-learn

On Sunday, 26 March 2017 at 07:18:14 UTC, ketmar wrote:
i.e. what compiler does (roughly) is inserting anonymous fields 
of the appropriate size *into* the container. for "inner" 
aligning compiler inserts anonymous fields *between* other 
fields. for "outer" aligning compiler just appends anonymous 
field at the *end* of a data type, so data type size will met 
align requirements.


Big thank!!


Re: union.sizeof

2017-03-26 Thread ketmar via Digitalmars-d-learn

zabruk70 wrote:


On Sunday, 26 March 2017 at 06:45:13 UTC, ketmar wrote:

yes. you have a typo in second `writefln`: S1 instead of S2. ;-)


thank you.
another question, related to my first post:

why size of S2.b1 and S2.b2 still 3, not 4?

am i right: then align applied to members, compiler not change size of 
members, just make padding, so CONTAINER size changes?


yes. compiler is not allowed to mess with data types of the known size. ;-) 
and you are right: it doesn't have to. it just inserts dummy anonymous (and 
unused) bytes into struct/union to satisfy alignment requirements.




if so (because size of S2.b1 and S2.b2 still is 3 in my code),
then adding align(1) outside of union must not change zise of union, but 
size of some comainer more upper level.


nope, it changes size of the union itself. padding bytes *are* included in 
union, so `myunion.sizeof` includes 'em too.


i.e. what compiler does (roughly) is inserting anonymous fields of the 
appropriate size *into* the container. for "inner" aligning compiler 
inserts anonymous fields *between* other fields. for "outer" aligning 
compiler just appends anonymous field at the *end* of a data type, so data 
type size will met align requirements.


Re: foreach, is and pointer

2017-03-26 Thread rikki cattermole via Digitalmars-d-learn

On 26/03/2017 7:52 AM, helxi wrote:

What's the difference between
1.
string x = "abcd";
foreach(character; x)
write(character);

and

string x = "abcd";
foreach(character; x[0..$])
write(character);


Hopefully the compiler is smart enough to ignore that slice (since its 
identical in purpose).



2. is and ==


is: bit for bit comparison
==: "magic" comparison logic, supports e.g. opEquals on classes.


3. pointer and address and reference?


pointer: a place in memory! or hdd.. or well pretty much anywhere the 
kernel maps it to, just assume that there is some data there that you 
may be able to do some, all or none of these things read, write, 
execute. May also be invalid aka null aka 0.


reference: pointer + some other pointer generally, e.g. class instance 
data pointer + typeinfo reference + vtable.