Re: SList container problem
thanks for the reply... the method you described is suitable for appending to an array, but I'm using the singly-linked-list container. I've extended the test, and I'm pretty sure it's a bug... --ted Nicholas Wilson wrote: On Thursday, 13 August 2015 at 08:40:13 UTC, ted wrote: have upgraded from 2.066.1 to 2.068.0, and have a change in behaviour: import std.container: SList; void main() { SList!int tmp; tmp.insertAfter( tmp[], 3 ); } used to work happily with dmd2.066.1, causes assert (core.exception.AssertError@std/container/slist.d(57): Assertion failure) in 2.068.0 (also 2.067.1). There was a change in slist.d in 2.067. Am I no longer able to start from an empty list? --ted tmp ~= 3; ?
Associative array literal. Why doesn't it compile?
Compiler dmd_2.068.0-0_amd64.deb on Ubuntu 12.04 Linux: auto lookup = [ one:1, two:2 ]; The dmd error: Error: non-constant expression [one:1, two:2] Why doesn't it compile? As a workaround I could do the assignment one element at a time in a loop. It would be uglier though.
Re: Associative array literal. Why doesn't it compile?
On 08/13/2015 11:48 PM, Adel Mamin wrote: Compiler dmd_2.068.0-0_amd64.deb on Ubuntu 12.04 Linux: auto lookup = [ one:1, two:2 ]; The dmd error: Error: non-constant expression [one:1, two:2] I think the problem is when the variable is defined at module scope. It works inside functions, etc. Why doesn't it compile? As a workaround I could do the assignment one element at a time in a loop. It would be uglier though. A better workaround is to initialize it in the module constructor: immutable int[string] lookup; shared static this() { lookup = [ one:1, two:2 ]; } void main() { assert(one in lookup); } Ali
Re: Associative array literal. Why doesn't it compile?
On Friday, 14 August 2015 at 06:48:27 UTC, Adel Mamin wrote: Compiler dmd_2.068.0-0_amd64.deb on Ubuntu 12.04 Linux: auto lookup = [ one:1, two:2 ]; The dmd error: Error: non-constant expression [one:1, two:2] Why doesn't it compile? As a workaround I could do the assignment one element at a time in a loop. It would be uglier though. It's because of the key type (string is a library type). You have to initialize it by hand. Explanation here: http://stackoverflow.com/a/26862994/3661500 see the comment of Adam D. Ruppe. Although this case was 'a bit' different since the AA had to be immutable (in this case it was only possible to initialize it in a static module constructor or in class/struct constructor). But it's almost the same problem.
Re: More threads - Slower program ??
On Wednesday, 12 August 2015 at 23:23:03 UTC, Yuxuan Shui wrote: Is there a way to do thread-local allocations? Yes, either manually or just putting things on the stack, but the std.string functions you use doesn't try to do them. You might try replacing format() with formattedWrite(), which calls a function you provide to put the data where it needs to be. I tried running your program on my computer and it was too fast to measure so i'm not sure if this would make a difference or not.
Re: Associative array literal. Why doesn't it compile?
On Friday, 14 August 2015 at 07:04:53 UTC, BBasile wrote: It's because of the key type (string is a library type). This is not true. It's not because of the key type. And string is not a library type.
Re: iterating through a range, operating on last few elements at a time
On 08/14/2015 05:12 AM, H. S. Teoh via Digitalmars-d-learn wrote: On Fri, Aug 14, 2015 at 02:42:26AM +, Laeeth Isharc via Digitalmars-d-learn wrote: I have a range that is an array of structs. I would like to iterate through the range, calling a function with the prior k items in the range up to that point and storing the result of the function in a new range/array. what's the best way to do this? for low fixed k I could use zip with staggered slices (s[3..$],s[2..$-1],s[1..$-2],s[0..$-3]) and then map. I can't think of how to do it elegantly. any thoughts? Maybe something like this? import std.algorithm; import std.stdio; import std.range; auto slidingWindow(R)(R range, int k) { return iota(k).map!(i = range.save.drop(i)) .array .transposed; } void main() { auto data = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]; writeln(data.slidingWindow(3)); } To apply the function to each slice, just write: data.slidingWindow(k).map!myFunc ... I didn't figure out how to eliminate the short slices toward the end, import std.algorithm; import std.stdio; import std.range; auto transp(RoR)(RoR ror){ static struct Transp{ typeof(transposed(ror)) orig; alias orig this; @property bool empty(){ return orig.tupleof[0].any!(a=a.empty); } } return Transp(transposed(ror)); } auto slidingWindow(R)(R range, int k) { return iota(k).map!(i = range.save.drop(i)).array.transp; } void main() { auto data = iota(1,11).array; writeln(data.slidingWindow(3)); } :o) but all you need to do is to somehow drop the last (k-1) elements from the range returned by slidingWindow.
Re: iterating through a range, operating on last few elements at a time
On 08/14/2015 03:26 PM, Timon Gehr wrote: On 08/14/2015 05:12 AM, H. S. Teoh via Digitalmars-d-learn wrote: ... I didn't figure out how to eliminate the short slices toward the end, ... :o) ... Less hacky and less efficient: auto slidingWindow(R)(R range, int k) { return iota(k).map!(i=range.save.drop(i)) .array.transposed.zip(range.save.drop(k-1)).map!(a=a[0]); }
Theoretical Best Practices
This is more a theoretical exercise than specific code nitty gritty, but... Let's say I have some code like this: class World { // Bunch of members and other functions void happyDay () { if (bCthulhuRises) { debug(logging) { logger.writeLog(this); // uses the class toString to give a dump of interesting parts of the object } throw new Exception(We're doomed! Run you fools!); } } } I only want to access the logger object when the program is compiled with the -debug option, so I don't want to pass it along to the object constructor or set a member as a reference to it (which is both tedious and pointless if not in -debug mode). The simple solution is to make the Logger class a singleton (can D do singletons? I presume it's possible, but I haven't really looked into it), but is there a means in D that is considered a better way to do this?
dub and subpackages
i'm trying to have my own versions of my dependencies as git submodules. problem: i include a local version of vibe.d and then i add other local versions of packages that themselves include vibe.d somehow my version of vibe isn't picked up by the other dependencies and it results in an error: Sub package vibe-d: doesn't exist. when i go and simply remove the vibe-d dependency from the dub.json it compiles fine. but that can't be the solution. dub --version DUB version 0.9.24-rc.2+18-g4fece3c, built on Aug 14 2015 top level project uses dub.sdl, subpackages use dub.json. whats the correct way of having a chain of packages included from git submodules so that every packages get's only picked once?
Re: dub and subpackages
On Friday, 14 August 2015 at 08:06:15 UTC, yawniek wrote: i'm trying to have my own versions of my dependencies as git submodules. whats the correct way of having a chain of packages included from git submodules so that every packages get's only picked once? dub add-local allows you to add local copy of a package. This will be system wide though, not only for the current package.
Re: Attributes not propagating to objects via typeinfo?
On Thursday, 13 August 2015 at 16:05:19 UTC, Steven Schveighoffer wrote: On 8/13/15 11:59 AM, Steven Schveighoffer wrote: That is definitely a bug. It's because typeid is looking up the derived type via the vtable, but the compiler should rewrap it with 'shared' afterwards. Actually, now that I think about it, I'm not sure how the compiler can figure this out. There would have to be a way to construct a TypeInfo_Shared at runtime, which the compiler shouldn't be doing. Alternatively, it could proactively create a TypeInfo_Shared (and all the other flavors) for each class type in the runtime, and then look it up using some hash mechanism. This likely isn't fixable. What you CAN do, however, is: typeid(typeof(c)) Which should get the *static* type (and that should be TypeInfo_Shared in both struct and class instances). So likely this is not a bug, or at the best, a wontfix. If it yields invalid results, it should at least be forbidden, if it can't be fixed.
Re: dub and subpackages
On Friday, 14 August 2015 at 08:09:18 UTC, Edwin van Leeuwen wrote: On Friday, 14 August 2015 at 08:06:15 UTC, yawniek wrote: dub add-local allows you to add local copy of a package. This will be system wide though, not only for the current package. i actually tried this, somehow did't work
Re: Associative array literal. Why doesn't it compile?
It's because it's implemented in DMD only partly. There's a bug report associated with it.
Re: Attributes not propagating to objects via typeinfo?
On 08/13/2015 06:05 PM, Steven Schveighoffer wrote: On 8/13/15 11:59 AM, Steven Schveighoffer wrote: That is definitely a bug. It's because typeid is looking up the derived type via the vtable, but the compiler should rewrap it with 'shared' afterwards. Actually, now that I think about it, I'm not sure how the compiler can figure this out. There would have to be a way to construct a TypeInfo_Shared at runtime, which the compiler shouldn't be doing. Alternatively, it could proactively create a TypeInfo_Shared (and all the other flavors) for each class type in the runtime, and then look it up using some hash mechanism. ... Can't the shared typeinfo be constructed for all superclasses of C at the point where shared(C) is used? (Think: template instantiation.) This likely isn't fixable. ... I don't understand. It is evidently fixable. E.g. if TypeInfo was just a template without the mostly redundant additional compiler support, this would be a trivial fix.
Re: Attributes not propagating to objects via typeinfo?
On 8/14/15 11:39 AM, Timon Gehr wrote: On 08/13/2015 06:05 PM, Steven Schveighoffer wrote: On 8/13/15 11:59 AM, Steven Schveighoffer wrote: That is definitely a bug. It's because typeid is looking up the derived type via the vtable, but the compiler should rewrap it with 'shared' afterwards. Actually, now that I think about it, I'm not sure how the compiler can figure this out. There would have to be a way to construct a TypeInfo_Shared at runtime, which the compiler shouldn't be doing. Alternatively, it could proactively create a TypeInfo_Shared (and all the other flavors) for each class type in the runtime, and then look it up using some hash mechanism. ... Can't the shared typeinfo be constructed for all superclasses of C at the point where shared(C) is used? (Think: template instantiation.) I don't think it can do this at compile time. It would have to do it at link time, since it doesn't know what subclasses of C will exist. If it's a dynamically-linked library, it would have to construct them on library load. Optionally, it could allocate the necessary TypeInfo_Shared on the heap when needed. I don't like that idea either. This likely isn't fixable. ... I don't understand. It is evidently fixable. E.g. if TypeInfo was just a template without the mostly redundant additional compiler support, this would be a trivial fix. I mean, it's not likely fixable without a drastic redesign of the typeinfo system. I'd prefer having typeinfo simply not exist as far as the compiler is concerned, and have typeid call a template with the type as the parameter. We have RTInfo, we should make the whole darned thing done that way. -Steve
Re: Compiletime Table
On Friday, 14 August 2015 at 20:48:43 UTC, Adam D. Ruppe wrote: On Friday, 14 August 2015 at 20:40:13 UTC, D_Learner wrote: Perhaps I have to get myself a copy. you should! There's a lot of little tips and tricks in there. Am currently looking at your Dconf2015 talk . My blasphemous talk as I like to call it :) There's a bit in the video where i went off script and started demoing and it wasn't shown. It was just this program fyi: https://github.com/adamdruppe/inspector not that magical but kinda cool in how simple the code was able to be. Just downloaded the demo, cheers!
Re: Theoretical Best Practices
On Friday, 14 August 2015 at 12:40:08 UTC, Steven Schveighoffer wrote: I would do it this way: // at module level debug(logging) { Logger logger; static this() { logger = new Logger;} } If you want to have the logger be global, add 'shared' to both the logger and the static this. This initializes the data before main() is run, so there is no need for singletons. The added bonus here is that you can't accidentally log stuff when debug(logging) isn't enabled, as the variable will not exist. -Steve Ahh, that is a much cleaner way to do it rather than using a singleton. By 'module level', I assume you mean in the module that defines the Logger class? An 'import debug.logger' or somesuch would then give all relevant modules access, correct? Is the compiler smart enough to compile out all the symbols associated with the logger if it is never instantiated?
Re: Compiletime Table
On Thursday, 13 August 2015 at 19:26:12 UTC, Adam D. Ruppe wrote: On Thursday, 13 August 2015 at 19:13:55 UTC, D_Learner wrote: [...] It is currently not possible to build an associative array at compile time and keep it as a runtime table due to the implementation. [...] Am aware you have published a book on D. Perhaps I have to get myself a copy. Am currently looking at your Dconf2015 talk . Thanks for your advice.
Re: Compiletime Table
On Friday, 14 August 2015 at 20:40:13 UTC, D_Learner wrote: Perhaps I have to get myself a copy. you should! There's a lot of little tips and tricks in there. Am currently looking at your Dconf2015 talk . My blasphemous talk as I like to call it :) There's a bit in the video where i went off script and started demoing and it wasn't shown. It was just this program fyi: https://github.com/adamdruppe/inspector not that magical but kinda cool in how simple the code was able to be.
Re: Compiletime Table
On Thursday, 13 August 2015 at 19:54:18 UTC, anonymous wrote: On Thursday, 13 August 2015 at 19:13:55 UTC, D_Learner wrote: [...] I think you may have some fundamental misunderstandings regarding CTFE, templates, etc. Your code seems to be half-way between a template-based and a CTFE-based solution. The simple way to do compile-time computation in D is CTFE (Compile Time Function Evaluation). That is, you write a pure function that can be evaluated both at run-time and at compile-time. CTFE doesn't need template parameters. Here's some code that should do the same as yours and is compatible with CTFE: import std.conv: to; import std.stdio; int[char] calculatebmBc(string pattern) pure { const int size = to!int(pattern.length); int[char] result; foreach(i; 0 .. size - 1) { result[pattern[i]] = to!int(size - i - 1); } return result; } void main() { auto bmBc = calculatebmBc(GCAGAGAG); enum bmBcTable = calculatebmBc(GCAGAGAG); } The key is that calculatebmBc is pure, i.e. it doesn't read or write any module-level mutables. I touched some things here and here I didn't like that are not related to purity/CTFE. Adam D. Ruppe already mentioned an issue with associative arrays: This doesn't work: static foo = calculatebmBc(GCAGAGAG); It's annoying, but if you need that you have to use some other data structure. See Adam's post. Thanks so much for the advice, it works fine. Just experimented with the code . I had no idea about it. My mind had the some pre-occupation that compile-time execution is only achievable through templates. Had no idea about pure functions...awesone , code. Thanks again for the clear explanation.
Re: Theoretical Best Practices
On Friday, 14 August 2015 at 22:25:15 UTC, DarthCthulhu wrote: Ahh, that is a much cleaner way to do it rather than using a singleton. By 'module level', I assume you mean in the module that defines the Logger class? An 'import debug.logger' or somesuch would then give all relevant modules access, correct? Is the compiler smart enough to compile out all the symbols associated with the logger if it is never instantiated? If you want to make 100% sure that the Logger code does not end up in the release version, you can just put the Logger class definition in that debug block as well. Also, am I the only one who is imagining that you are really the dog in your avatar. I am just imagining that there is a dog somewhere trying to learn D.
Re: Theoretical Best Practices
On Friday, 14 August 2015 at 23:17:44 UTC, Tofu Ninja wrote: On Friday, 14 August 2015 at 22:25:15 UTC, DarthCthulhu wrote: Ahh, that is a much cleaner way to do it rather than using a singleton. By 'module level', I assume you mean in the module that defines the Logger class? An 'import debug.logger' or somesuch would then give all relevant modules access, correct? Is the compiler smart enough to compile out all the symbols associated with the logger if it is never instantiated? If you want to make 100% sure that the Logger code does not end up in the release version, you can just put the Logger class definition in that debug block as well. Well, it doesn't really matter much as a logger class wouldn't have very much in it anyway. But I am imagining some kind of uber-huge class might be used for some reason in other ways and it would be interesting to know if it would be cut out completely by the compiler or not. Also, am I the only one who is imagining that you are really the dog in your avatar. I am just imagining that there is a dog somewhere trying to learn D. WHO TOLD YOU!? Er, I mean, gee-whilikers, why would you think that? I am a perfectly normal human. Yessiree, human hands an evryting. no annoyingly fat paws that make it hard to type. Now if you'll excuse me, I have to go walkies.
Re: using memset withing a pure function
On Saturday, 15 August 2015 at 01:09:15 UTC, D_Learner wrote: When writting a pure fucntion involving C non pure functions like memcpy() and memset() Those functions are pure already, and marked so in the newest dmd (and I think older ones too, though I haven't confirmed. Your code compiled out of the box for me. BTW D also has some syntax sugar for them: arr[start .. end] = 0; // memset those bounds to 0 arr[start .. end] = arr2[start .. end]; // memcpy
Re: using memset withing a pure function
On Saturday, 15 August 2015 at 02:21:46 UTC, D_Learner wrote: Well, the actual error I got is : Error: memset cannot be interpreted at compile time, because it has no available source code . I seems to suggest I miss the actual code. I guess I gave you a wrong impression of how pure relates to CTFE over here: http://forum.dlang.org/post/hdzhkxqgcpsuovcif...@forum.dlang.org. Sorry 'bout that. There, your function wasn't pure which made CTFE impossible. But being pure is not enough for a function to be CTFEable. The source code needs to be available, too. And then there are things that are ok in pure functions but simply don't work in CTFE.
Re: using memset withing a pure function
On 08/14/2015 06:09 PM, D_Learner wrote: When writting a pure fucntion involving C non pure functions If you want to live dangerously, you can use assumePure, which is found in one of the unittest blocks of std.traits: import std.traits; auto assumePure(T)(T t) if (isFunctionPointer!T || isDelegate!T) { enum attrs = functionAttributes!T | FunctionAttribute.pure_; return cast(SetFunctionAttributes!(T, functionLinkage!T, attrs)) t; } int i = 0; void foo() { ++i;// foo accesses mutable module-level data } void bar() pure { auto pureFoo = assumePure(foo); pureFoo();// -- pure function is calling impure function } void main() { assert(i == 0); bar(); assert(i == 1);// mutation through a pure function } Ali
Re: iterating through a range, operating on last few elements at a time
On Friday, 14 August 2015 at 13:32:57 UTC, Timon Gehr wrote: On 08/14/2015 03:26 PM, Timon Gehr wrote: On 08/14/2015 05:12 AM, H. S. Teoh via Digitalmars-d-learn wrote: ... I didn't figure out how to eliminate the short slices toward the end, ... :o) ... Less hacky and less efficient: auto slidingWindow(R)(R range, int k) { return iota(k).map!(i=range.save.drop(i)) .array.transposed.zip(range.save.drop(k-1)).map!(a=a[0]); } Thanks v much HS and Timon. Laeeth.
Re: using memset withing a pure function
On Saturday, 15 August 2015 at 02:21:46 UTC, D_Learner wrote: Well, the actual error I got is : Error: memset cannot be interpreted at compile time, because it has no available source code . I seems to suggest I miss the actual code. yeah, ctfe is different than pure functions. That's where the compiler interprets the code inside the compiler. The slice syntax might work there though. Try changing them to that.
Re: using memset withing a pure function
On Saturday, 15 August 2015 at 02:21:46 UTC, D_Learner wrote: On Saturday, 15 August 2015 at 01:13:02 UTC, Adam D. Ruppe wrote: On Saturday, 15 August 2015 at 01:09:15 UTC, D_Learner wrote: When writting a pure fucntion involving C non pure functions like memcpy() and memset() Those functions are pure already, and marked so in the newest dmd (and I think older ones too, though I haven't confirmed. Your code compiled out of the box for me. BTW D also has some syntax sugar for them: arr[start .. end] = 0; // memset those bounds to 0 arr[start .. end] = arr2[start .. end]; // memcpy Well, the actual error I got is : Error: memset cannot be interpreted at compile time, because it has no available source code . I seems to suggest I miss the actual code. this is another thing. Here you reach the CTFE limits.
using memset withing a pure function
When writting a pure fucntion involving C non pure functions like memcpy() and memset() , what could be the way around? Should I re-write these and make them pure? The code am converting is as below :- int ag_cmatch(const string pattern, const string text, int[char] bmBc , int[size] bmGs ) pure { //Start of AG search algorithm int i,j,k , s, shift; int[size] skip; int[size] suff; int m = to!int(pattern.length); int n = to!int(text.length); int position = -1; /* Preprocessing */ memset(skip[0], 0, m* int.sizeof); // Initialise skip table /* searching */ j = 0; while(j=n-m){ i=m-1; while( i = 0){ // Start inner while k = skip[i]; s = suff[i]; if( k 0) if( k s){ //writeln( Int Size 3 , int.sizeof); if(i+1 == s) i = (-1); else { i -=s; //writeln(Innner while loop .Found... ); break; } } else{ i-=k; if( k s ){ // writeln(Innner while loop .Found 1 ... ); //getchar(); break; } } else { if ( pattern[i] == text[i+j]){ --i; //writeln(Innner while loop .Found 2 ); } else break; } }// End inner while if ( i 0){ //writeln( AG Pattern found at :, j); position = j;//Added for display / reporting //getchar(); // Manually added to cause a pattern found stop(Not in documentation) skip[m-1] = m; shift = bmGs[0]; break; } else{ skip[ m-1 ] = m -1 -i; shift = bmGs[i] (bmBc[text[i+j]] - m + 1 + i) ? bmGs[i] : (bmBc[text[i+j]] - m + 1 + i ) ; } j+=shift; // writeln( j Before memcpy== : , j); memcpy(skip[0], skip[0]+shift, (m-shift)*(int.sizeof)); memset(skip[0]+(m-shift),0, shift*(int.sizeof)); }//End outer while return position ; }//End AG search
Re: using memset withing a pure function
On Saturday, 15 August 2015 at 01:13:02 UTC, Adam D. Ruppe wrote: On Saturday, 15 August 2015 at 01:09:15 UTC, D_Learner wrote: When writting a pure fucntion involving C non pure functions like memcpy() and memset() Those functions are pure already, and marked so in the newest dmd (and I think older ones too, though I haven't confirmed. Your code compiled out of the box for me. BTW D also has some syntax sugar for them: arr[start .. end] = 0; // memset those bounds to 0 arr[start .. end] = arr2[start .. end]; // memcpy Well, the actual error I got is : Error: memset cannot be interpreted at compile time, because it has no available source code . I seems to suggest I miss the actual code.
Re: complete win headers for 32/64 bit
http://code.dlang.org/packages/windows-headers - as a dub package.
Re: SList container problem
https://issues.dlang.org/show_bug.cgi?id=14920
Re: Attributes not propagating to objects via typeinfo?
On 8/14/15 4:22 AM, Marc =?UTF-8?B?U2Now7x0eiI=?= schue...@gmx.net wrote: On Thursday, 13 August 2015 at 16:05:19 UTC, Steven Schveighoffer wrote: On 8/13/15 11:59 AM, Steven Schveighoffer wrote: That is definitely a bug. It's because typeid is looking up the derived type via the vtable, but the compiler should rewrap it with 'shared' afterwards. Actually, now that I think about it, I'm not sure how the compiler can figure this out. There would have to be a way to construct a TypeInfo_Shared at runtime, which the compiler shouldn't be doing. Alternatively, it could proactively create a TypeInfo_Shared (and all the other flavors) for each class type in the runtime, and then look it up using some hash mechanism. This likely isn't fixable. What you CAN do, however, is: typeid(typeof(c)) Which should get the *static* type (and that should be TypeInfo_Shared in both struct and class instances). So likely this is not a bug, or at the best, a wontfix. If it yields invalid results, it should at least be forbidden, if it can't be fixed. I think it's really a limitation of the runtime. If we can eliminate TypeInfo from the purview of the compiler, we could do some kind of solution where the result of typeid could be some sort of wrapper struct in this case. But I don't know if it's a good idea to forbid this, you would probably break a lot of code. -Steve
Re: Theoretical Best Practices
On 8/14/15 5:21 AM, DarthCthulhu wrote: This is more a theoretical exercise than specific code nitty gritty, but... Let's say I have some code like this: class World { // Bunch of members and other functions void happyDay () { if (bCthulhuRises) { debug(logging) { logger.writeLog(this); // uses the class toString to give a dump of interesting parts of the object } throw new Exception(We're doomed! Run you fools!); } } } I only want to access the logger object when the program is compiled with the -debug option, so I don't want to pass it along to the object constructor or set a member as a reference to it (which is both tedious and pointless if not in -debug mode). The simple solution is to make the Logger class a singleton (can D do singletons? I presume it's possible, but I haven't really looked into it), but is there a means in D that is considered a better way to do this? I would do it this way: // at module level debug(logging) { Logger logger; static this() { logger = new Logger;} } If you want to have the logger be global, add 'shared' to both the logger and the static this. This initializes the data before main() is run, so there is no need for singletons. The added bonus here is that you can't accidentally log stuff when debug(logging) isn't enabled, as the variable will not exist. -Steve
Re: Theoretical Best Practices
On Friday, 14 August 2015 at 09:21:56 UTC, DarthCthulhu wrote: I only want to access the logger object when the program is compiled with the -debug option, so I don't want to pass it along to the object constructor or set a member as a reference to it (which is both tedious and pointless if not in -debug mode). The simple solution is to make the Logger class a singleton (can D do singletons? I presume it's possible, but I haven't really looked into it), but is there a means in D that is considered a better way to do this? D can do singletons, the regular java/c# way, or you can just have an object on a module level. You can also debug{} the field.