Re: std.socket undefined UnixAddress?
I solved the problem by creating my own version of UnixAddress. The existing implementation needs some work. I'll filed a bug report. http://d.puremagic.com/issues/show_bug.cgi?id=9384 --rt
Re: Coping files and folders
On Thursday, 24 January 2013 at 07:41:23 UTC, Jacob Carlborg wrote: On 2013-01-24 07:28, Joel wrote: How does one copy folders (with files in them) including sub folders, and creating any needed folders? Like: land\house\cat.d land\house\rat.exe land\house\bedroom\ants.txt to root\island\house\cat.d root\island\house\rat.exe root\island\house\bedroom\ants.txt One work around is to use 'system' (under std.process). I don't think Phobos currently has any functions for this. Someone posted code in these newsgroups of a parallel implementation of copy and remove. Mustn't be very hard to manually write copyDir. The problem with copyDir is its transactional behavior: What should it do in case of a failure mid copy? Bail? Cleanup? Continue? Anyways, I just threw this together. The first version bails on first error. The second version keeps going as much as it can, and returns true on success. The caller is then free to (or not to) call rmdirRecurse in case of failure. //Throws exception on first error. void copyDir(string inDir, string outDir) { if (!exists(outDir)) mkdir(outDir); else if (!isDir(outDir)) throw new FileException(format(Destination path %s is not a folder., outDir)); foreach (entry; dirEntries(inDir.idup, SpanMode.shallow)) { auto fileName = baseName(entry.name); auto destName = buildPath(outDir, fileName); if (entry.isDir()) copyDir(entry.name, destName); else copy(entry.name, destName); } } //Silently keeps going as much as it can, then returns true on success, //or false if an error occured. bool copyDirSilent(string inDir, string outDir) { if (!exists(outDir)) { auto e = collectException(mkdir(outDir)); if (e !is null) return false; } else if (!isDir(outDir)) return false; foreach (entry; dirEntries(inDir, SpanMode.shallow)) { auto fileName = baseName(entry.name); auto destName = buildPath(outDir, fileName); if (entry.isDir()) { bool b = copyDirSilent(entry.name, destName); if (b == false) return false; } else { auto e = collectException(mkdir(outDir)); if (e !is null) return false; } } return true; }
Re: Passing opaque struct between functions/modules
On Wednesday, 23 January 2013 at 16:33:08 UTC, Sarath Kumar wrote: DMD v2.61; openSUSE 12.1 Source: --- libA.d: module libA; extern (C) { struct Opaque; Opaque* getObject(); void doSomething(Opaque *); } -- libB.d: module libB; extern (C) { struct Opaque; void doAction(Opaque *); } --- bug.d import libA, libB; int main(string[] args) { auto opaque = libA.getObject(); libA.doSomething(opaque); // this is okay libB.doAction(opaque); // but this is not, compiler error here return 0; } When I compile the above files, I get the below error. $ rdmd bug.d bug.d(7): Error: function libB.doAction (Opaque*) is not callable using argument types (Opaque*) bug.d(7): Error: cannot implicitly convert expression (opaque) of type Opaque* to Opaque* If I do an explicit cast, libB.Opaque*, for opaque in line 7, bug.d, I get completely different set of errors. $ rdmd bug.d libB.d(5): Error: struct libB.Opaque unknown size libB.d(5): Error: struct libB.Opaque no size yet for forward reference libB.d(5): Error: struct libB.Opaque unknown size libB.d(5): Error: struct libB.Opaque no size yet for forward reference libA.d(5): Error: struct libA.Opaque unknown size libA.d(5): Error: struct libA.Opaque no size yet for forward reference Can someone please tell me the right way to pass an opaque object between module's functions. The error message here is deceiving. Declare the struct in one module only and then import it in every module that uses it. So, for example, keep the declaration in libA, remove it from libB and in libB add import libA;.
Re: Passing opaque struct between functions/modules
On Wednesday, 23 January 2013 at 17:14:31 UTC, Ali Çehreli wrote: On 01/23/2013 08:33 AM, Sarath Kumar wrote: Can someone please tell me the right way to pass an opaque object between module's functions. I am assuming that you are interfacing with a C library. That library must have a D binding file. I am assuming that it is your libA.d: There is also a library that implements the struct and the functions. Although you would have it in the C library, here is a D module to imitate it: // libA_impl.d // These are presumably defined in a C library. Simply imitating it with this // D module extern (C) { struct Opaque { int i; double d; } Opaque* getObject() { return new Opaque(42, 1.5); } void doSomething(Opaque *) {} } I don't know the contents of the struct as libA and libB are 3rd party C libraries.
Segfault in _d_dynamic_cast ()
I am trying to create a BVH tree structure to speed up raytracing. So far it has been fine. I have created the BVH tree. It works for 202 triangles/spheres. However, when the scene has more spheres/triangles, I get a segmentation fault when the rays are traces, not when the tree is being built. To let you understand, there is a Surface class, from which BVHNode, Sphere and Triangle inherit. I have written a small function that prints the BVH tree recursively. Here it is: void printBVH(Surface root, int i = 0, string str = ) { if( root is null ) return; writeln(--PRINT()--); writeln(icy);//writeln(root.boundingBox()); writeln(name = , root.name, depth = , i, [, str, ]); writeln(--~~~--\n); if( (cast(BVHNode)root) !is null ) // OOPS! SEG FAULT HERE { printBVH((cast(BVHNode)(root)).left, i+1, left); printBVH((cast(BVHNode)(root)).right, i+1, right); } } And I pass to printBVH() the root node that the function that builds the tree has returned. // replaces every two Surfaces with one that is their parent. Proceeds until there is only one surface, which is the root. BVHNode createBVHTree2(Surface[] objects, ubyte axis = 0, int depth = 0) { import std.algorithm, std.stdio; BVHNode root; // sort left out for now until the seg fault is fixed //sort!((a.boundingBox().min.x + a.boundingBox().max.x) * 0.5f (b.boundingBox().min.x + b.boundingBox().max.x) * 0.5f, SwapStrategy.unstable)(objects); while( objects.length 1 ) { writeln(--- Level ---); foreach(o; objects) write([, o.name, ] ); writeln(); auto temp = new Surface[objects.length/2 + 1]; auto sz = 0UL; for(auto i = 0UL; i objects.length; i += 2) { writeln(i = , i, sz = , sz+1); BVHNode parent = new BVHNode(); parent.name = p; parent.left = objects[i]; if( i + 1 objects.length ) { parent.right = objects[i+1]; auto box1 = objects[i].boundingBox(), box2 = objects[i+1].boundingBox(); parent.box = combine(box1, box2); } else { parent.right = null; parent.box = objects[i].boundingBox(); } temp[sz++] = parent; } temp.length = sz; objects = temp; } root = cast(BVHNode)objects[0]; return root; } Ok, so when I print the scene using printBVH(), I get a segfault in the line: if( (cast(BVHNode)root) !is null ) GDB says: Program received signal SIGSEGV, Segmentation fault. 0x004b55fc in _d_dynamic_cast () Note that I have written the createBVHTree() and printBVH() functions in Java to see if it would be different. The code works in Java. I guess something is wrong with the compiler here and the way it handles recursion(?) -- By the way the code seg faults at the 11 depth level. Are there any know bugs for this? Thanks.
Re: Passing opaque struct between functions/modules
On Thursday, 24 January 2013 at 09:39:39 UTC, Sarath Kumar wrote: On Thursday, 24 January 2013 at 09:04:09 UTC, Mike Parker wrote: The error message here is deceiving. Declare the struct in one module only and then import it in every module that uses it. So, for example, keep the declaration in libA, remove it from libB and in libB add import libA;. I can't import libA into libB. So, I had moved the forward declaration into a separate D file and did a public import into libA and libB. This works. But this is a workaround. I will file a bug. The only potential bug I see here is in the error message. What you're seeing is a conflict that arises from D's name mangling. The doSomething in libA is expecting a parameter of type libA.Opaque* and getObject is returning the same, whereas the functions in libB are expecting a parameter of type libB.Opaque*. You can see this if you do the following: writeln(doSomething.mangleof); writeln(doAction.mangleof); This is why your code is failing when you call getAction, because you're passing it a libA.Opaque* returned from libA.getObject. The solution is to declare opaque struct in a single place and import it everywhere you need it. That's why your public imports work. I would suggest that you not use the public import in this case, but work out some other scenario. In Derelict (a collection of C bindings) for example, I tend to follow this pattern for any lib a bind to: types.d - all type constant declarations go here functions.d - all function declarations go here, imports the types module Then I have a module named according to the C library's primary header that publicly imports both. For SDL2, for example: module derelict.sdl2.sdl; public { import derelict.sdl2.types; import derelict.sdl2.functions; } This way, all types are declared in a single location so there's no danger of mixing up different mangles of the same type.
Re: Pull 1019
yebblies: Can an auto-ref function pointer/deltegate implicitly convert to ref? 9rnsr: To @yebblies : I yet not implement it because this is a basic proposal. IMHO, what he says is that behavior proposed by yebblies is some more complicated special cases he is not going to do within this pull request to keep things simple. All pulls are proposals, by the way, it is up to one of core devs (other than pull author) to make a decision about merging. On Wednesday, 23 January 2013 at 23:46:19 UTC, Namespace wrote: I have now seen something I've probably overlooked before. Here: https://github.com/D-Programming-Language/dmd/pull/1019#issuecomment-11836011 Kenji says, that the pull is a basic _proposal_. What does this mean? It isn't merged until we made a final discussion and decision about that? :/ I thought that this is the solution for all C++ rvalue ref problems. Am i wrong? I'm asking so much because I've been using it already - and I love it. Without such thing it is very annoying to work with structs.
Why is null lowercase?
This is probably a question for Walter, but maybe others know. Of all of the differences between C and D, the one which I have the most difficulty adapting to is null being lowercase. Does anyone know why this decision was made? -- Matthew Caron, Software Build Engineer Sixnet, a Red Lion business | www.sixnet.com +1 (518) 877-5173 x138 office
Re: Segfault in _d_dynamic_cast ()
On Thursday, 24 January 2013 at 10:14:29 UTC, Minas Mina wrote: I am trying to create a BVH tree structure to speed up raytracing. So far it has been fine. I have created the BVH tree. It works for 202 triangles/spheres. skipped Thanks. Requests for debugging help without source code are likely to be buried in archives silently. Perhaps you can look at _d_dynamic_cast source code (https://github.com/D-Programming-Language/druntime/blob/master/src/rt/cast_.d#L69) and figure out the exact statement which produces segfault.
Re: Why is null lowercase?
Matthew Caron: Of all of the differences between C and D, the one which I have the most difficulty adapting to is null being lowercase. Does anyone know why this decision was made? Probably because writing all in uppercase ugly. null is a keyword like the others, and they are in lowercase. DO YOU PREFER A LANGUAGE ALL IN UPPERCASE? Bye, bearophile
Re: Why is null lowercase?
On Thursday, 24 January 2013 at 12:56:03 UTC, Matthew Caron wrote: This is probably a question for Walter, but maybe others know. Of all of the differences between C and D, the one which I have the most difficulty adapting to is null being lowercase. Does anyone know why this decision was made? In the world of C and C++, 'NULL' is a macro. Macros, by convention, are all uppercase. Contrast that with C++11 which provides for 'nullptr', a type rather than a macro. Consider Java, which also has a lowercase null. In D, null follows the same convention as other built-ins, so it is lowercase. To me, it makes perfect sense. There are no macros in D, so I wouldn't have expected to see NULL to begin with. *That* would have been highly inconsistent.
Re: Why is null lowercase?
On Thursday, 24 January 2013 at 12:56:03 UTC, Matthew Caron wrote: This is probably a question for Walter, but maybe others know. Of all of the differences between C and D, the one which I have the most difficulty adapting to is null being lowercase. Does anyone know why this decision was made? Keep in mind that strictly speeking, NULL != null: NULL is a C macro that expands to 0. null is a D keyword that cannot be implicitly cast to an integer. This is a source of bugs: // void foo(int); void foo(int*); // in C++: foo(NULL); //Calls void foo(int) in D: foo(null); //Calls void foo(int*) Having code that is valid in both C++ and D, but having a different behavior would be VERY bad. BTW, you can be thankful that it is *just* null, because what it really is C++11's null_ptr. Which is worst.
Re: Why is null lowercase?
Hi, In C, NULL is a #define, and #defines are typically all-caps. In D, null is real keyword recognized by the compiler, and those are typically lowercase. I am just guessing here, but I'd say the choice for 'null' instead of 'NULL' is just to be coherent with this. Personally, I kinda like 'null'. :-) LMB On Thu, Jan 24, 2013 at 10:56 AM, Matthew Caron matt.ca...@redlion.net wrote: This is probably a question for Walter, but maybe others know. Of all of the differences between C and D, the one which I have the most difficulty adapting to is null being lowercase. Does anyone know why this decision was made? -- Matthew Caron, Software Build Engineer Sixnet, a Red Lion business | www.sixnet.com +1 (518) 877-5173 x138 office
Re: Pull 1019
Thanks for your answer. That explains my question. I would love to see an official statement about this pull and this feature. But neither in the related threads or here in learn I get such statement. That is very sad because this feature is very important and long discussed.
Re: Pull 1019
On Thursday, 24 January 2013 at 13:42:36 UTC, Namespace wrote: Thanks for your answer. That explains my question. I would love to see an official statement about this pull and this feature. But neither in the related threads or here in learn I get such statement. That is very sad because this feature is very important and long discussed. And I must add: I read so often that Walter does not like to break existing code. But with dmd 2.061 structs aren't lvalues anymore (that was a correct decision) but auto ref (which would solve the problem and prevent breaking existing code) wasn't merged and it seems that this feature isn't that relevant if I look on the merge history. That a bit weird to me.
Re: Passing opaque struct between functions/modules
On Wednesday, 23 January 2013 at 16:33:08 UTC, Sarath Kumar wrote: DMD v2.61; openSUSE 12.1 Source: --- libA.d: module libA; extern (C) { struct Opaque; Opaque* getObject(); void doSomething(Opaque *); } -- libB.d: module libB; extern (C) { struct Opaque; void doAction(Opaque *); } --- bug.d import libA, libB; int main(string[] args) { auto opaque = libA.getObject(); libA.doSomething(opaque); // this is okay libB.doAction(opaque); // but this is not, compiler error here return 0; } When I compile the above files, I get the below error. $ rdmd bug.d bug.d(7): Error: function libB.doAction (Opaque*) is not callable using argument types (Opaque*) bug.d(7): Error: cannot implicitly convert expression (opaque) of type Opaque* to Opaque* If I do an explicit cast, libB.Opaque*, for opaque in line 7, bug.d, I get completely different set of errors. $ rdmd bug.d libB.d(5): Error: struct libB.Opaque unknown size libB.d(5): Error: struct libB.Opaque no size yet for forward reference libB.d(5): Error: struct libB.Opaque unknown size libB.d(5): Error: struct libB.Opaque no size yet for forward reference libA.d(5): Error: struct libA.Opaque unknown size libA.d(5): Error: struct libA.Opaque no size yet for forward reference Can someone please tell me the right way to pass an opaque object between module's functions. -- Thanks, Sarath You have hit one of the D problems regarding extern(). The first problem is that extern(C)-declared objects inside functions are still mangled, the other problem is that extern(C) Type var; still creates var object, unlike C does (except when Type is a function pointer). The following D program is compiled and linked: extern(C) int i; void main() { i = 0; } However, a C equivalent would result in linking error due to unresolved i reference. So, what you are really doing is unusable. By the way, doing this way you are actually defining two different structs, libA.Opaque and libB.Opaque. Compiler is right in this case, because these types are incompatible, but it should print full names to show the difference explicitly. If you are working with C library, you can use following scheme: --main.d extern extern(C) struct Opaque; extern extern(C) Opaque* getObject(); void main() { Opaque* ptr = getObject(); } -struct.c--- struct Opaque { int i; double d; }; struct Opaque op; struct Opaque* getObject() { return op; } and if you are using D code, you should use .di files.
Re: Pull 1019
On Thursday, 24 January 2013 at 13:51:27 UTC, Namespace wrote: On Thursday, 24 January 2013 at 13:42:36 UTC, Namespace wrote: Thanks for your answer. That explains my question. I would love to see an official statement about this pull and this feature. But neither in the related threads or here in learn I get such statement. That is very sad because this feature is very important and long discussed. And I must add: I read so often that Walter does not like to break existing code. break *cough* valid *cough* existing code. This wasn't really a new/changed feature that broke your code. It was just something that worked that never should have worked. I know it sucks being on your end, but that's how it is.
Singleton Pattern with struct
Hi, I am trying to figure out the singleton pattern with a struct instead of a class: [code] struct Singleton { private : this( int a = 0 ) {} ; static Singleton * s ; public : @disable this() ; static ref Singleton instance() { if ( s is null ) s = new Singleton( 0 ) ; return * s ; } int val = 0 ; } [/code] This compiles, but when I use it: [code] auto s = Singleton.instance ; writeln( s.val ) ; Singleton.instance.val = 2 ; writeln( s.val ) ; [/code] I get: 0 0 Where is my mistake ? Cheers, PP !
Re: Passing opaque struct between functions/modules
On Thursday, 24 January 2013 at 11:52:57 UTC, Mike Parker wrote: The only potential bug I see here is in the error message. What you're seeing is a conflict that arises from D's name mangling. The doSomething in libA is expecting a parameter of type libA.Opaque* and getObject is returning the same, whereas the functions in libB are expecting a parameter of type libB.Opaque*. It is a bug because even after casting, the compiler gives an error. The compiler wants to know the size of the opaque object, even though I'm dealing with a pointer only. As Maxim Fomin mentioned, the compiler is trying to create an instance of the object even when it is declared as extern (C) and it is a pointer. -- Thanks, Sarath
Re: Singleton Pattern with struct
On Thursday, 24 January 2013 at 14:11:10 UTC, ParticlePeter wrote: Hi, I am trying to figure out the singleton pattern with a struct instead of a class: [code] struct Singleton { private : this( int a = 0 ) {} ; static Singleton * s ; public : @disable this() ; static ref Singleton instance() { if ( s is null ) s = new Singleton( 0 ) ; return * s ; } int val = 0 ; } [/code] This compiles, but when I use it: [code] auto s = Singleton.instance ; writeln( s.val ) ; Singleton.instance.val = 2 ; writeln( s.val ) ; [/code] I get: 0 0 Where is my mistake ? Cheers, PP ! Even if Singleton.instance returns by ref, s object is still stack-allocated struct, which is not affected by further modification of private pointer. import core.stdc.stdio : printf; struct Singleton { private : this( int a = 0 ) {} ; static Singleton * s ; public : @disable this() ; static ref Singleton instance() { if ( s is null ) s = new Singleton(0) ; return * s ; } int val = 0 ; } void main() { auto s = Singleton.instance ; printf( %d\n, s.val ) ; //0 Singleton.instance.val = 2 ; printf( %d\n, s.val ) ; // also 0 printf( %d\n, Singleton.instance.val); // is 2 as expected }
Re: Singleton Pattern with struct
On 2013-01-24 15:43, Maxim Fomin wrote: Even if Singleton.instance returns by ref, s object is still stack-allocated struct, which is not affected by further modification of private pointer. The struct is allocated using new. -- /Jacob Carlborg
Re: Singleton Pattern with struct
Even if Singleton.instance returns by ref, s object is still stack-allocated struct, which is not affected by further modification of private pointer. But where and when is ( a second ? ) Singleton created or duplicated ? The only ctor is in the static instance ( it is called only once according to my debugger ) and allocates a Singleton instance on the Heap ( as far as I understand new Struct ). The return statement does return a reference ( to a pointer, even that shouldn't be necessary ) so I would expect ... well a reference and not a copy. So where does the second object come from ?
Re: Singleton Pattern with struct
On Thursday, 24 January 2013 at 15:05:15 UTC, Jacob Carlborg wrote: On 2013-01-24 15:43, Maxim Fomin wrote: Even if Singleton.instance returns by ref, s object is still stack-allocated struct, which is not affected by further modification of private pointer. The struct is allocated using new. This is about auto s = in main, not about new in method. Type of s is Singleton, not Singleton* or ref Singleton. Singleton s = Singleton.instance; // is compiled when Singleton* s = Singleton.instance; // is not - Error: cannot implicitly convert // expression (instance()) of type Singleton to Singleton*
Re: Pull 1019
break *cough* valid *cough* existing code. This wasn't really a new/changed feature that broke your code. It was just something that worked that never should have worked. Ok, ok, it wasn't a valid solution but it was the only solution for handy programming with structs. We have still nothing which is compareable with the rvalue ref of C++ and now where this handy programming with structs is gone you have to write your code twice: for ref and for not ref. That is annoying. I know it sucks being on your end, but that's how it is. Yes it sucks and I hope it will change in the near future, but I'm not sure. Maybe I should get to like the idea that I have to write my code twice. Who knows how long it takes to merge this pull or to find another solution...
Re: Singleton Pattern with struct
Got it, thanks, I changed the instance method to: [code] static Singleton * instance() { if ( s is null ) s = new Singleton( 0 ) ; return s ; } [\code] and everything works as expected. Cheers, PP !
Re: Singleton Pattern with struct
On Thursday, 24 January 2013 at 15:50:34 UTC, ParticlePeter wrote: Got it, thanks, I changed the instance method to: [code] static Singleton * instance() { if ( s is null ) s = new Singleton( 0 ) ; return s ; } [\code] and everything works as expected. Cheers, PP ! Yes, but this can be broken by: import core.stdc.stdio : printf; struct Singleton { private : this( int a = 0 ) {} ; static Singleton * s ; public : @disable this() ; static Singleton* instance() { if ( s is null ) s = new Singleton(0) ; return s ; } int val = 0 ; } void main() { Singleton s = * Singleton.instance; printf( %d\n, s.val ) ; // Singleton.instance.val = 2 ; printf( %d\n, s.val ) ; //0 } Here s is explicitly defined to be a struct object, not pointer (reference), so main.s is independent of further modification of Singleton.instance.
Re: S-Expressions
On Wednesday, 23 January 2013 at 17:49:23 UTC, bearophile wrote: We are getting to the Mathematica again: http://rosettacode.org/wiki/Rosetta_Code/Rank_languages_by_popularity Bye, bearophile We're even now ;) http://rosettacode.org/wiki/Rosetta_Code/Rank_languages_by_popularity#D
Re: Singleton Pattern with struct
On Thursday, 24 January 2013 at 16:07:36 UTC, Maxim Fomin wrote: Yes, but this can be broken by: void main() { Singleton s = * Singleton.instance; printf( %d\n, s.val ) ; // Singleton.instance.val = 2 ; printf( %d\n, s.val ) ; //0 } Here s is explicitly defined to be a struct object, not pointer (reference), so main.s is independent of further modification of Singleton.instance. I'm not sure but this seems like one of the few appropriate places i would just make a normal struct and just use a global variable. True there could 'be' multiple instances of these singletons, but only ever making one ensures it would work right so long as you cannot copy it. Wasn't disabling this(this) and opAssign the way to ensure that didn't happen? Course if you didn't and you relied on the instance one, and you cannot copy then you could only pass by reference or be required to use .instance every time you needed it. Seems a bit excessive. Hmmm. You could separate the data and remove the pointer... then use alias this. [code] struct Singleton { static SingletonData single; alias single this; @disable this(this); //disable copy/assignment? Not that it would matter... //copying nothing does nothing, as there's nothing here. private static struct SingletonData { //methods and data here. } } [/code]
Re: Singleton Pattern with struct
On Thursday, 24 January 2013 at 16:17:34 UTC, Era Scarecrow wrote: On Thursday, 24 January 2013 at 16:07:36 UTC, Maxim Fomin wrote: Yes, but this can be broken by: void main() { Singleton s = * Singleton.instance; printf( %d\n, s.val ) ; // Singleton.instance.val = 2 ; printf( %d\n, s.val ) ; //0 } Here s is explicitly defined to be a struct object, not pointer (reference), so main.s is independent of further modification of Singleton.instance. I'm not sure but this seems like one of the few appropriate places i would just make a normal struct and just use a global variable. True there could 'be' multiple instances of these singletons, but only ever making one ensures it would work right so long as you cannot copy it. Wasn't disabling this(this) and opAssign the way to ensure that didn't happen? Course if you didn't and you relied on the instance one, and you cannot copy then you could only pass by reference or be required to use .instance every time you needed it. Seems a bit excessive. Hmmm. You could separate the data and remove the pointer... then use alias this. [code] struct Singleton { static SingletonData single; alias single this; @disable this(this); //disable copy/assignment? Not that it would matter... //copying nothing does nothing, as there's nothing here. private static struct SingletonData { //methods and data here. } [/code] I agree, but disabling ctors makes creating module-level object tricky. Static struct initialization might help.
Re: Singleton Pattern with struct
Yes, but this can be broken by: import core.stdc.stdio : printf; struct Singleton { private : this( int a = 0 ) {} ; static Singleton * s ; public : @disable this() ; static Singleton* instance() { if ( s is null ) s = new Singleton(0) ; return s ; } int val = 0 ; } void main() { Singleton s = * Singleton.instance; printf( %d\n, s.val ) ; // Singleton.instance.val = 2 ; printf( %d\n, s.val ) ; //0 } Here s is explicitly defined to be a struct object, not pointer (reference), so main.s is independent of further modification of Singleton.instance. O.k. good to know, I'll try to avoid this. But one thing is still not clear, This method here ( my first approach ) does return a reference to an object on the heap, right ? static ref Singleton instance() { if ( s is null ) s = new Singleton( 0 ) ; return * s ; } so when I use it with: auto another_s = Singleton.instance ; Why is the s inside the struct and another_s not identical ? Afaik that is the purpose of the ref keyword ?
Re: Singleton Pattern with struct
On 01/24/2013 08:52 AM, ParticlePeter wrote: This method here ( my first approach ) does return a reference to an object on the heap, right ? Yes, but the caller does not get a reference. static ref Singleton instance() { if ( s is null ) s = new Singleton( 0 ) ; return * s ; } so when I use it with: auto another_s = Singleton.instance ; Why is the s inside the struct and another_s not identical ? Afaik that is the purpose of the ref keyword ? When you print the type of another_s you will see that it is not a ref, because unlike C++, D does not have local ref variables; it has pointers for that purpose. import std.stdio; ref int foo() { return *new int; } void main() { auto i = foo(); writeln(typeid(i)); } Prints 'int', not 'ref int'. So, i is a copy of the dynamically created int. Ali
Re: Why is null lowercase?
On Thursday, 24 January 2013 at 12:56:03 UTC, Matthew Caron wrote: This is probably a question for Walter, but maybe others know. Of all of the differences between C and D, the one which I have the most difficulty adapting to is null being lowercase. Does anyone know why this decision was made? You'll get used to it, it's actually much better than typing in NULL, and it's a real type instead on an int, which never worked well in C. Just be warned that when checking for null *do not* use equality operator if ( ptr == null) ... instead use the identity operator is if ( ptr is null) ... for not null checks if ( ptr !is null) ... BTW, half of what you thought worked well in C/C++ will get turned upside down if you stick with D, and once you get it, moving back to C/C++ becomes unbearable. --rt
Getting the parameters of a struct/class constructor
Hello all, Is there a way to construct a tuple of the types that need to be passed to a struct or class's constructor? I tried using ParameterTypeTuple either on the class or its constructor: ParameterTypeTuple!A or ParameterTypeTuple!(A.this) ... but neither works: the former generates an error, Error: template instance ParameterTypeTuple!(A) ParameterTypeTuple!(A) does not match template declaration ParameterTypeTuple(func...) if (func.length == 1 isCallable!(func)) while the latter generates, Error: identifier expected following '.', not 'this' A (broken) bit of sample code is attached which illustrates what I'm trying to achieve. Can anyone advise? Thanks best wishes, -- Joe import std.stdio, std.traits; struct A { private immutable int _a; private immutable double _b; this(int a, double b) { _a = a; _b = b; } auto alpha() @property { return _a; } auto beta() @property { return _b; } } struct B { A one; A two; this(ParameterTypeTuple!A inputOne, ParameterTypeTuple!A inputTwo) { one = A(inputOne); two = A(inputTwo); } } void main() { auto join = B(1, 3.2, 5, 6.9); writeln(join.one.alpha, \t, join.one.beta); writeln(join.two.alpha, \t, join.two.beta); }
Re: Singleton Pattern with struct
On Thursday, 24 January 2013 at 17:00:44 UTC, Ali Çehreli wrote: On 01/24/2013 08:52 AM, ParticlePeter wrote: This method here ( my first approach ) does return a reference to an object on the heap, right ? Yes, but the caller does not get a reference. Actually the caller gets the reference (which is a pointer from low-level POV), but allocates on stack struct object, and then does copy from returned reference to that stack object. static ref Singleton instance() { if ( s is null ) s = new Singleton( 0 ) ; return * s ; } so when I use it with: auto another_s = Singleton.instance ; Why is the s inside the struct and another_s not identical ? Afaik that is the purpose of the ref keyword ? When you print the type of another_s you will see that it is not a ref, because unlike C++, D does not have local ref variables; it has pointers for that purpose. Yes, that the point - D does not have references like C++. And I should thought about C++ influence on understanding D :) import std.stdio; ref int foo() { return *new int; } void main() { auto i = foo(); writeln(typeid(i)); } Prints 'int', not 'ref int'. So, i is a copy of the dynamically created int. Ali
Re: Singleton Pattern with struct
On 01/24/13 17:52, ParticlePeter wrote: Yes, but this can be broken by: import core.stdc.stdio : printf; struct Singleton { private : this( int a = 0 ) {} ; static Singleton * s ; public : @disable this() ; static Singleton* instance() { if ( s is null ) s = new Singleton(0) ; return s ; } int val = 0 ; } void main() { Singleton s = * Singleton.instance; printf( %d\n, s.val ) ; // Singleton.instance.val = 2 ; printf( %d\n, s.val ) ; //0 } Here s is explicitly defined to be a struct object, not pointer (reference), so main.s is independent of further modification of Singleton.instance. O.k. good to know, I'll try to avoid this. But one thing is still not clear, This method here ( my first approach ) does return a reference to an object on the heap, right ? static ref Singleton instance() { if ( s is null ) s = new Singleton( 0 ) ; return * s ; } so when I use it with: auto another_s = Singleton.instance ; Why is the s inside the struct and another_s not identical ? Afaik that is the purpose of the ref keyword ? There currently are no reference variables in D [1]; the only way to get a reference to something is via function arguments (including implicit method ones) and function returns. So assigning a ref-return means a copy. You can workaround it like this: struct Singleton { private: this( int a = 0 ) {} ; static Singleton* s ; public: @disable this(); @disable this(this); static instance() @property { static struct Ref(T) { T* obj; ref g() @property { return *obj; } alias obj this; @disable this(this); } if ( s is null ) s = new Singleton( 0 ) ; return Ref!(typeof(this))(s) ; } int val = 0 ; } though, that's not how I'd do it. artur [1] Classes don't count; they are a reference /types/.
Re: Getting the parameters of a struct/class constructor
On 1/24/13, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: On 1/24/13, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote: ParameterTypeTuple!(A.this) Use ParameterTypeTuple!(A.__ctor) If you have multiple constructors you can pick the parameters with a helper template: import std.traits, std.string; struct A { this(int a, double b) { } this(float y) { } } template PickCtorParams(Type, size_t index) { enum ctorLen = __traits(getOverloads, Type, __ctor).length; static if (index ctorLen) { alias ParameterTypeTuple!(__traits(getOverloads, A, __ctor)[index]) PickCtorParams; } else { static assert(0, format(index %s exceeds %s ctors for type %s, index, ctorLen, Type.stringof)); } } void main() { pragma(msg, PickCtorParams!(A, 0)); // (int, double) pragma(msg, PickCtorParams!(A, 1)); // (float) pragma(msg, PickCtorParams!(A, 2)); // out of bounds }
Re: Singleton Pattern with struct
On 01/24/13 18:14, Artur Skawina wrote: struct Singleton { private: this( int a = 0 ) {} ; static Singleton* s ; public: @disable this(); @disable this(this); static instance() @property { static struct Ref(T) { T* obj; ref g() @property { return *obj; } alias obj this; @disable this(this); } if ( s is null ) s = new Singleton( 0 ) ; return Ref!(typeof(this))(s) ; } int val = 0 ; } Grr. What I meant to write was of course: static struct Ref(T) { T* obj; ref g() @property { return *obj; } alias g this; @disable this(this); } Sorry, artur
Re: Singleton Pattern with struct
On Thursday, 24 January 2013 at 17:00:44 UTC, Ali Çehreli wrote: On 01/24/2013 08:52 AM, ParticlePeter wrote: This method here ( my first approach ) does return a reference to an object on the heap, right ? Yes, but the caller does not get a reference. static ref Singleton instance() { if ( s is null ) s = new Singleton( 0 ) ; return * s ; } so when I use it with: auto another_s = Singleton.instance ; Why is the s inside the struct and another_s not identical ? Afaik that is the purpose of the ref keyword ? When you print the type of another_s you will see that it is not a ref, because unlike C++, D does not have local ref variables; it has pointers for that purpose. import std.stdio; ref int foo() { return *new int; } void main() { auto i = foo(); writeln(typeid(i)); } Prints 'int', not 'ref int'. So, i is a copy of the dynamically created int. Ali Thanks, I re-read the purpose of ref type function() in the D programming language, and the sole purpose is that such a function call can be directly a parameter to another function expecting a ref ? As: ref int foo() { return some class member ; } void bar( ref int data ) { do something with data ; } This means, it is never ever possible to initialize any variable with a reference some class/struct member data ? Unless I return the address of the member data ?
Re: Getting the parameters of a struct/class constructor
On 01/24/2013 06:14 PM, Andrej Mitrovic wrote: On 1/24/13, Joseph Rushton Wakeling joseph.wakel...@webdrake.net wrote: ParameterTypeTuple!(A.this) Use ParameterTypeTuple!(A.__ctor) Brilliant. Thanks very much. :-)
Re: Singleton Pattern with struct
On Thursday, 24 January 2013 at 17:21:38 UTC, Artur Skawina wrote: On 01/24/13 17:52, ParticlePeter wrote: Yes, but this can be broken by: import core.stdc.stdio : printf; struct Singleton { private : this( int a = 0 ) {} ; static Singleton * s ; public : @disable this() ; static Singleton* instance() { if ( s is null ) s = new Singleton(0) ; return s ; } int val = 0 ; } void main() { Singleton s = * Singleton.instance; printf( %d\n, s.val ) ; // Singleton.instance.val = 2 ; printf( %d\n, s.val ) ; //0 } Here s is explicitly defined to be a struct object, not pointer (reference), so main.s is independent of further modification of Singleton.instance. O.k. good to know, I'll try to avoid this. But one thing is still not clear, This method here ( my first approach ) does return a reference to an object on the heap, right ? static ref Singleton instance() { if ( s is null ) s = new Singleton( 0 ) ; return * s ; } so when I use it with: auto another_s = Singleton.instance ; Why is the s inside the struct and another_s not identical ? Afaik that is the purpose of the ref keyword ? There currently are no reference variables in D [1]; the only way to get a reference to something is via function arguments (including implicit method ones) and function returns. So assigning a ref-return means a copy. You can workaround it like this: struct Singleton { private: this( int a = 0 ) {} ; static Singleton* s ; public: @disable this(); @disable this(this); static instance() @property { static struct Ref(T) { T* obj; ref g() @property { return *obj; } alias obj this; @disable this(this); } if ( s is null ) s = new Singleton( 0 ) ; return Ref!(typeof(this))(s) ; } int val = 0 ; } though, that's not how I'd do it. artur [1] Classes don't count; they are a reference /types/. Well ... I think I as well would not wanna do it like this, thanks :-) I'm fine with returning and using a pointer, fortunately there is no difference in syntax as in c, so it doesn't matter.
Re: Singleton Pattern with struct
On 01/24/2013 09:26 AM, ParticlePeter wrote: Thanks, I re-read the purpose of ref type function() in the D programming language, and the sole purpose is that such a function call can be directly a parameter to another function expecting a ref ? As Maxim Fomin noted, I didn't word it correctly: The caller does get a reference to the returned object. So, the sole purpose is not to pass a variable to a ref-taking function. As: ref int foo() { return some class member ; } void bar( ref int data ) { do something with data ; } This means, it is never ever possible to initialize any variable with a reference some class/struct member data ? Unless I return the address of the member data ? Not true. There are no local ref variables nor ref member variables in D. All you need to do is to use pointers instead: ref int foo() { return *new int; } struct S { int i; int * j; this(int i) { this.i = i; this.j = foo(); // member pointer } } void main() { int* i = foo(); // local pointer } No, the pointer syntax is not the cleanest. :) Ali
Re: Singleton Pattern with struct
On 01/24/13 18:35, ParticlePeter wrote: On Thursday, 24 January 2013 at 17:21:38 UTC, Artur Skawina wrote: On 01/24/13 17:52, ParticlePeter wrote: Why is the s inside the struct and another_s not identical ? Afaik that is the purpose of the ref keyword ? There currently are no reference variables in D [1]; the only way to get a reference to something is via function arguments (including implicit method ones) and function returns. So assigning a ref-return means a copy. You can workaround it like this: struct Singleton { private: this( int a = 0 ) {} ; static Singleton* s ; public: @disable this(); @disable this(this); static instance() @property { static struct Ref(T) { T* obj; ref g() @property { return *obj; } alias g this; @disable this(this); } if ( s is null ) s = new Singleton( 0 ) ; return Ref!(typeof(this))(s) ; } int val = 0 ; } Well ... I think I as well would not wanna do it like this, thanks :-) I'm fine with returning and using a pointer, fortunately there is no difference in syntax as in c, so it doesn't matter. Careful, at some point you'll end up doing s[1] etc, and /then/ it matters. The Ref struct is actually the way to deal with ref types in D; what I meant by 'that's not how I'd do it' is that it might be better to use a global (well, thread-local module-field in D) etc. artur
Re: Why is null lowercase?
On 01/24/2013 04:56 AM, Matthew Caron wrote: This is probably a question for Walter, but maybe others know. Of all of the differences between C and D, the one which I have the most difficulty adapting to is null being lowercase. Does anyone know why this decision was made? Similarly, the common macros TRUE and FALSE are replaced by the 'true' and 'false' keywords. Ali
Re: Getting the parameters of a struct/class constructor
There may be more than one this, so you'll have to specify the args for each specific constructor manually. Disclaimer: Someone else may have a better solution as I'm not that much of an expert in this area. This sample may point you in the right direction ... import std.typetuple; struct X { alias TypeTuple!(int, double) CONSTUCT1; alias TypeTuple!(int, double, string) CONSTUCT2; this( CONSTUCT1 args ) { alias args[0] a_int; alias args[0] a_double; _a = a_int; _b = b_double; } this( CONSTUCT2[0] a_int, CONSTUCT2[1] b_double, CONSTUCT2[2] c_string ) { _a = a_int; _b = b_double; writeln(c_string); } int _a; double _b; } void foo(X.CONSTUCT1[0] a, X.CONSTUCT1[1] b ) { ... } void bar(X.CONSTUCT2 args ) { alias args[0] a_int; alias args[1] a_double; alias args[2] a_string; ... } Hope this helps. --rt
Re: Singleton Pattern with struct
On Thursday, 24 January 2013 at 17:35:58 UTC, Ali Çehreli wrote: On 01/24/2013 09:26 AM, ParticlePeter wrote: Thanks, I re-read the purpose of ref type function() in the D programming language, and the sole purpose is that such a function call can be directly a parameter to another function expecting a ref ? As Maxim Fomin noted, I didn't word it correctly: The caller does get a reference to the returned object. So, the sole purpose is not to pass a variable to a ref-taking function. As: ref int foo() { return some class member ; } void bar( ref int data ) { do something with data ; } This means, it is never ever possible to initialize any variable with a reference some class/struct member data ? Unless I return the address of the member data ? Not true. There are no local ref variables nor ref member variables in D. All you need to do is to use pointers instead: ref int foo() { return *new int; } struct S { int i; int * j; this(int i) { this.i = i; this.j = foo(); // member pointer } } void main() { int* i = foo(); // local pointer } No, the pointer syntax is not the cleanest. :) Ali This is what I meant :-) I can't return a reference ( with reference I don't mean reference type, but semantically a reference ) to a class member, but I can return the address of this member, which, to my understanding is an implicit pointer. struct Foo { int val = 3 ; auto getValPtr() { return val ; } } Foo foo ; writeln( foo.val ) ; // = 3 auto valPtr = foo.getValPtr() ; * valPtr = 7 ; writeln( foo.val ) ; // = 7
Re: Singleton Pattern with struct
On Thursday, 24 January 2013 at 16:49:53 UTC, Maxim Fomin wrote: On Thursday, 24 January 2013 at 16:17:34 UTC, Era Scarecrow wrote: Hmmm. You could separate the data and remove the pointer... then use alias this. [code] struct Singleton { static SingletonData single; alias single this; @disable this(this); //disable copy/assignment? Not that it would matter... //copying nothing does nothing, as there's nothing here. private static struct SingletonData { //methods and data here. } [/code] I agree, but disabling ctors makes creating module-level object tricky. Static struct initialization might help. I'll have to agree. But in that case don't disable the default ctor (not that the Singleton has any contents anyways); Actually opAssign/postblit only needs to be disabled inside SingletonData. I'd think that would work. [code] struct Singleton { static SingletonData single; alias single this; private static struct SingletonData { @disable void opAssign(); //methods and data here. } } [/code]
Re: Getting the parameters of a struct/class constructor
You can use magic functions __ctor and __dtor which actually serve as constructor and destructor implementations behind the scene. Example and proof-of-concept: http://dpaste.1azy.net/fd924332 Have no idea if it is explicitly defined by spec somewhere though.
Re: Assembly - 64-bit registers supported?
On 01/24/2013 01:08 AM, dale wrote: I am following these helpful suggestions, but still having trouble linking properly. I have Visual Studio 10 and its 64-bit extension installed, and I believe the amd64\link.exe is getting called, but I must have something configured incorrectly, because it does not appear to find all of the libraries correctly. C:\prj\Ddmd -m64 hello64B.d C:\d\dmd2\windows\bin\..\lib\shell32.lib : warning LNK4003: invalid library format; library ignored C:\d\dmd2\windows\bin\..\lib\kernel32.lib : warning LNK4003: invalid library format; library ignored phobos64.lib(dmain2_4a8_47b.obj) : error LNK2019: unresolved external symbol GetCommandLineW referenced in function _d_run_main phobos64.lib(dmain2_4a8_47b.obj) : error LNK2019: unresolved external symbol CommandLineToArgvW referenced in function _d_run_main ... And zillions more unresolved externals follow. Why is it trying to include shell32.lib and kernel32.lib for a 64-bit app? Is that a problem? Any hints as to what I'm missing? Thanks, dale I think this has come up before, and it has something to do with some environment variables set in sc.ini and the MS linker picking up the libs supplied be dmd for win32 because of it. -- Mike Wey
Re: endless loop with ref and non-ref parameter
On Thursday, January 24, 2013 18:24:32 Namespace wrote: In relation to this post: http://forum.dlang.org/thread/hlyospppnjiziyokf...@forum.dlang.org?page=2#po st-qxqvreqpniftjnwxvqgt:40forum.dlang.org I dicided to test a bit with manual auto ref. This Code works as expected. [code] import std.stdio; struct A { public: } void foo(A a) { writeln(without ref); foo(a); } void foo(ref A a) { writeln(with ref); } void main() { foo(A()); } [/code] it prints: without ref with ref but if I change ref A a to ref const A a it turns into an endless loop. My question is: Is this behavior intended? I know const is part of the type, but shouldn't recognize the compiler this case? It's intended. constness matters more than refness when selecting a function overload. From the docs ( http://dlang.org/function.html#ufunction/u- overloading ): - Functions are overloaded based on how well the arguments to a function can match up with the parameters. The function with the best match is se lected. The levels of matching are: no match match with implicit conversions match with conversion to const exact match - So, you need to put const on the parameters for both functions, or you need to create other overloads which do. In general, if you're overloading on ref, make sure that the constness matches, or you're going to get infinite recursion. So, if you're mixing const and ref, then you're probably either going to want 4 different overloads (non-ref, ref, const non-ref, const ref) or 2 overloads which use inout instead of const (inout and inout ref). - Jonathan M Davis
Re: endless loop with ref and non-ref parameter
On 01/24/2013 11:33 AM, Jonathan M Davis wrote: It's intended. constness matters more than refness when selecting a function overload. From the docs ( http://dlang.org/function.html#ufunction/u- overloading ): - Functions are overloaded based on how well the arguments to a function can match up with the parameters. The function with the best match is se lected. The levels of matching are: no match match with implicit conversions match with conversion to const exact match - That doesn't explain why the first case selects the ref function: void foo(A a) { writeln(without ref); foo(a);// -- why is this foo(ref A)? } void foo(ref A a) { writeln(with ref); } foo(A) is the exact match there because the type of a is A. What is also considered in function selection is the rvalue-lvalue distinction, which shouldn't affect the outcome here either. Ali
Re: endless loop with ref and non-ref parameter
On Thursday, 24 January 2013 at 20:06:34 UTC, Ali Çehreli wrote: On 01/24/2013 11:33 AM, Jonathan M Davis wrote: It's intended. constness matters more than refness when selecting a function overload. From the docs ( http://dlang.org/function.html#ufunction/u-overloading ): - Functions are overloaded based on how well the arguments to a function can match up with the parameters. The function with the best match is selected. The levels of matching are: no match match with implicit conversions match with conversion to const exact match - That doesn't explain why the first case selects the ref function: void foo(A a) { writeln(without ref); foo(a);// -- why is this foo(ref A)? } Because your local variable (in the signature) becomes a lvalue and thereby reference-able. void foo(ref A a) { writeln(with ref); } foo(A) is the exact match there because the type of a is A. What is also considered in function selection is the rvalue-lvalue distinction, which shouldn't affect the outcome here either. In case David's explanation was too confusing, then let's look at it. If your variable is non-const, it will always select a non-const matching one first. If there is no matching non-const, it converts it to const, then tries again. void foo(A a) { writeln(without ref); //a is an lvalue but not const //Foo(A) matches closer. Infinite loop foo(a); } void foo(const ref A a) { writeln(with ref); } void foo2(A a) { writeln(foo2 - without ref); //const lvalue, foo(const ref A) is closer foo(cast(const A) a) //rvalue, postblit call foo(A) (if it can) foo(cast(const A) A()); } I know this very issue seems like a big annoyance, to me too. I'd say the order of preference should be const ref, const non-ref, ref, non-ref. But then you can't have const non const versions unless the signature differs, like ref, more input variables or the function itself is const. Until/unless that is changed all 4 versions need to be written (as David said) to make the proper calls.
Re: Why is null lowercase?
On 01/24/2013 12:50 PM, Ali Çehreli wrote: Similarly, the common macros TRUE and FALSE are replaced by the 'true' and 'false' keywords. Ironically, those don't bother me because I never used them. -- Matthew Caron, Software Build Engineer Sixnet, a Red Lion business | www.sixnet.com +1 (518) 877-5173 x138 office
Re: Why is null lowercase?
On 01/24/2013 12:04 PM, Rob T wrote: You'll get used to it, it's actually much better than typing in NULL, and it's a real type instead on an int, which never worked well in C. Just be warned that when checking for null *do not* use equality operator Yeah, the compiler helped me find that one out. That takes a little getting used to as well. Old habits and such. for not null checks if ( ptr !is null) ... And too much perl has me wanting to write: if (ptr is not null) BTW, half of what you thought worked well in C/C++ will get turned upside down if you stick with D, and once you get it, moving back to C/C++ becomes unbearable. It already is. I have very little desire to do anything in any other language. C and C++ are too primitive. Java and C# don't play as nicely with native libraries as I'd like and require a whole VM which consumes gobs of memory and takes forever to start. D gives me the features I want from Java and C# while falling somewhere between them and C in terms of speed. I can get more done, faster, in D. Meanwhile, it seems like the rest of the world is moving towards writing everything in JavaScript, and that's just leaving me scratching my head in amazement. -- Matthew Caron, Software Build Engineer Sixnet, a Red Lion business | www.sixnet.com +1 (518) 877-5173 x138 office
Re: endless loop with ref and non-ref parameter
On Thursday, January 24, 2013 12:06:33 Ali Çehreli wrote: On 01/24/2013 11:33 AM, Jonathan M Davis wrote: It's intended. constness matters more than refness when selecting a function overload. From the docs ( http://dlang.org/function.html#ufunction/u- overloading ): - Functions are overloaded based on how well the arguments to a function can match up with the parameters. The function with the best match is se lected. The levels of matching are: no match match with implicit conversions match with conversion to const exact match - That doesn't explain why the first case selects the ref function: void foo(A a) { writeln(without ref); foo(a); // -- why is this foo(ref A)? } void foo(ref A a) { writeln(with ref); } foo(A) is the exact match there because the type of a is A. What is also considered in function selection is the rvalue-lvalue distinction, which shouldn't affect the outcome here either. Whether an argument is an lvalue or rvalue is very important to the issue. That's _exactly_ why the ref overload gets called in the first case. If the argument is an lvalue, the ref overload is selected. If the argument is an rvalue, the non-ref overload is selected. const only enters into it _after_ that. - Jonathan M Davis
Re: endless loop with ref and non-ref parameter
On Thursday, 24 January 2013 at 20:06:34 UTC, Ali Çehreli wrote: On 01/24/2013 11:33 AM, Jonathan M Davis wrote: It's intended. constness matters more than refness when selecting a function overload. From the docs ( http://dlang.org/function.html#ufunction/u- overloading ): - Functions are overloaded based on how well the arguments to a function can match up with the parameters. The function with the best match is se lected. The levels of matching are: no match match with implicit conversions match with conversion to const exact match - That doesn't explain why the first case selects the ref function: void foo(A a) { writeln(without ref); foo(a);// -- why is this foo(ref A)? } void foo(ref A a) { writeln(with ref); } foo(A) is the exact match there because the type of a is A. What is also considered in function selection is the rvalue-lvalue distinction, which shouldn't affect the outcome here either. Ali From http://dlang.org/function.html If two or more functions have the same match level, then partial ordering is used to try to find the best match. Partial ordering finds the most specialized function. If neither function is more specialized than the other, then it is an ambiguity error. Partial ordering is determined for functions f() and g() by taking the parameter types of f(), constructing a list of arguments by taking the default values of those types, and attempting to match them against g(). If it succeeds, then g() is at least as specialized as f(). It is possible to pass an lvalue to both ref and non-ref parameters, however rvalue cannot be passed to ref-parameter. Hence ref version for lvalue is more specialized and selected.
Re: Getting the parameters of a struct/class constructor
On Thursday, 24 January 2013 at 18:41:31 UTC, mist wrote: You can use magic functions __ctor and __dtor which actually serve as constructor and destructor implementations behind the scene. Example and proof-of-concept: http://dpaste.1azy.net/fd924332 Have no idea if it is explicitly defined by spec somewhere though. If you have more than one ctor it seems to take the first one http://dpaste.1azy.net/b994fdf3 I don't know if you will able to rely on the order unless it's a part of the spec. --rt
Re: Segfault in _d_dynamic_cast ()
On Thursday, 24 January 2013 at 13:22:20 UTC, Maxim Fomin wrote: On Thursday, 24 January 2013 at 10:14:29 UTC, Minas Mina wrote: I am trying to create a BVH tree structure to speed up raytracing. So far it has been fine. I have created the BVH tree. It works for 202 triangles/spheres. skipped Thanks. Requests for debugging help without source code are likely to be buried in archives silently. Perhaps you can look at _d_dynamic_cast source code (https://github.com/D-Programming-Language/druntime/blob/master/src/rt/cast_.d#L69) and figure out the exact statement which produces segfault. The code can be found here: https://github.com/minas1/D_Raytracing The code that creates the BVH tree is in bvh.d. The code that prints the tree is in main.d.
Re: Getting the parameters of a struct/class constructor
On Thu, Jan 24, 2013 at 10:34 PM, Rob T al...@ucora.com wrote: On Thursday, 24 January 2013 at 18:41:31 UTC, mist wrote: You can use magic functions __ctor and __dtor which actually serve as constructor and destructor implementations behind the scene. Example and proof-of-concept: http://dpaste.1azy.net/fd924332 Have no idea if it is explicitly defined by spec somewhere though. If you have more than one ctor it seems to take the first one http://dpaste.1azy.net/b994fdf3 I don't know if you will able to rely on the order unless it's a part of the spec. IIRC, you can use __traits(getOverloads, mytype.__ctor) to get all constructor overloads. See: http://dlang.org/traits.html#getOverloads I used this in conjunction with __traits(getMember, ...) to get the entire list of member, overloads included.
Re: Getting the parameters of a struct/class constructor
On 1/24/13, Philippe Sigaud philippe.sig...@gmail.com wrote: IIRC, you can use __traits(getOverloads, mytype.__ctor) to get all constructor overloads. See: http://dlang.org/traits.html#getOverloads I used this in conjunction with __traits(getMember, ...) to get the entire list of member, overloads included. I don't understand why, but it seems DForum doesn't show up any of my posts. I've posted this as my second reply (hope this makes it): If you have multiple constructors you can pick the parameters with a helper template: import std.traits, std.string; struct A { this(int a, double b) { } this(float y) { } } template PickCtorParams(Type, size_t index) { enum ctorLen = __traits(getOverloads, Type, __ctor).length; static if (index ctorLen) { alias ParameterTypeTuple!(__traits(getOverloads, A, __ctor)[index]) PickCtorParams; } else { static assert(0, format(index %s exceeds %s ctors for type %s, index, ctorLen, Type.stringof)); } } void main() { pragma(msg, PickCtorParams!(A, 0)); // (int, double) pragma(msg, PickCtorParams!(A, 1)); // (float) pragma(msg, PickCtorParams!(A, 2)); // out of bounds }
Re: Coping files and folders
Brilliant! Thanks. I think the silent one has errors. But I've used the first function in my program now. With mine, strait after doing the copying is was supposed then update a file, but didn't. Your one seems to work though. On Thursday, 24 January 2013 at 08:58:06 UTC, monarch_dodra wrote: On Thursday, 24 January 2013 at 07:41:23 UTC, Jacob Carlborg wrote: On 2013-01-24 07:28, Joel wrote: How does one copy folders (with files in them) including sub folders, and creating any needed folders? Like: land\house\cat.d land\house\rat.exe land\house\bedroom\ants.txt to root\island\house\cat.d root\island\house\rat.exe root\island\house\bedroom\ants.txt One work around is to use 'system' (under std.process). I don't think Phobos currently has any functions for this. Someone posted code in these newsgroups of a parallel implementation of copy and remove. Mustn't be very hard to manually write copyDir. The problem with copyDir is its transactional behavior: What should it do in case of a failure mid copy? Bail? Cleanup? Continue? Anyways, I just threw this together. The first version bails on first error. The second version keeps going as much as it can, and returns true on success. The caller is then free to (or not to) call rmdirRecurse in case of failure. //Throws exception on first error. void copyDir(string inDir, string outDir) { if (!exists(outDir)) mkdir(outDir); else if (!isDir(outDir)) throw new FileException(format(Destination path %s is not a folder., outDir)); foreach (entry; dirEntries(inDir.idup, SpanMode.shallow)) { auto fileName = baseName(entry.name); auto destName = buildPath(outDir, fileName); if (entry.isDir()) copyDir(entry.name, destName); else copy(entry.name, destName); } } //Silently keeps going as much as it can, then returns true on success, //or false if an error occured. bool copyDirSilent(string inDir, string outDir) { if (!exists(outDir)) { auto e = collectException(mkdir(outDir)); if (e !is null) return false; } else if (!isDir(outDir)) return false; foreach (entry; dirEntries(inDir, SpanMode.shallow)) { auto fileName = baseName(entry.name); auto destName = buildPath(outDir, fileName); if (entry.isDir()) { bool b = copyDirSilent(entry.name, destName); if (b == false) return false; } else { auto e = collectException(mkdir(outDir)); if (e !is null) return false; } } return true; }
Re: Getting the parameters of a struct/class constructor
On Thursday, 24 January 2013 at 22:49:33 UTC, Andrej Mitrovic wrote: On 1/24/13, Philippe Sigaud philippe.sig...@gmail.com wrote: IIRC, you can use __traits(getOverloads, mytype.__ctor) to get all constructor overloads. See: http://dlang.org/traits.html#getOverloads I used this in conjunction with __traits(getMember, ...) to get the entire list of member, overloads included. I don't understand why, but it seems DForum doesn't show up any of my posts. I've posted this as my second reply (hope this makes it): The thread got split up into two separate threads. Your missing post shows up in the split. I really hate it when it does this. --rt
Re: endless loop with ref and non-ref parameter
On 01/24/2013 12:25 PM, Era Scarecrow wrote: What is also considered in function selection is the rvalue-lvalue distinction, which shouldn't affect the outcome here either. In case David's explanation was too confusing, then let's look at it. If your variable is non-const, it will always select a non-const matching one first. If there is no matching non-const, it converts it to const, then tries again. void foo(A a) { writeln(without ref); //a is an lvalue but not const //Foo(A) matches closer. Infinite loop And that's exactly why this issue is so confusing. Normally, const vs. immutable parameters are different in the way that they accept arguments: - immutable is limiting because it insists that the argument is immutable. - const is welcoming because it accepts mutable, const, and immutable. However, according to your example and explanation above, in this case const is not welcoming but limiting! What the example shows is that, because the following function takes 'const ref A', now it wants 'const A' but not 'A'. See, how in this case 'const' is not welcoming? That is the problem in this whole confusing situation. If there is another explanation that would bring sanity to the way I see things, I would love to hear about it. Does my understanging above regarding limiting vs. welcoming off? Perhaps that's where I go wrong? foo(a); } void foo(const ref A a) { writeln(with ref); } void foo2(A a) { writeln(foo2 - without ref); //const lvalue, foo(const ref A) is closer foo(cast(const A) a) //rvalue, postblit call foo(A) (if it can) foo(cast(const A) A()); } Ali
Re: Why is null lowercase?
On 01/24/2013 12:42 PM, Matthew Caron wrote: for not null checks if ( ptr !is null) ... And too much perl has me wanting to write: if (ptr is not null) IIRC, the !is operator is thanks to bearophile. We would have to reverse the logic before he insisted on !is: :) if (!(ptr is null)) Ali
Re: S-Expressions
qznc: We're even now ;) http://rosettacode.org/wiki/Rosetta_Code/Rank_languages_by_popularity#D I have cut some lines, and I have used a more functional style, that fits well for this entry. Compared to the C++ entry this D entry is nicer. I greatly prefer the verbose option of the Python regex. And g for regexes should be the default. This D code: auto pairs = categories.match(r2) .filter!(m = languages.canFind(m[1]))() .map!(m = tuple(m[2].to!uint(), m[1].dup))() .array(); With a Python-like syntax becomes nicer: auto pairs = [(r.to!uint, l.dup) for l,r in categories.match(r2) if l in languages]; Bye, bearophile
Re: endless loop with ref and non-ref parameter
On Thursday, January 24, 2013 17:13:36 Ali Çehreli wrote: On 01/24/2013 12:25 PM, Era Scarecrow wrote: What is also considered in function selection is the rvalue-lvalue distinction, which shouldn't affect the outcome here either. In case David's explanation was too confusing, then let's look at it. If your variable is non-const, it will always select a non-const matching one first. If there is no matching non-const, it converts it to const, then tries again. void foo(A a) { writeln(without ref); //a is an lvalue but not const //Foo(A) matches closer. Infinite loop And that's exactly why this issue is so confusing. Normally, const vs. immutable parameters are different in the way that they accept arguments: - immutable is limiting because it insists that the argument is immutable. - const is welcoming because it accepts mutable, const, and immutable. However, according to your example and explanation above, in this case const is not welcoming but limiting! What the example shows is that, because the following function takes 'const ref A', now it wants 'const A' but not 'A'. See, how in this case 'const' is not welcoming? That is the problem in this whole confusing situation. If there is another explanation that would bring sanity to the way I see things, I would love to hear about it. Does my understanging above regarding limiting vs. welcoming off? Perhaps that's where I go wrong? I've never heard anyone describe it that way before. const is more generic, whereas immutable is more specific. But from the compiler's point of view, passing a non-const object to a const function means doing a conversion (from mutable to const), whereas calling a function of the same type does not require a conversion. I believe that _that_ is the core of why ref takes precedence over const. The overload rules avoid converting types as much as possible. So, if you have auto foo(A a) {...} //#1 auto foo(const A a) {...} //#2 A a; const A ca; foo(a); //calls #1 foo(ca); //calls #2 The same goes with ref. When passing an lvalue, the ref requires no conversion or copy, whereas without ref, a copy is required. So, auto foo(A a) {...} //#1 auto foo(ref A a) {...} //#2 A a; foo(a); //calls #2 foo(createA()); //calls #1 The question is what happens when you start mixing const and ref. You have to choose which has precedence. It's obvious what to do when you have all of the combinations auto foo(A a) {...} //#1 auto foo(ref A) {...} #2 auto foo(const A) {...} //#3 auto foo(ref const A) {...} //#4 A a; const A ca; foo(a); //Calls #2 foo(ca); //Calls #4 foo(createA()); //Calls #1 foo(createConstA()); //Calls #3 The problem is what to do when you only have a subset: auto foo(ref A) {...} #2 auto foo(const A) {...} //#3 A a; const A ca; foo(a); //Calls #2 foo(ca); //Calls #3 foo(createA()); //Calls #3 foo(createConstA()); //Calls #3 or auto foo(A a) {...} //#1 auto foo(ref const A) {...} //#4 A a; const A ca; foo(a); //Calls #4 foo(ca); //Calls #4 foo(createA()); //Calls #1 foo(createConstA()); //Calls #1 or etc... The compiler _has_ to pick either const or ref as having higher precedence. ref was almost certainly chosen as having higher precedence because it avoids a conversion, but also by picking ref, you end up with fewer unnecessary copies, making it the more efficient choice. So, from the standpoint of both type conversions and efficiency, it makes more sense for ref to have precedence over const than the other way around. The reality of the matter is that regardless of whether const or ref had precedence, you'd still need all 4 overloads or you'd have problems. auto ref and inout can help reduce the number of overloads required, but the function needs to accept all of the type combinations in order to avoid having to convert the type or make unnecessary copies. - Jonathan M Davis
From package import syntax
This is the current syntax to import several modules from the std package: import std.stdio, std.algorithm, std.range, std.array; This is the syntax to import names from a module: import std.stdio: writeln, write; Currently this is not accepted, but do you like a syntax to import modules that is more consistent (the same as the one used to import names from a module)? import std: stdio, algorithm, range, array; Bye, bearophile
Re: From package import syntax
On 1/25/13, bearophile bearophileh...@lycos.com wrote: Currently this is not accepted, but do you like a syntax to import modules that is more consistent (the same as the one used to import names from a module)? import std: stdio, algorithm, range, array; FWIW this was filed as an enhancement a few years ago: http://d.puremagic.com/issues/show_bug.cgi?id=3603
Re: From package import syntax
Andrej Mitrovic: FWIW this was filed as an enhancement a few years ago: http://d.puremagic.com/issues/show_bug.cgi?id=3603 Thank you. Commented and voted. Bye, bearophile
Re: endless loop with ref and non-ref parameter
On Friday, 25 January 2013 at 01:57:02 UTC, Jonathan M Davis wrote: The compiler _has_ to pick either const or ref as having higher precedence. ref was almost certainly chosen as having higher precedence because it avoids a conversion, but also by picking ref, you end up with fewer unnecessary copies, making it the more efficient choice. So, from the standpoint of both type conversions and efficiency, it makes more sense for ref to have precedence over const than the other way around. The reality of the matter is that regardless of whether const or ref had precedence, you'd still need all 4 overloads or you'd have problems. auto ref and inout can help reduce the number of overloads required, but the function needs to accept all of the type combinations in order to avoid having to convert the type or make unnecessary copies. Personally that doesn't seem like it makes sense. I know it does logically, but at the same time it seems silly. If you have something as const, why do you need a non-const version? Example might be if you were to re-write strlen for C, you have a const version but no need for a non-const version as the data will never change. Having multiple ones doing different behavior likely can only get confusing. Say we have the following. ///public interface int strlen(const char[] input); //no public/DDoc interface //does what the above does but also swaps upper/lower case int strlen(char[] input); Now when you change something from const to non-const the behavior changes drastically. Even if the Behavior didn't change, there shouldn't be a need for two versions of it for the same name in order for it to work. There's cases where I've tried to make use of only incorporating a few const/ref differences and yet it fails terribly unless I fill in the other two with unexpected behavior. I see a variable with 'const' and it's I declare 'this variable cannot be changed by me', where as for a function signature it's 'I promise (in good Faith) not to change this'. In these aspects the const should have equal footing as the non-const when determining which to call. Here's a older example although I'll have to redo it. struct S { //move semantics as it's rvalue void opAssign(S s); //If lvalue, we only want to reference it and //make manual updates to this one void opAssign(const ref S s); } In this case the opAssign(S) would always be called unless you made the lvalue (or cast it) as const. This personally seems wrong. If const ref had the highest priority the issue goes away, although you cannot have a non-const ref otherwise with the same signature, but why would you need one? It seems to be causing more issues than it helps, kinda like multiple inheritance. //with above if const ref was highest void opAssign(ref S s); //error, opAssign(const ref S) trumps If auto ref does get accepted, then it will help alleviate some of the problems, but doesn't feel like all of them will be handled.
Re: endless loop with ref and non-ref parameter
On Friday, January 25, 2013 05:14:45 Era Scarecrow wrote: On Friday, 25 January 2013 at 01:57:02 UTC, Jonathan M Davis wrote: The compiler _has_ to pick either const or ref as having higher precedence. ref was almost certainly chosen as having higher precedence because it avoids a conversion, but also by picking ref, you end up with fewer unnecessary copies, making it the more efficient choice. So, from the standpoint of both type conversions and efficiency, it makes more sense for ref to have precedence over const than the other way around. The reality of the matter is that regardless of whether const or ref had precedence, you'd still need all 4 overloads or you'd have problems. auto ref and inout can help reduce the number of overloads required, but the function needs to accept all of the type combinations in order to avoid having to convert the type or make unnecessary copies. Personally that doesn't seem like it makes sense. I know it does logically, but at the same time it seems silly. If you have something as const, why do you need a non-const version? With templated code, it can be important. But then again, if there's no point in having a non-const overload, you can simply not declare any overloads without const. You only run into problems when you mix const and non-const. The compiler has to be able to deal with various combinations of const and ref regardless of what it actually makes sense to declare. The only way that I can think of to get rid of that problem is to make it illegal to declare both const and non-const overloads at the same time, which seems unnecessarily restrictive (especially with regards to generic code), even if it doesn't normally make sense to overload on const. - Jonathan M Davis
Re: Coping files and folders
On Thursday, 24 January 2013 at 07:41:23 UTC, Jacob Carlborg wrote: Someone posted code in these newsgroups of a parallel implementation of copy and remove. I posted a parallel implementation a while back, and also put it on github. The parallel trick is to create the folder structure first, then populate the folders with the files. Best for ssd drives. I also wrote a copy version that orders file sequence on disk efficiently, using write through, and posted it. This speeds up any subsequent file system operations done in the directory order as if you have done a defrag. Great for hard drives, but not needed for ssd. https://github.com/jnorwood
Re: endless loop with ref and non-ref parameter
On Friday, 25 January 2013 at 04:26:18 UTC, Jonathan M Davis wrote: With templated code, it can be important. But then again, if there's no point in having a non-const overload, you can simply not declare any overloads without const. You only run into problems when you mix const and non-const. The compiler has to be able to deal with various combinations of const and ref regardless of what it actually makes sense to declare. The only way that I can think of to get rid of that problem is to make it illegal to declare both const and non-const overloads at the same time, which seems unnecessarily restrictive (especially with regards to generic code), even if it doesn't normally make sense to overload on const. True, but still it seems overtly annoying. I noticed most of this from TDPL. pg 257 [quote] The problem is that opAssign as defined expects a ref Widget, that is, an lvalue of type Widget. To accept assignment from rvalue in addition to lvalues, Widget must define two assignment operators: import std.algorithm; struct Widget { private int[] array; ref Widget opAssign(ref Widget rhs) { array = rhs.array.dup; return this; } ref Widget opAssign(Widget rhs) { swap(array, rhs.array); return this; } } There's no more .dup in the version takint an rvalue. Why? Well the rvalue (with it's array in tow) is practically owned by the second opAssign: It was copied prior to entering the function and will be destroyed just before the function returns. This means there's no more need to duplicate rhs.array because nobody will miss it. Swapping rhs.array with this.array is enough. When opAssign returns, rhs goes away with this's old array, and this stays with rhs's old array--perfect conservation of state. We now could remove the first overload of opAssign altogether: The one taking rhs by value takes care of everything (lvalues are automatically converted to rvalues). But keeping the lvalue version allows for a useful optimization: instead of .duping the source, opAssign can check whether the current array has space for accommodating the new contents, in which case an overwrite is enough. [/quote] The whole time I look at the example code, I can see how the ref Widget can be const and continue to work perfectly, but the non-ref cannot be const (without ugly unsafe casting). But if you try to pass const data to opAssign it will either try to copy it (if it's POD or postblit it), or fail outright. In my mind I shouldn't have to double the functions to have it 'do the right thing', even if it's just to forward them. This is not a case where 'auto ref' could help, as lvalue/rvalue distinction needs to be kept.
Re: endless loop with ref and non-ref parameter
On Thursday, January 24, 2013 21:38:42 Ali Çehreli wrote: If const really requires a conversion then we have a language design problem here. No. const T is _not_ the same type as T, therefore assigning a T to a const T _is_ a type conversion. _Any_ time that a variable of one type is assigned to a variable of another type is a conversion regardless of the types involved. True, the bits of the object won't have changed when converting from T to const T (assuming that no alias this has been declared for the conversion anyway), but it's still a type conversion. So, if you have [...] These examples are great but as I said, they don't help the programmer at function signature stage. immutable is easy: If I am going to need immutable data, then I make the parameter immutable. By-value is also understandable: I don't care about the original. Additionally, when a 'ref' overload exists, by-value gives me the chance to move because only the rvalue can be bound to by-value. Pretty indirect way of thinking but we can deal with it... const should be easy as well: I am not going to modify. Just like in C++... Unfortunately that is not the case. I don't see what could be done to make it simpler other than making it illegal to overload on constness or refness, which would cause other problems. When you're dealing with a variety of overloads, it's always going to get complicated on some level. Stuff like auto ref and inout help, but it's complicated by its very nature. Besides, the simple rule of making sure that either all of your overloads match in terms of constness or that you have overloads for both const and non-const parameters of matching refness solves the problem. And if you screw it up, it's obvious _very_ quickly, since it causes infinite recursion. - Jonathan M Davis
Re: Coping files and folders
Sounds cool. I've bookmarked your github hub link. Just wondering with this: // parallel foreach for regular files foreach(fn ; taskPool.parallel(files,100)) { string dfn = destRoot ~ fn[srcLen..$]; copy(fn,dfn); } What is the 100 number for? On Friday, 25 January 2013 at 05:30:11 UTC, Jay Norwood wrote: On Thursday, 24 January 2013 at 07:41:23 UTC, Jacob Carlborg wrote: Someone posted code in these newsgroups of a parallel implementation of copy and remove. I posted a parallel implementation a while back, and also put it on github. The parallel trick is to create the folder structure first, then populate the folders with the files. Best for ssd drives. I also wrote a copy version that orders file sequence on disk efficiently, using write through, and posted it. This speeds up any subsequent file system operations done in the directory order as if you have done a defrag. Great for hard drives, but not needed for ssd. https://github.com/jnorwood
Re: S-Expressions
On Friday, 25 January 2013 at 01:52:27 UTC, bearophile wrote: qznc: We're even now ;) http://rosettacode.org/wiki/Rosetta_Code/Rank_languages_by_popularity#D I have cut some lines, and I have used a more functional style, that fits well for this entry. Compared to the C++ entry this D entry is nicer. I greatly prefer the verbose option of the Python regex. And g for regexes should be the default. This D code: auto pairs = categories.match(r2) .filter!(m = languages.canFind(m[1]))() .map!(m = tuple(m[2].to!uint(), m[1].dup))() .array(); With a Python-like syntax becomes nicer: auto pairs = [(r.to!uint, l.dup) for l,r in categories.match(r2) if l in languages]; I completely agree. The functional style is better and I miss list comprehensions as well. It does not require new keywords, so maybe it can be added to D at some point.