Re: Generic Property Implementation
On Saturday, 10 March 2018 at 17:43:06 UTC, Simen Kjærås wrote: I'm not sure how fixable this is, but I am sure that there's plenty of benefit to being able to write code like this: struct S { int n, m; SomeType!(() => n + m) a; } over this: struct S { int n, m; auto a() { return SomeType!(() => n + m)(); } } Anyways, I filed a bug for it: https://issues.dlang.org/show_bug.cgi?id=18587 Actually, this is not fixable. If we consider for a moment the internals of SomeType in the above code, it's something like this: struct SomeType(alias fn) { S* context; } The full layout of S then becomes this: struct S { int n; int m; S* a.context; // points to 'this'. } Since structs in D are defined to be movable by blitting only, with no cleanup afterwards, internal pointers are a no-no. Ref https://dlang.org/spec/garbage.html: Do not have pointers in a struct instance that point back to the same instance. The trouble with this is if the instance gets moved in memory, the pointer will point back to where it came from, with likely disastrous results. One possible solution would be for the above code to generate the function a() instead of making 'a' a member. This has its own set of issues, though - suddenly something that looks like a member isn't one, and its address can't be taken, it can't be passed by ref, etc. -- Simen
Re: Generic Property Implementation
On Monday, 12 March 2018 at 07:04:19 UTC, Simen Kjærås wrote: On Saturday, 10 March 2018 at 17:43:06 UTC, Simen Kjærås wrote: I'm not sure how fixable this is, but I am sure that there's plenty of benefit to being able to write code like this: struct S { int n, m; SomeType!(() => n + m) a; } over this: struct S { int n, m; auto a() { return SomeType!(() => n + m)(); } } Anyways, I filed a bug for it: https://issues.dlang.org/show_bug.cgi?id=18587 Actually, this is not fixable. If we consider for a moment the internals of SomeType in the above code, it's something like this: struct SomeType(alias fn) { S* context; } The full layout of S then becomes this: struct S { int n; int m; S* a.context; // points to 'this'. } Since structs in D are defined to be movable by blitting only, with no cleanup afterwards, internal pointers are a no-no. Ref https://dlang.org/spec/garbage.html: Do not have pointers in a struct instance that point back to the same instance. The trouble with this is if the instance gets moved in memory, the pointer will point back to where it came from, with likely disastrous results. One possible solution would be for the above code to generate the function a() instead of making 'a' a member. This has its own set of issues, though - suddenly something that looks like a member isn't one, and its address can't be taken, it can't be passed by ref, etc. -- Simen This is strange... An incomplete type is perfectly ok, so there should be no problem with a pointer of the same type inside a struct. If accidentally the pointer refers "this", then it must have been set after construction. As before construction the value of "this"-pointer does not exist and after the construction the pointer to "this" has the default value of null. Therefore, you are aware of this circumstance and appropriate movings of the pointer value are also up to you. On the other side: Isn't it the case, that struct SomeType(alias fn) {} is (or has to be) lowered to something like struct SomeType { typeof(fn)* fn; } Even if fn contains a frame pointer to S it is perfectly legal to have such a type. SomeType would contain a delegate then. However, I think, the syntax struct S { int n, m; SomeType!(() => n + m) a; } is still invalid and struct S { int n, m; auto a() { return SomeType!(() => n + m)(); } } has another semantics. The latter closures above the current values inside of S. The former has to be constructible without the context, as it is perfectly legal to write struct Outer { struct Inner{} } void main() { auto i = Outer.Inner(); } but would be impossible with this syntax.
Re: What's the proper way to add a local file dependence to dub?
On Sunday, 4 March 2018 at 16:46:56 UTC, Marc wrote: then copy it to sources folder? let's say I have a small library folder at C:\mylibrary\D where I want to use dir.d from it. How do I add that file dependence to dub? But I do not want to that file be passed directly to dmd, I want to that file be copied to application's source folder (so it's easy to distribuite, with the dependences together as possible) then compiled. So, what I want to some extension is dub work with loca files. Is this possible to do solely with dub? I know I can easily write a script to run before dub which copies the dependence files from C:\mylibrary to application's source but I'm looking for a more elegant approach as possible; I'm afraid of rewriting a makefile-like soon (I find cmake/make/makefiles just ugly). I did it this sway: the part of dub.json: "dependencies": { "diet-ng": "~>1.4", "vibe-d:tls": "~>0.8.0", "vibe-d:http": "~>0.8", "mysql-d": "~>0.3", "mylib":{ "versions": "~master", "path": "/home/mt/d/mylib" } }, In spite of using a version directly after the used lib, you give two parameters "versions" : "~master" and "path": "/path_to_your_lib/" Works well.
Re: Generic Property Implementation
On Monday, 12 March 2018 at 08:59:49 UTC, Alex wrote: An incomplete type is perfectly ok, so there should be no problem with a pointer of the same type inside a struct. If accidentally the pointer refers "this", then it must have been set after construction. As before construction the value of "this"-pointer does not exist and after the construction the pointer to "this" has the default value of null. Therefore, you are aware of this circumstance and appropriate movings of the pointer value are also up to you. But I don't have a hook to update the pointer when the struct is moved. The GC may move my struct without informing me in any way. In fact, even just a copy construction will break this: struct S { S* ptr; this(int dummy) { ptr = &this; } ~this() { // This assert will fail. assert(ptr == &this); } } unittest { S s1 = S(0); S s2 = S(0); assert(&s1 == s1.ptr); assert(&s2 == s2.ptr); s1 = s2; } The reason is copy construction makes a copy[1] of the lhs, then performs the copy construction[2]. If the copy construction[2] succeeds, the copy[1] is destroyed. If not, the copy[1] is blitted back over the original, to give the impression that nothing ever happened. When the destructor is called on the copy[1], &this returns a different address from what it did before, since it's a copy and logically resides at a different address. struct SomeType(alias fn) {} is (or has to be) lowered to something like struct SomeType { typeof(fn)* fn; } Even if fn contains a frame pointer to S it is perfectly legal to have such a type. SomeType would contain a delegate then. Indeed. But stack frames aren't copied or moved the way structs are. However, I think, the syntax struct S { int n, m; SomeType!(() => n + m) a; } is still invalid and struct S { int n, m; auto a() { return SomeType!(() => n + m)(); } } has another semantics. The latter closures above the current values inside of S. The former has to be constructible without the context, as it is perfectly legal to write struct Outer { struct Inner{} } void main() { auto i = Outer.Inner(); } but would be impossible with this syntax. I'm not using any inner structs in my examples. SomeType is assumed to be a separate type that knows nothing about S. If you're saying this should work: unittest { auto tmp = typeof(S.a)(); } It wouldn't, and such code is not possible in D today: struct S { int n; auto a() { return SomeType!(() => n)(); } } struct SomeType(alias fn) { int get() { return fn(); } } unittest { // cannot access frame pointer of foo.S.a.SomeType!(delegate () => this.n).SomeType auto tmp = typeof(S.a())(); } -- Simen
Re: What's the proper way to add a local file dependence to dub?
On Monday, 12 March 2018 at 09:38:41 UTC, Martin Tschierschke wrote: On Sunday, 4 March 2018 at 16:46:56 UTC, Marc wrote: [...] I did it this sway: the part of dub.json: "dependencies": { [...] "mylib":{ "versions": "~master", "path": "/home/mt/d/mylib" } }, In spite of using a version directly after the used lib, you give two parameters "versions" : "~master" and "path": "/path_to_your_lib/" Works well. And in ...mylib/dub.json you just add: "targetType": "library", on the top-level, and place your dir.d in ...mylib/source/
Re: [vibe.d/dub] Linker error
On Friday, 9 March 2018 at 13:46:33 UTC, Chris wrote: I got this error msg today (see below): DUB version 1.8.0, built on Mar 3 2018 vibe.d version 0.8.3 dmd 2.078.3 (the same with 2.079.0 and 2.077.0) .dub/build/server64_72_debug-debug-linux.posix-x86_64-dmd_2079-CAC4A12AC8FE4B4625A9511E4EFEB8F6/anscealai.o: In function `_D3std5range10primitives__T5doPutTSQBh6format__T11hasToStringTSQCj8typecons__T5TupleTAysTmZQnTaZ9__lambda1MFZ1STaZQDjFNaNbNiNfKQDpaZv': /usr/include/dlang/dmd/std/range/primitives.d:269: undefined reference to `_D3std6format__T11hasToStringTSQBd8typecons__T5TupleTAysTmZQnTaZ9__lambda1MFZ1S3putMFNaNbNiNfaZv' [...and loads of other similar messages...] collect2: error: ld returned 1 exit status Error: linker exited with status 1 /usr/bin/dmd failed with exit code 1. It is so massive that it must be something ridiculous. Ok, I've solved it now with a fresh head on my. I had `dflags "-allinst"` in the dub.sdl file which was there due to an old bug in dmd, I think. Once I had removed it, the linking worked. I knew it was something ridiculous.
Re: What's the proper way to add a local file dependence to dub?
On Sunday, 4 March 2018 at 16:46:56 UTC, Marc wrote: then copy it to sources folder? let's say I have a small library folder at C:\mylibrary\D where I want to use dir.d from it. How do I add that file dependence to dub? But I do not want to that file be passed directly to dmd, I want to that file be copied to application's source folder (so it's easy to distribuite, with the dependences together as possible) then compiled. So, what I want to some extension is dub work with loca files. Is this possible to do solely with dub? I know I can easily write a script to run before dub which copies the dependence files from C:\mylibrary to application's source but I'm looking for a more elegant approach as possible; I'm afraid of rewriting a makefile-like soon (I find cmake/make/makefiles just ugly). You can also add a simple dub.sdl to your local files and then use `dub add-local` to add the package to your dub environment. Dub will only rebuild the dependency on your local files if they changed (or you use a different compiler / build settings).
Re: Generic Property Implementation
On Monday, 12 March 2018 at 09:54:20 UTC, Simen Kjærås wrote: But I don't have a hook to update the pointer when the struct is moved. The GC may move my struct without informing me in any way. In fact, even just a copy construction will break this: struct S { S* ptr; this(int dummy) { ptr = &this; } ~this() { // This assert will fail. assert(ptr == &this); } } unittest { S s1 = S(0); S s2 = S(0); assert(&s1 == s1.ptr); assert(&s2 == s2.ptr); s1 = s2; } The reason is copy construction makes a copy[1] of the lhs, then performs the copy construction[2]. If the copy construction[2] succeeds, the copy[1] is destroyed. If not, the copy[1] is blitted back over the original, to give the impression that nothing ever happened. When the destructor is called on the copy[1], &this returns a different address from what it did before, since it's a copy and logically resides at a different address. Sure, you have. https://dlang.org/spec/struct.html#assign-overload Point #4. In this case, ref S opAssign(ref S rhs) { return this; } Another point is, that I hope, that pointers don't move anywhere, as in C, by definition. struct SomeType(alias fn) {} is (or has to be) lowered to something like struct SomeType { typeof(fn)* fn; } Even if fn contains a frame pointer to S it is perfectly legal to have such a type. SomeType would contain a delegate then. Indeed. But stack frames aren't copied or moved the way structs are. Yes. This is how the structs are meant to be, I thought :) However, I think, the syntax struct S { int n, m; SomeType!(() => n + m) a; } is still invalid and struct S { int n, m; auto a() { return SomeType!(() => n + m)(); } } has another semantics. The latter closures above the current values inside of S. The former has to be constructible without the context, as it is perfectly legal to write struct Outer { struct Inner{} } void main() { auto i = Outer.Inner(); } but would be impossible with this syntax. I'm not using any inner structs in my examples. SomeType is assumed to be a separate type that knows nothing about S. If you're saying this should work: Ah... I was unclear, I think... unittest { auto tmp = typeof(S.a)(); } I thought, this shouldn't be possible (at least in my mind) It wouldn't, and such code is not possible in D today: struct S { int n; auto a() { return SomeType!(() => n)(); } } struct SomeType(alias fn) { int get() { return fn(); } } But this is clearly valid. unittest { // cannot access frame pointer of foo.S.a.SomeType!(delegate () => this.n).SomeType auto tmp = typeof(S.a())(); } For sure, tmp cannot be defined without an instance of S. So the correct unittest in my eyes would be: unittest { S s; auto res = s.a; assert(res.get == S.init.n); } -- Simen
Re: DUB and Gtk-d reduce size of huge executable, build dynamic dependencies
OK. With the right compiler options (ldc2 -Oz and removing -g) the app_d file size, after stripping, becomes 10.5K.
context pointer breaks getOverloads, shouldn't it be ignored by it?
void main() { class Foo { void fun(){} } foreach(m; __traits(allMembers, Foo)) foreach(sym; __traits(getOverloads, Foo, m)) { } } this fails with: onlineapp.d(9): Error: no property this for type onlineapp.main.Foo onlineapp.d(9): Error: (Foo).this cannot be resolved it works fine if i add a `static if(m != "this")` or alternatively use std.meta.Erase("this", __traits(allMembers, Foo)).
Re: Generic Property Implementation
On Monday, 12 March 2018 at 10:37:00 UTC, Alex wrote: Sure, you have. https://dlang.org/spec/struct.html#assign-overload Point #4. In this case, ref S opAssign(ref S rhs) { return this; } True. Can you fix these, too? struct S { S* ptr; this(int dummy) { ptr = &this; } ~this() { assert(ptr == &this); } } void test(S s) {} unittest { test(S(0)); } S test2() { return S(0); } unittest { S s = test2(); } Another point is, that I hope, that pointers don't move anywhere, as in C, by definition. And why not? D allows for moving garbage collectors. unittest { auto tmp = typeof(S.a)(); } I thought, this shouldn't be possible (at least in my mind) It wouldn't, and such code is not possible in D today: struct S { int n; auto a() { return SomeType!(() => n)(); } } struct SomeType(alias fn) { int get() { return fn(); } } But this is clearly valid. Yes, it's an example of code that works in D today, with similar semantics to those implied in the other example. It's meant to show that just like `auto tmp = typeof(S.a())()` doesn't work today, it shouldn't work with the types used in my other example. unittest { // cannot access frame pointer of foo.S.a.SomeType!(delegate () => this.n).SomeType auto tmp = typeof(S.a())(); } For sure, tmp cannot be defined without an instance of S. So the correct unittest in my eyes would be: unittest { S s; auto res = s.a; assert(res.get == S.init.n); } I think we may be speaking past one another. Yes, your unittest would be expected to pass. If we go back to the example code: struct S1 { int n, m; SomeType!(() => n + m) a; } vs. struct S2 { int n, m; auto a() { return SomeType!(() => n + m)(); } } I would expect typeof(S1.a) and typeof(S2.a()) to be equivalent. I don't see a good reason why I should be able to construct an instance of typeof(S1.a), since I can't construct a typeof(S2.a()). I see your point that "The latter closures above the current values inside of [S2]". I'm saying I want the former to do the same. I understand that it currently doesn't, and I argue that having it do the same would be a much more useful behavior. Apart from the fact it's impossible, I don't see any good reason not to make it work. :p -- Simen
Re: Generic Property Implementation
On Monday, 12 March 2018 at 13:04:54 UTC, Simen Kjærås wrote: On Monday, 12 March 2018 at 10:37:00 UTC, Alex wrote: Sure, you have. https://dlang.org/spec/struct.html#assign-overload Point #4. In this case, ref S opAssign(ref S rhs) { return this; } True. Can you fix these, too? struct S { S* ptr; this(int dummy) { ptr = &this; } ~this() { assert(ptr == &this); } } void test(S s) {} unittest { test(S(0)); } S test2() { return S(0); } unittest { S s = test2(); } ok... this is a little bit more tricky, as there is no assignment now. :) But in this two cases I assume, you want to have explicit pass by reference, no? struct S { S* ptr; this(int dummy) { ptr = &this; } ~this() { assert(ptr == &this); } } void test(ref S s){} unittest { auto s = S(0); test(s); /* if I call test(S(0)) with void test(S s) as in your example, neither the postblit nor opAssign is called... hm... no idea why... */ } auto test2() { return new S(0); } unittest { auto s = test2(); /* This example differs more from the post before :) test2 is a true factory now, it has to grant the right setting of all members... */ } Another point is, that I hope, that pointers don't move anywhere, as in C, by definition. And why not? D allows for moving garbage collectors. If it were allowed, then "contiguous memory allocation" for arrays would be senseless. unittest { auto tmp = typeof(S.a)(); } I thought, this shouldn't be possible (at least in my mind) It wouldn't, and such code is not possible in D today: struct S { int n; auto a() { return SomeType!(() => n)(); } } struct SomeType(alias fn) { int get() { return fn(); } } But this is clearly valid. Yes, it's an example of code that works in D today, with similar semantics to those implied in the other example. It's meant to show that just like `auto tmp = typeof(S.a())()` doesn't work today, it shouldn't work with the types used in my other example. unittest { // cannot access frame pointer of foo.S.a.SomeType!(delegate () => this.n).SomeType auto tmp = typeof(S.a())(); } For sure, tmp cannot be defined without an instance of S. So the correct unittest in my eyes would be: unittest { S s; auto res = s.a; assert(res.get == S.init.n); } I think we may be speaking past one another. Yes, your unittest would be expected to pass. If we go back to the example code: struct S1 { int n, m; SomeType!(() => n + m) a; } vs. struct S2 { int n, m; auto a() { return SomeType!(() => n + m)(); } } I would expect typeof(S1.a) and typeof(S2.a()) to be equivalent. I don't see a good reason why I should be able to construct an instance of typeof(S1.a), since I can't construct a typeof(S2.a()). I see your point that "The latter closures above the current values inside of [S2]". I'm saying I want the former to do the same. I understand that it currently doesn't, and I argue that having it do the same would be a much more useful behavior. Apart from the fact it's impossible, I don't see any good reason not to make it work. :p I see your point too :) But the latter form just grants the existence of an instance of S, whereas the first form doesn't. By the way, this would work: struct S1 { static int n, m; // added a static here. SomeType!(() => n + m) a; } struct SomeType(alias fn){} -- Simen
Re: How do you call an eponymous template that has a secondary template arg?
On Monday, 12 March 2018 at 04:15:23 UTC, Simen Kjærås wrote: Yeah, that's a little hole in the grammar, but there are ways: // Declare an alias: alias aliasOfInt = aliasOf!int; // And use that: assert(!aliasOfInt!string); Or use std.meta.Instantiate: assert(!Instantiate!(aliasOf!int, string)); -- Simen Noice! Did not know about instantiate. Btw: I just tried this and it worked, to my surprise!: template aliasOf(T) { auto aliasOf(U)(U) { return is(U == T); } enum aliasOf(alias a) = aliasOf!int(a); } void main() { writeln(aliasOf!int(3)); // works writeln(allSatisfy!(aliasOf!int, 3)); // works }
Re: Date range iteration
On Monday, 12 March 2018 at 02:49:34 UTC, Jonathan M Davis wrote: On Monday, March 12, 2018 02:11:49 Jordan Wilson via Digitalmars-d-learn wrote: [...] Maybe iota should be made to work, but as present, it basically wants all three of the types it's given to be the same or implicitly convertible to a single type. It can't handle the step being a completely different type. [...] Yes I agree, a for loop for simple iteration is fine, but I'm sure there are cases where a date range would be quite useful, so the everyDuration tip is great, thanks! Jordan
How give a module to a CTFE function
Hi, I have a CTFE function that I want to make more generic by given it a module as parameter. My actual code looks like : mixin(implementFunctionsOf()); string implementFunctionsOf() { import std.traits; string res; foreach(name; __traits(allMembers, myHardCodedModule)) { } return res; } I tried many things but I can't figure out the type of the parameter I should use for the function implementFunctionsOf.
Re: How give a module to a CTFE function
On Monday, 12 March 2018 at 21:00:07 UTC, Xavier Bigand wrote: Hi, I have a CTFE function that I want to make more generic by given it a module as parameter. My actual code looks like : mixin(implementFunctionsOf()); string implementFunctionsOf() { import std.traits; string res; foreach(name; __traits(allMembers, myHardCodedModule)) { } return res; } I tried many things but I can't figure out the type of the parameter I should use for the function implementFunctionsOf. you can use a alias or a string: void fun(alias mod, string mod2)() { foreach(m; __traits(allMembers, mod)) pragma(msg, m); foreach(m; __traits(allMembers, mixin(mod2))) pragma(msg, m); } void main() { import std.stdio; fun!(std.stdio, "std.stdio"); }
Re: How give a module to a CTFE function
Le 12/03/2018 à 22:30, arturg a écrit : On Monday, 12 March 2018 at 21:00:07 UTC, Xavier Bigand wrote: Hi, I have a CTFE function that I want to make more generic by given it a module as parameter. My actual code looks like : mixin(implementFunctionsOf()); string implementFunctionsOf() { import std.traits; stringres; foreach(name; __traits(allMembers, myHardCodedModule)) { } return res; } I tried many things but I can't figure out the type of the parameter I should use for the function implementFunctionsOf. you can use a alias or a string: void fun(alias mod, string mod2)() { foreach(m; __traits(allMembers, mod)) pragma(msg, m); foreach(m; __traits(allMembers, mixin(mod2))) pragma(msg, m); } void main() { import std.stdio; fun!(std.stdio, "std.stdio"); } I tried both without success, Here is my full code : module api_entry; import std.stdio : writeln; import std.algorithm.searching; import derelict.opengl3.functions; import std.traits; string implementFunctionsOf(string mod) { import std.traits; string res; static foreach(name; __traits(allMembers, mixin(mod))) { static if (mixin("isCallable!" ~ name) && name.startsWith("da_")) { string oglFunctionName = name[3..$]; string returnType = ReturnType!(mixin(name)).stringof; string parametersType = Parameters!(mixin(name)).stringof; res ~= "export\n" ~ "extern (C)\n" ~ returnType ~ "\n" ~ oglFunctionName ~ parametersType ~ "\n" ~ "{\n" ~ " writeln(\"" ~ oglFunctionName ~ "\");\n"; static if (ReturnType!(mixin(name)).stringof != "void") { res ~= " " ~ returnType ~ " result;\n" ~ " return result;"; } res ~= "}\n"; } } return res; } mixin(implementFunctionsOf("derelict.opengl3.functions")); As string I get the following error: ..\src\api_entry.d(16): Error: variable `mod` cannot be read at compile time ..\src\api_entry.d(48):called from here: `implementFunctionsOf("derelict.opengl3.functions")` I also tried to make implementFunctionsOf a mixin template.
Re: How give a module to a CTFE function
Le 12/03/2018 à 23:24, Xavier Bigand a écrit : Le 12/03/2018 à 22:30, arturg a écrit : On Monday, 12 March 2018 at 21:00:07 UTC, Xavier Bigand wrote: Hi, I have a CTFE function that I want to make more generic by given it a module as parameter. My actual code looks like : mixin(implementFunctionsOf()); string implementFunctionsOf() { import std.traits; stringres; foreach(name; __traits(allMembers, myHardCodedModule)) { } return res; } I tried many things but I can't figure out the type of the parameter I should use for the function implementFunctionsOf. you can use a alias or a string: void fun(alias mod, string mod2)() { foreach(m; __traits(allMembers, mod)) pragma(msg, m); foreach(m; __traits(allMembers, mixin(mod2))) pragma(msg, m); } void main() { import std.stdio; fun!(std.stdio, "std.stdio"); } I tried both without success, Here is my full code : module api_entry; import std.stdio : writeln; import std.algorithm.searching; import derelict.opengl3.functions; import std.traits; string implementFunctionsOf(string mod) { import std.traits; stringres; static foreach(name; __traits(allMembers, mixin(mod))) { static if (mixin("isCallable!" ~ name) && name.startsWith("da_")) { string oglFunctionName = name[3..$]; string returnType = ReturnType!(mixin(name)).stringof; string parametersType = Parameters!(mixin(name)).stringof; res ~= "export\n" ~ "extern (C)\n" ~ returnType ~ "\n" ~ oglFunctionName ~ parametersType ~ "\n" ~ "{\n" ~ " writeln(\"" ~ oglFunctionName ~ "\");\n"; static if (ReturnType!(mixin(name)).stringof != "void") { res ~= " " ~ returnType ~ " result;\n" ~ " return result;"; } res ~= "}\n"; } } return res; } mixin(implementFunctionsOf("derelict.opengl3.functions")); As string I get the following error: ..\src\api_entry.d(16): Error: variable `mod` cannot be read at compile time ..\src\api_entry.d(48):called from here: `implementFunctionsOf("derelict.opengl3.functions")` I also tried to make implementFunctionsOf a mixin template. I forgot to precise, that I don't have a main, because I am trying to create an opengl32.dll. This is why I already have a mixin to inject to function definitions in the root scope.
Re: How give a module to a CTFE function
Le 12/03/2018 à 23:28, Xavier Bigand a écrit : Le 12/03/2018 à 23:24, Xavier Bigand a écrit : Le 12/03/2018 à 22:30, arturg a écrit : On Monday, 12 March 2018 at 21:00:07 UTC, Xavier Bigand wrote: Hi, I have a CTFE function that I want to make more generic by given it a module as parameter. My actual code looks like : mixin(implementFunctionsOf()); string implementFunctionsOf() { import std.traits; stringres; foreach(name; __traits(allMembers, myHardCodedModule)) { } return res; } I tried many things but I can't figure out the type of the parameter I should use for the function implementFunctionsOf. you can use a alias or a string: void fun(alias mod, string mod2)() { foreach(m; __traits(allMembers, mod)) pragma(msg, m); foreach(m; __traits(allMembers, mixin(mod2))) pragma(msg, m); } void main() { import std.stdio; fun!(std.stdio, "std.stdio"); } I tried both without success, Here is my full code : module api_entry; import std.stdio : writeln; import std.algorithm.searching; import derelict.opengl3.functions; import std.traits; string implementFunctionsOf(string mod) { import std.traits; stringres; static foreach(name; __traits(allMembers, mixin(mod))) { static if (mixin("isCallable!" ~ name) && name.startsWith("da_")) { string oglFunctionName = name[3..$]; string returnType = ReturnType!(mixin(name)).stringof; string parametersType = Parameters!(mixin(name)).stringof; res ~= "export\n" ~ "extern (C)\n" ~ returnType ~ "\n" ~ oglFunctionName ~ parametersType ~ "\n" ~ "{\n" ~ " writeln(\"" ~ oglFunctionName ~ "\");\n"; static if (ReturnType!(mixin(name)).stringof != "void") { res ~= " " ~ returnType ~ " result;\n" ~ " return result;"; } res ~= "}\n"; } } return res; } mixin(implementFunctionsOf("derelict.opengl3.functions")); As string I get the following error: ..\src\api_entry.d(16): Error: variable `mod` cannot be read at compile time ..\src\api_entry.d(48):called from here: `implementFunctionsOf("derelict.opengl3.functions")` I also tried to make implementFunctionsOf a mixin template. I forgot to precise, that I don't have a main, because I am trying to create an opengl32.dll. This is why I already have a mixin to inject to function definitions in the root scope. Ok, it works with the alias, I didn't see the last () in the implementFunctionsOf prototype. Thank you a lot.
Re: How give a module to a CTFE function
On Monday, 12 March 2018 at 22:28:30 UTC, Xavier Bigand wrote: I forgot to precise, that I don't have a main, because I am trying to create an opengl32.dll. This is why I already have a mixin to inject to function definitions in the root scope. you have to pass the string as a template arg so make implementFunctionsOf a template: string implementFunctionsOf(string mod)() { } then mix it in somewhere you want: mixin(implementFunctionOf!"std.stdio");
Re: How give a module to a CTFE function
On Monday, 12 March 2018 at 22:34:10 UTC, Xavier Bigand wrote: Ok, it works with the alias, I didn't see the last () in the implementFunctionsOf prototype. Thank you a lot. no problem. :)
Re: How give a module to a CTFE function
On Monday, 12 March 2018 at 22:24:15 UTC, Xavier Bigand wrote: mixin(implementFunctionsOf("derelict.opengl3.functions")); As string I get the following error: ..\src\api_entry.d(16): Error: variable `mod` cannot be read at compile time ..\src\api_entry.d(48):called from here: `implementFunctionsOf("derelict.opengl3.functions")` I also tried to make implementFunctionsOf a mixin template. make the argument to implementFunctionsOf a template arg.
how to make private class member private
I cannot get my head around, why private is not private, in D. How do I make a private member, private? - module test; import std.stdio; void main() { myClass c = new myClass(); c.myPrivateClassMember= "wtf"; writeln(c.myPrivateClassMember); } class myClass { private string myPrivateClassMember; // private does not mean private anymore?? } --
Re: how to make private class member private
Visibility modifiers in D are for the module, not class or struct. This is very useful to be able to access internal stuff outside of the abstraction and modify it sanely. While also keeping others at bay.
Re: how to make private class member private
On Tuesday, March 13, 2018 01:12:15 psychoticRabbit via Digitalmars-d-learn wrote: > I cannot get my head around, why private is not private, in D. > > How do I make a private member, private? > > - > module test; > > import std.stdio; > > void main() > { > myClass c = new myClass(); > c.myPrivateClassMember= "wtf"; > writeln(c.myPrivateClassMember); > } > > class myClass > { > private string myPrivateClassMember; // private does not mean > private anymore?? > } > > -- private is private to the module, not the class. There is no way in D to restrict the rest of the module from accessing the members of a class. This simplification makes it so that stuff like C++'s friend are unnecessary. If your class in a separate module from main, then main won't be able to access its private members. - Jonathan M Davis
Re: how to make private class member private
On Tuesday, 13 March 2018 at 01:39:13 UTC, Jonathan M Davis wrote: private is private to the module, not the class. There is no way in D to restrict the rest of the module from accessing the members of a class. This simplification makes it so that stuff like C++'s friend are unnecessary. If your class in a separate module from main, then main won't be able to access its private members. - Jonathan M Davis Mmm.. I don't think I like it. I feel you should be able to make a member of a class, private, regardless of where the class is located. This seems to break the concept of class encapsulation. No. I don't like it at all.
Re: how to make private class member private
On Tuesday, 13 March 2018 at 02:06:57 UTC, psychoticRabbit wrote: Mmm.. I don't think I like it. I feel you should be able to make a member of a class, private, regardless of where the class is located. This seems to break the concept of class encapsulation. No. I don't like it at all. If you have access to the module source, you have access to the source of types inside it. Making the module the lowest level of encapsulation makes sense from that perspective.
Re: how to make private class member private
psychoticRabbit wrote: On Tuesday, 13 March 2018 at 01:39:13 UTC, Jonathan M Davis wrote: private is private to the module, not the class. There is no way in D to restrict the rest of the module from accessing the members of a class. This simplification makes it so that stuff like C++'s friend are unnecessary. If your class in a separate module from main, then main won't be able to access its private members. - Jonathan M Davis Mmm.. I don't think I like it. I feel you should be able to make a member of a class, private, regardless of where the class is located. This seems to break the concept of class encapsulation. No. I don't like it at all. just stop thinking in C/C++ "#include" terms. there, you have no other ways to restrict data access, so they were forced to make it broken, and then introduce "friends" just to workaround the fact that there are no modules in C++. instead, start thinking with modules in mind. module is THE unit of incapsulation. there is nothing wrong in isolating class or two in a module. then, to make imports manageable, either create a package of that, or just a dummy module that does `public import xxx;` for everything.
Re: how to make private class member private
On Tuesday, 13 March 2018 at 02:24:38 UTC, Mike Parker wrote: On Tuesday, 13 March 2018 at 02:06:57 UTC, psychoticRabbit wrote: Mmm.. I don't think I like it. I feel you should be able to make a member of a class, private, regardless of where the class is located. This seems to break the concept of class encapsulation. No. I don't like it at all. If you have access to the module source, you have access to the source of types inside it. Making the module the lowest level of encapsulation makes sense from that perspective. There are two problems I see: 1st - D has broken the concept of class encapsulation, simply for convenience at the module level. Not good in my opinion. 2nd - C++/C#/Java programmers will come to D, use the same syntax, but get very different semantics. Not good in my opinion. (i.e. I only realised private was not private, by accident). D has made many good design decisions. I do not see this as one of them.
Re: how to make private class member private
On Tuesday, 13 March 2018 at 05:11:48 UTC, psychoticRabbit wrote: On Tuesday, 13 March 2018 at 02:24:38 UTC, Mike Parker wrote: On Tuesday, 13 March 2018 at 02:06:57 UTC, psychoticRabbit wrote: Mmm.. I don't think I like it. I feel you should be able to make a member of a class, private, regardless of where the class is located. This seems to break the concept of class encapsulation. No. I don't like it at all. If you have access to the module source, you have access to the source of types inside it. Making the module the lowest level of encapsulation makes sense from that perspective. There are two problems I see: 1st - D has broken the concept of class encapsulation, simply for convenience at the module level. Not good in my opinion. 2nd - C++/C#/Java programmers will come to D, use the same syntax, but get very different semantics. Not good in my opinion. (i.e. I only realised private was not private, by accident). D has made many good design decisions. I do not see this as one of them. There is another problem: 3rd: You are a brainwashed monkey who can't think for himself. See, You learned a little about C++/C#/Java and think the world must conform to what they say is correct and deny everything that contradicts it rather than first seeing if you are on the wrong side of the contradiction. The fact is, there is no reason a module should be restricted to see it's own classes private members. It's sorta like a family who runs around pretending that they can't see each others private parts. Sure, it sounds like a good thing... until someone accidentally drops the towel and the offended calls the cop on their brother and has him arrested for breaking the law. You should learn that your view of the world is very minute and stop trying to fit the world in to your box. It's called growing up. If you can't make a distinction between C++ encapsulation and D encapsulation you have far bigger problems than you think.
Re: how to make private class member private
psychoticRabbit wrote: There are two problems I see: 1) it is not how C++ done it. 2) it is not how C++ done it. and you're completely right: it is not how C++ done it.
Re: how to make private class member private
On Tuesday, 13 March 2018 at 05:35:30 UTC, Amorphorious wrote: There is another problem: 3rd: You are a brainwashed monkey who can't think for himself. No need for personal attacks. Let's keep it civil.
Re: how to make private class member private
On Tuesday, 13 March 2018 at 05:52:55 UTC, ketmar wrote: psychoticRabbit wrote: There are two problems I see: 1) it is not how C++ done it. 2) it is not how C++ done it. and you're completely right: it is not how C++ done it. umm...didn't you forget something: 1) it is not how C# done it. 2) it is not how C# done it. 1) it is not how Java done it. 2) it is not how Java done it.
Re: how to make private class member private
On Tuesday, 13 March 2018 at 05:11:48 UTC, psychoticRabbit wrote: 1st - D has broken the concept of class encapsulation, simply for convenience at the module level. Not good in my opinion. No, it hasn't broken encapsulation. Encapsulation is at the module level. A class or struct and any supporting functions can be included in a single module and the private API is encapsulated from the outside world. 2nd - C++/C#/Java programmers will come to D, use the same syntax, but get very different semantics. Not good in my opinion. (i.e. I only realised private was not private, by accident). D is not C++, C#, or Java. C++ uses friend to get around the issue. Java has no solution. I don't know about C#. D has made many good design decisions. I do not see this as one of them. I think it's a great feature and I use it frequently. It's allows more flexibility in class design. Without it, we'd need another protection attribute to enable the concept of "private to the module". In Java, it's recommended to manipulate private member variables through their accessors even in methods of the same class. I've always found that extreme. If you need to make a breaking change to the member variable, you already have access to all of the method internals anyway. Yes, there's room for error if you forget to make a change, but with all the support in modern IDEs and editors for find/replace, it's a simple matter to handle it all at once. And in the standard edit-compile-run cycle, any breakage is discovered right away, not weeks down the road in the field. The same applies here. Encapsulation simply isn't broken by this feature.
Re: how to make private class member private
psychoticRabbit wrote: On Tuesday, 13 March 2018 at 05:52:55 UTC, ketmar wrote: psychoticRabbit wrote: There are two problems I see: 1) it is not how C++ done it. 2) it is not how C++ done it. and you're completely right: it is not how C++ done it. umm...didn't you forget something: 1) it is not how C# done it. 2) it is not how C# done it. 1) it is not how Java done it. 2) it is not how Java done it. ah, yes, sorry: i completely forgot that C++ was invented after c# and java. mea maxima culpa!
Re: how to make private class member private
On Tuesday, 13 March 2018 at 06:01:43 UTC, ketmar wrote: ah, yes, sorry: i completely forgot that C++ was invented after c# and java. mea maxima culpa! My point was, that the 2 most widely used and popular languages on the plant, C# and Java, decided NOT to make private, something mean else, like D has done. So the 3 most used languages got it wrong??
Re: how to make private class member private
On Tuesday, 13 March 2018 at 05:35:30 UTC, Amorphorious wrote: There is another problem: 3rd: You are a brainwashed monkey who can't think for himself. Gee..takes some real brains to come up with that one. See, You learned a little about C++/C#/Java and think the world must conform to what they say is correct and deny everything that contradicts it rather than first seeing if you are on the wrong side of the contradiction. The fact is, there is no reason a module should be restricted to see it's own classes private members. Yeah that sounds fine. As long as you're willing to give up the concept of class encapsulation. And, as long as you are willing to have programmers use the same syntax in D, as used in the 3 most widely used lanaguages on the planet, but get very different semantics. It's a real gotcha for those programmers. It's sorta like a family who runs around pretending that they can't see each others private parts. Sure, it sounds like a good thing... until someone accidentally drops the towel and the offended calls the cop on their brother and has him arrested for breaking the law. I'm not interested in your fanatasies. Keep them to yourself. You should learn that your view of the world is very minute and stop trying to fit the world in to your box. It's called growing up. If you can't make a distinction between C++ encapsulation and D encapsulation you have far bigger problems than you think. I think the view of the 3 most widely used langauges on the planet, is not something to dismiss so easily. D has what, 1000 programmers, maybe.. so I wonder whose world is really minute. In any case, I'm not attacking D. I use it. I am just questioning whether the different semantics for private, in D, is really worth it.
Re: how to make private class member private
On Tuesday, 13 March 2018 at 06:03:11 UTC, Mike Parker wrote: I think it's a great feature and I use it frequently. It's allows more flexibility in class design. Without it, we'd need another protection attribute to enable the concept of "private to the module". That's kind of my point. That's what I would have done, if for no other reason, to prevent the same syntax from having different semantics (when C++/C#/Java programmers come over to D). And I switch between them all, and now, I have to remember D's private memeber is something very different indeed. In Java, it's recommended to manipulate private member variables through their accessors even in methods of the same class. I've always found that extreme. Java is extreme in many ways ;-) but at least, private member, is still a private member (to the class). If my private class memeber can be directly modified outside of the class, then class encapsulation IS broken. Just saying, oh no, it's module encapsulation you should be thinking about, seems kinda strange, since we still use classes - which are their own level of encapsulation. That's the whole point of them.
Re: how to make private class member private
On Tuesday, 13 March 2018 at 06:25:39 UTC, ketmar wrote: psychoticRabbit wrote: So the 3 most used languages got it wrong?? yes. do you know any other language, where a private class memeber, is not private to the class? (btw. that's a question, not a statement).
Re: how to make private class member private
On Tuesday, 13 March 2018 at 06:14:49 UTC, psychoticRabbit wrote: On Tuesday, 13 March 2018 at 06:01:43 UTC, ketmar wrote: ah, yes, sorry: i completely forgot that C++ was invented after c# and java. mea maxima culpa! My point was, that the 2 most widely used and popular languages on the plant, C# and Java, decided NOT to make private, something mean else, like D has done. So the 3 most used languages got it wrong?? Yes, they got it wrong! Because they don't have modules, and because Java & C# are OOP bondage-everything-is-a-class, and preach that the world spins on classes. C++ tried to fix it with 'friend', and it shows the hack that it is. Don't know why you think D should be just another Java or C#?
Re: how to make private class member private
psychoticRabbit wrote: So the 3 most used languages got it wrong?? yes.
Re: how to make private class member private
On 13/03/2018 7:14 PM, psychoticRabbit wrote: On Tuesday, 13 March 2018 at 06:01:43 UTC, ketmar wrote: ah, yes, sorry: i completely forgot that C++ was invented after c# and java. mea maxima culpa! My point was, that the 2 most widely used and popular languages on the plant, C# and Java, decided NOT to make private, something mean else, like D has done. So the 3 most used languages got it wrong?? Yes. Module system comes from the ML family. As proven by the adoption by Java as of late, it is far superior to alternative designs.
Re: how to make private class member private
On Tuesday, 13 March 2018 at 06:26:13 UTC, Radu wrote: On Tuesday, 13 March 2018 at 06:14:49 UTC, psychoticRabbit wrote: On Tuesday, 13 March 2018 at 06:01:43 UTC, ketmar wrote: ah, yes, sorry: i completely forgot that C++ was invented after c# and java. mea maxima culpa! My point was, that the 2 most widely used and popular languages on the plant, C# and Java, decided NOT to make private, something mean else, like D has done. So the 3 most used languages got it wrong?? Yes, they got it wrong! Because they don't have modules, and because Java & C# are OOP bondage-everything-is-a-class, and preach that the world spins on classes. C++ tried to fix it with 'friend', and it shows the hack that it is. Don't know why you think D should be just another Java or C#? Well I don't really. But one of the great things about D, is that a C++/C#/Java programmers can jump right in. But when the same syntax suddenly means something really different, I tend to think that's not a good design decision. And that's really the main point of my argument. As I said, this was a real gotcha for me. I only realised after I accidently tried to modify a private member directly, and discovered I did actually modify it! Maybe, a different modifier that made it private to the module would have been a better design decision.
Re: how to make private class member private
psychoticRabbit wrote: On Tuesday, 13 March 2018 at 06:25:39 UTC, ketmar wrote: psychoticRabbit wrote: So the 3 most used languages got it wrong?? yes. do you know any other language, where a private class memeber, is not private to the class? (btw. that's a question, not a statement). that is, we should stick to defective design only 'cause there is no "other D" that made it right? ;-) also, your question is not valid. you were told several times that you're evaluating the whole thing wrong, but you're insisting on your view being right. and you're keep asking, omiting the *critical* piece of the picture: modules. you were told that in D, encapsulation unit is *module*, not class/struct. it is not a "misdesign", it is the proper modular design. it doesn't matter what others are doing in this case. p.s.: yes, i know such language. Delphi/FreePascal.