Re: Incomplete types question
NoUseForAName: In C my favorite way of achieving encapsulation is to use incomplete types. The module header contains the definition of an incomplete type and the prototypes for the public functions which operate on it. Probably in D you can archive something similar with different means. Bye, bearophile
Re: Incomplete types question
On 07/07/2014 09:44 PM, NoUseForAName wrote: In C my favorite way of achieving encapsulation is to use incomplete types. The module header contains the definition of an incomplete type and the prototypes for the public functions which operate on it. I have read D has incomplete types too however D does not have headers and as a C guy I do not know how to implement this scheme without a .h/.c separation. As I said, in C I put the incomplete declaration in the header while keeping the complete declaration private to the module. How do I do this in D? I mean type is complete within the module itself (and thus can be instantiated there) but incomplete for clients (i.e. other modules) i.e. instantiating or modifying data of that type directly is impossible. P.S.: It seems D lingo for incomplete types is "opaque types". 1) Put the opaque type and its functions into a .di file: // deneme.di module deneme; struct S; S * makeS(int i); void useS(S * s); 2) Put the implementation in its .d file: // deneme.d module deneme; import std.stdio; struct S { int i; void foo() { writefln("Executing foo() for %s", this); } } S * makeS(int i) { return new S(i); } void useS(S * s) { s.foo(); } 3) Compile the implementation as a library (just a .o in this case): $ dmd deneme.d -c (That will create the file deneme.o) 4) Write a client program that uses the interface. (Make sure that only deneme.di is visible to the client (not deneme.d).) // main.c import deneme; void main() { S * s = makeS(42); useS(s); } 5) Compile (and link) the client program and the library to make the program: $ dmd main.d deneme.o (That will create the executable 'main'.) 6) Run the program: $ ./main Executing foo() for S(42) Ali
Re: Opinions: The Best and Worst of D (for a lecture/talk I intend to give)
On Mon, Jul 07, 2014 at 11:47:25PM +, Aerolite via Digitalmars-d-learn wrote: [...] > So, if you would be so kind, give me a bullet list of the aspects of D > you believe to be good, awesome, bad, and/or ugly. If you have the > time, some code examples wouldn't go amiss either! Try not to go > in-depth to weird edge cases - remain general, yet informative. E.g. I > consider D's string mixins to be in the 'awesome' category, but its > reliance on the GC for large segments of the standard library to be in > the 'ugly' category. [...] String mixins are a controversial feature. Many (including myself) think they are definitely awesome, but that power also comes with the price of being harder to maintain, and difficult to integrate with IDE features (though the latter doesn't matter to me 'cos I don't use IDEs). Because of that, some others think they are a misfeature, and have proposed to remove them. But I don't think it's going away anytime soon, since several key features depend on it. Perhaps I may bring up a representative use case: operator overloading. In C++, if you implement a custom number type, for example, you have to overload operator+, operator*, operator/, operator-. And then you realize you left out operator+=, operator*=, operator/=, ... and then you need operator<, operator>, operator<=, operator>=, ad nauseum. In D? // This covers +, -, *, /, +=, -=, *=, /=, etc.. auto opBinary(string op)(NumType n) { return NumType(mixin(this.val ~ op ~ n.val)); } // And this covers all the comparison operators: int opCmp(NumType n) { return ... /* implementation here */ } Without string mixins, you'd have to copy-n-paste a ton of boilerplate to get the necessary operator overloadings. // About the GC, my opinion is that anti-GC sentiment is largely unfounded. The GC greatly simplifies certain tasks (string manipulation, for one thing, and returning recursive data structures like trees). There *are* cases where the GC can cause trouble, like in game engines, esp. given that the GC implementation in D leaves a lot of room for improvement, but a lot of C/C++ programmers have knee-jerk reactions about GCs for no other reason than unfamiliarity breeding contempt (I speak for myself, since I come from a strong C/C++ background, and had the same reaction), than any truly objective measurements. I'd say a large percentage of applications don't need to manually micro-manage memory, and having a GC eliminates an entire class of bugs and greatly improves productivity. // But anyway, not to dwell on a contentious issue, let's move on to something oft overlooked (and sometimes even maligned): unittests. I could sing praises of D's built-in unittest blocks all day. When I was young and foolish, I prided myself on being the macho C/C++ programmer whose code will work the first time after I write it. Who needs tests? They are for the weak-minded, who cannot grasp their code in every last detail of their programs in their head with absolute clarity. Real Programmers can write code in their dreams, and it will work the first time they run it. Except that they don't. :P When I first started learning D, I tried my best to ignore unittests, telling myself that it's for weaker programmers, but they just kept sitting their, right in the language, and staring at me, all cute-like, until I was shamed into actually writing a few of them just to quiet that nagging voice within. And lo and behold, I started finding bugs in my "perfect" code -- corner cases I missed (even though I painstakingly took care of all the *other* corner cases), subtle typos that compiled but gave the wrong answers, blatant errors that I missed due to obsession over tiny details, etc.. To my chagrin, I discovered that I was *not* the macho perfect programmer that I imagined, and that these unittests for the weak were singlehandedly improving the quality of my code by leaps and bounds. Sometimes, the mere act of writing unittests would bring my attention to a corner case that I'd missed, and I'd fix the code, long before my past self would've noticed it (by finding it as a runtime bug much later). When I revised the code later, I suddenly could have peace of mind that if the unittests didn't break, then in all likelihood the new code is still correct (or mostly so). Regressions were instantly noticed, rather than weeks or months down the road when I suddenly needed a corner case that I knew was previously working but had since been broken by a later revision. Unittests in the language == total win. External unittest frameworks may be more powerful, more flexible, etc., but I'd never use them, 'cos they are too troublesome. I have to switch out of coding mode, open a new file, and possibly shift gears to a different language, write the test, then switch back, and later on it becomes too trouble to keep switching back and forth (and maintaining the unittest
Re: implib and system dlls, oh my
Let me see what I can do for time. There's the above, it's also possible to link mixed coff and omf with jwlink (http://www.japheth.de/JWlink/JWlink.htm). There's a couple of paths and while win32 isn't leading edge, I think enhancing it is a worthwhile project for lesser lights like myself. I've tried the above and get a horde of errors. Some seem to be weak link __symbol doesn't match the library's _symbol (two leading underbars on one side, one on the other). Some seem to be some utterly missing capitalized symbols like GETLONG, GETPOINTER and STRLEN2. The underbar mismatches I should be able to fix with a def file or maybe there's a (j)wlink option I missed to resolve those. As I make progress, such as it is, I'll report. Anybody who sees something I've missed feel free to chime in. While I'm learning I have no pride, I save it for pride in having learned.
Re: implib and system dlls, oh my
You may want to spearhead the effort to get Win32 support of MSVC into D, if you care enough about it. Rainer has done most of the work, you'd just have to turn his patches into pull requests, shepherd them through the review process, and maybe add some polish: http://forum.dlang.org/thread/mailman.1560.1323886804.24802.digitalmar...@puremagic.com?page=9#post-llldfc:242q6p:241:40digitalmars.com I'd love to, but that might be a little over my head. I see he forked from 2.060 and now we're almost in 2.066. I'd have to radically improve my git fu and my D fu to be able to bring the patches up to 2.066. I'm on some extended time off in a couple of weeks for some surgery, this might be a project to while away the recovery days.
Incomplete types question
In C my favorite way of achieving encapsulation is to use incomplete types. The module header contains the definition of an incomplete type and the prototypes for the public functions which operate on it. I have read D has incomplete types too however D does not have headers and as a C guy I do not know how to implement this scheme without a .h/.c separation. As I said, in C I put the incomplete declaration in the header while keeping the complete declaration private to the module. How do I do this in D? I mean type is complete within the module itself (and thus can be instantiated there) but incomplete for clients (i.e. other modules) i.e. instantiating or modifying data of that type directly is impossible. P.S.: It seems D lingo for incomplete types is "opaque types".
Re: Sparse Aggregate Assignment/Initialization (RAII)
On Monday, 7 July 2014 at 21:50:22 UTC, Justin Whear wrote: Copy and paste gone astray; should be this link: http://dpaste.dzfl.pl/3c33ad70040f Thx!
Opinions: The Best and Worst of D (for a lecture/talk I intend to give)
Hey all, I've not posted here in a while, but I've been keeping up to speed with D's progress over the last couple of years and remain consistently impressed with the language. I'm part of a new computing society in the University of Newcastle, Australia, and am essentially known throughout our Computer Science department as 'the D guy'. At the insistence of my peers, I have decided to give an introductory lecture on the D Programming Language, in order to expose more students to the increasingly amazing aspects of D. I expect to cover the good, the bad, the awesome, and the ugly, in a complement-criticism-complement styled talk, and while I have my own opinions regarding each of these things, I'd like a broader view from the community regarding these aspects, so that I may provide as accurate and as useful information as possible. So, if you would be so kind, give me a bullet list of the aspects of D you believe to be good, awesome, bad, and/or ugly. If you have the time, some code examples wouldn't go amiss either! Try not to go in-depth to weird edge cases - remain general, yet informative. E.g. I consider D's string mixins to be in the 'awesome' category, but its reliance on the GC for large segments of the standard library to be in the 'ugly' category. Thanks so much for your time!
Re: Visual D: Settings to Improve compil and link process
On 07.07.2014 12:46, ParticlePeter wrote: On Sunday, 6 July 2014 at 19:27:38 UTC, Rainer Schuetze wrote: These object files are in the library ;-) That means manual selection, though, as incremental builds to multiple object files don't work with dmd, and single file compilation is painfully slow. Not sure if I am getting this right, so when one object file has to be recompiled all other object files, even if up to date, would be recompiled ? That's how it is currently done if you don't use "single file compilation". Compiling only modified and dependent modules in one step could work incrementally, but especially template instantiations make this hard to do correctly. The modules form MyProject do import the MyLib modules properly, I do not get compiler errors. However, the compiler should create Object files from MyLib modules, and the linker should link them. But he does not. On the other hand, when I add MyLib modules to MyProject ( Rightclick MyProject - add - existing item... MyLib source files ) then linking works. I do not understand why the later step is necessary. dmd does not compile imported modules, but rdmd does. Ähm ... not seeing the connection here either, why is this significant ? dmd just compiles the files given on the command line. rdmd makes two passes, one to collect imported files, and another to compile all the collected files. So rdmd works the way you want dmd to work (if I understand you correctly). I feel that I could not explain my problem properly, so one example: Importing phobos modules. I do not have to define any import path or lib file in the project settings, I just need to import std.somthing. That's because the import path for phobos modules are stored in the dmd sc.ini file. When I want to import my modules which are somewhere on my hard-drive and not added to my project I need to tell the compiler where these modules can be found, using the additional import path project setting. That's fine, doing this. But result is, std.somthing works, my modules in a path known by the compiler don't work, giving me linker errors. Why ? ( I do not create a lib, I just want to import the module. ) phobos is precompiled to a library and is automatically included in the link. If you want your custom modules to work the same way, you have to compile them to a library.
Re: Sparse Aggregate Assignment/Initialization (RAII)
On Mon, 07 Jul 2014 21:49:22 +, Justin Whear wrote: > On Mon, 07 Jul 2014 21:34:05 +, Nordlöw wrote: > >> However using this function through UFCS >> >> auto cx = new C().set!"x"(11); >> >> fails as >> >> algorithm_ex.d(1257,17): Error: template algorithm_ex.set cannot deduce >> function from argument types !("x")(C, int), candidates are: >> algorithm_ex.d(1242,7):algorithm_ex.set(string member, T, >> U)(ref T a, in U value) if (isAggregateType!T && hasMember!(T, >> member)) >> >> Instead I have to use >> >> auto c = new C(); set!"x"(c, 11); >> >> which is not as elegant. >> >> Why doesn't UCFS work here and is there a solution using DMD git >> master? > > You need to use `auto ref` to have this work with both classes and > structs. A working version of your code here: auto dx = > D().set!"x"(11); > assert(dx.x == 11); Copy and paste gone astray; should be this link: http://dpaste.dzfl.pl/3c33ad70040f
Re: Sparse Aggregate Assignment/Initialization (RAII)
On Mon, 07 Jul 2014 21:34:05 +, Nordlöw wrote: > However using this function through UFCS > > auto cx = new C().set!"x"(11); > > fails as > > algorithm_ex.d(1257,17): Error: template algorithm_ex.set cannot deduce > function from argument types !("x")(C, int), candidates are: > algorithm_ex.d(1242,7):algorithm_ex.set(string member, T, > U)(ref T a, in U value) if (isAggregateType!T && hasMember!(T, > member)) > > Instead I have to use > > auto c = new C(); set!"x"(c, 11); > > which is not as elegant. > > Why doesn't UCFS work here and is there a solution using DMD git master? You need to use `auto ref` to have this work with both classes and structs. A working version of your code here: auto dx = D().set!"x"(11); assert(dx.x == 11); On Mon, 07 Jul 2014 21:34:05 +, Nordlöw wrote: > Further Is there a cleverer way to do this without resorting to mixins? __traits(getMember, ...) is useful here, see this version of your code: http://dpaste.dzfl.pl/75e03fbec020
Sparse Aggregate Assignment/Initialization (RAII)
Because D currently doesn't support RAII using named parameters like in Python I tried the following. Say I have an aggregate class C { int x,y,z,w; } or similarly struct C { int x,y,z,w; } I know define a generic _free_ function ref T set(string member, T, U)(ref T a, in U value) if (isAggregateType!T && hasMember!(T, member)) { mixin(`a.` ~ member ~ ` = value;`); return a; } which I want to use for flexible initialization of several members at once. However using this function through UFCS auto cx = new C().set!"x"(11); fails as algorithm_ex.d(1257,17): Error: template algorithm_ex.set cannot deduce function from argument types !("x")(C, int), candidates are: algorithm_ex.d(1242,7):algorithm_ex.set(string member, T, U)(ref T a, in U value) if (isAggregateType!T && hasMember!(T, member)) Instead I have to use auto c = new C(); set!"x"(c, 11); which is not as elegant. Why doesn't UCFS work here and is there a solution using DMD git master? Further Is there a cleverer way to do this without resorting to mixins? This old post http://forum.dlang.org/thread/mailman.2966.1301533296.4748.digitalmars-d-le...@puremagic.com talks about opDispatch() but, to my knowledge, it requires the aggregate to have extra members doing the initialization. I want this because I've identified in some parts of my code that I have large structures were only a few of the elements are initialized to non-default values.
Capture offset of matches in std.regex.matchAll?
I'm using a compile time regex to find some tags in an input string. Is it possible to capture the offset of the matches in some way? Otherwise I have to "calculate" the offsets myself by iterating over the results of matchAll. Thanks, Jeroen --- Example code: import std.stdio; import std.regex; void main() { auto input = "{{ message }}"; auto ctr = ctRegex!(`(\{\{|\{\%|\{\#)?`, "s"); auto matches = matchAll(input, ctr); /* auto offset = 0; foreach(match;matches) { writeln(offset, ":", match); ++offset; } */ }
Re: std.algorithm.sort error with default predicate
On Mon, Jul 07, 2014 at 08:35:53PM +, anonymous via Digitalmars-d-learn wrote: [...] > Looks like a bad bug: > > void main() > { > uint[] a = [0x22_DF_FF_FF]; > uint[] b = [0xA2_DF_FF_FF]; > assert(!(a < b && b < a)); /* fails */ > } This looks pretty serious. Please file a bug: http://issues.dlang.org/ T -- People tell me I'm stubborn, but I refuse to accept it!
Re: std.algorithm.sort error with default predicate
Is it chain you are after to concatenate the objects and sort them together? http://dlang.org/phobos/std_range.html#.chain You'd need to cast them all to the same type. On Monday, 7 July 2014 at 20:50:06 UTC, Archibald wrote: On Monday, 7 July 2014 at 20:17:16 UTC, bearophile wrote: Archibald: Using std.algorithm.sort(a,b,c,d,e) But isn't std.algorithm.sort accepting only one argument? Bye, bearophile Sorry, it's sort(zip(a,b,c,d,e))
Re: std.algorithm.sort error with default predicate
On Monday, 7 July 2014 at 20:17:16 UTC, bearophile wrote: Archibald: Using std.algorithm.sort(a,b,c,d,e) But isn't std.algorithm.sort accepting only one argument? Bye, bearophile Sorry, it's sort(zip(a,b,c,d,e))
Re: std.algorithm.sort error with default predicate
On Monday, 7 July 2014 at 20:10:10 UTC, Archibald wrote: Using std.algorithm.sort(a,b,c,d,e) I get the error message : core.exception.AssertError@C:\dmd\windows\bin\..\..\src\phobos\std\algorithm.d(1 0350): Predicate for isSorted is not antisymmetric. Both pred(a, b) and pred(b, a) are true for a=Tuple!(float, int, uint[], int, uint[])(-7.56963e-05, 17, [585 105407, 512], 1041, [2732589055, 0]) and b=Tuple!(float, int, uint[], int, uint[ ])(-7.56963e-05, 17, [2732589055, 0], 1105, [585105407, 512]) in positions 25182 and 25183 I am using the default predicate so is it a bug? Looks like a bad bug: void main() { uint[] a = [0x22_DF_FF_FF]; uint[] b = [0xA2_DF_FF_FF]; assert(!(a < b && b < a)); /* fails */ }
Re: Ranges & containers : is it possible to get a SortedRange from a RedBlackTree ?
On Monday, 7 July 2014 at 19:20:24 UTC, Fr wrote: On Monday, 7 July 2014 at 16:58:51 UTC, anonymous wrote: No array is created in the example. Where do you think an array is created? It's in the example above : SortedRange!(MyObject[]) opSlice() { sequence[].array.assumeSorted; } I thought that that using ".array" would lead to instantiating something. Ah, you're referring to Meta's response. Didn't catch that. Yes, .array does create an array. Yes, it has a significant cost. The actual code was the following, which seems to make sense if SortedRange expects random access: SortedRange!(RandomAccessFinite!MyObject) opSlice(); But then I have this error on assumeSorted() : template std.range.assumeSorted cannot deduce function from argument types !()(InputRange!int), candidates are: [...] RedBlackTree's Range is not a random access range. So, at some point the attempt to feed such a range to SortedRange must fail. At first, it failed at SortedRange!(InputRange!MyObject). Then you changed InputRange to RandomAccessFinite here. This passes then. But I guess you forgot to make the change when calling assumeSorted: InputRange!MyObject r = inputRangeObject(sequence[]); return assumeSorted(r); Here, instantiation of assumeSorted fails, because r is a InputRange!MyObject. This is the "cannot deduce function" error. If you now tried to change r's type to RandomAccessFinite!MyObject, assumeSorted would be satisfied, but the initialization of r would fail, because sequence[] is no random access range. For various reasons I'm very attached to interface-oriented design, and although I understand that this is not very "D"-like, I'll try a little bit more in this way ;) I really like the D language itself but for me it's almost mandatory to manipulate abstract interface such as "ordered set" and then to be able to switch easily between particular implementations. Sure, go ahead. And keep asking for help when you need it. It may not be the most popular style, but it's not exactly discouraged either. After all, the interfaces in std.range are there specifically to aid it. "Templated everything" has the same goal of being able to "switch easily between particular implementations", though.
Re: std.algorithm.sort error with default predicate
Archibald: Using std.algorithm.sort(a,b,c,d,e) But isn't std.algorithm.sort accepting only one argument? Bye, bearophile
std.algorithm.sort error with default predicate
Using std.algorithm.sort(a,b,c,d,e) I get the error message : core.exception.AssertError@C:\dmd\windows\bin\..\..\src\phobos\std\algorithm.d(1 0350): Predicate for isSorted is not antisymmetric. Both pred(a, b) and pred(b, a) are true for a=Tuple!(float, int, uint[], int, uint[])(-7.56963e-05, 17, [585 105407, 512], 1041, [2732589055, 0]) and b=Tuple!(float, int, uint[], int, uint[ ])(-7.56963e-05, 17, [2732589055, 0], 1105, [585105407, 512]) in positions 25182 and 25183 I am using the default predicate so is it a bug?
Re: Ranges & containers : is it possible to get a SortedRange from a RedBlackTree ?
On Monday, 7 July 2014 at 19:20:24 UTC, Fr wrote: It's in the example above : SortedRange!(MyObject[]) opSlice() { sequence[].array.assumeSorted; } I thought that that using ".array" would lead to instantiating something. Yes, this *will* instantiate an array and copy all of the items from the RedBlackTree into it. There's not really a way around it (unless you upgrade to 2.066 so assumeSorted will accept the result of sequence[] without having the intermediate array).
Re: Ranges & containers : is it possible to get a SortedRange from a RedBlackTree ?
On Monday, 7 July 2014 at 16:58:51 UTC, anonymous wrote: No array is created in the example. Where do you think an array is created? It's in the example above : SortedRange!(MyObject[]) opSlice() { sequence[].array.assumeSorted; } I thought that that using ".array" would lead to instantiating something. Oh, must be a restriction that's going to be lifted in 2.066. I'm using git head, so I didn't realize that it doesn't work in 2.065. OK that's what I was suspecting... Thanks for checking that. Looks like you can't get binary search through SortedRange over a Range of a RedBlackTree. If you don't need that, you can just drop SortedRange (and assumeSorted) and use InputRange directly. Yes it seems this is the way to go in my case. As far as I know, true (efficient) random access on a RB tree is not a "natural" thing and I would nto have expected that ranges coming from those trees would support it. However it's curious that random access was required by SortedSet, but as far as I understand, this constraint has been recently dropped. RandomAccessFinite is in the same family as InputRange [...] SortedRange is a different kind of template. The template parameter is a range type (e.g. MyObject[] or RedBlackTree!MyObject.Range). Replacing the one with the other doesn't make sense, and doesn't work. Of course ! I'm sorry I retyped it incorrectly, I tested so many things... The actual code was the following, which seems to make sense if SortedRange expects random access: SortedRange!(RandomAccessFinite!MyObject) opSlice(); But then I have this error on assumeSorted() : template std.range.assumeSorted cannot deduce function from argument types !()(InputRange!int), candidates are: [...] [...] Now, if you'd want to go the static-duck-typing route, you'd ditch the MyObjectSet interface. Instead, you'd pass RedBlackTree!MyObject or just RedBlackTree around as a template argument, possibly implicitly. Maybe you could give an example of how you would use MyObjectSet. Then we could think about a template-based alternative. For various reasons I'm very attached to interface-oriented design, and although I understand that this is not very "D"-like, I'll try a little bit more in this way ;) I really like the D language itself but for me it's almost mandatory to manipulate abstract interface such as "ordered set" and then to be able to switch easily between particular implementations. Note that `sequence` is declared as RedBlackTree!MyObject, not just RedBlackTree. There is no RedBlackTree.Range, but there is RedBlackTree!MyObject.Range. Yes, of course, stupid question, sorry... Thank you very much for your help !! Best regards, Frédérik
Re: dustmite build
On Monday, 7 July 2014 at 17:50:35 UTC, Frustrated wrote: when I build dustmite using dmd or gdc with no options or -O3, it is 18M but in the dmd directory, dustmite is only 650k. I assume I'm statically linking the whole library while in the small one is using some dynamic link library? Or is all that debug information or what? Also, how does one use dustmite on a project that invloves many subfolders and uses a library that is specified in the lib path in sc.ini, that also uses many directories? e.g., import a.b.c.d. Say the regression is in the library(worked in one version, new dmd version doesn't work cause it broke something in the library). Is dustmite going to pull in the problematic code from the library or is it too going to just crap out and now show the real problem?
dustmite build
when I build dustmite using dmd or gdc with no options or -O3, it is 18M but in the dmd directory, dustmite is only 650k. I assume I'm statically linking the whole library while in the small one is using some dynamic link library? Or is all that debug information or what?
Re: File needs to be closed on Windows but not on Posix, bug?
On Monday, 7 July 2014 at 12:00:48 UTC, Regan Heath wrote: On Mon, 07 Jul 2014 12:17:34 +0100, Joakim wrote: On Monday, 7 July 2014 at 10:19:01 UTC, Kagamin wrote: See if stdio allows you to specify delete sharing when opening the file. I don't know what delete sharing is exactly, but the File constructor simply calls fopen and I don't see any option for the Windows fopen that seems to do it: http://msdn.microsoft.com/en-us/library/yeby3zcb.aspx The fopen variant that allows you to specify sharing is: http://msdn.microsoft.com/en-us/library/8f30b0db.aspx But it does not mention delete sharing there. CreateFile allows sharing to be specified for delete however: http://msdn.microsoft.com/en-gb/library/windows/desktop/aa363858(v=vs.85).aspx So... you could: - Call CreateFile giving you a "handle" - Call _open_osfhandle to get a "file descriptor" - Call _fdopen on the file descriptor to get a FILE* for it But! I agree with Adam, leave it as a thin wrapper. Being a windows programmer by trade I would expect the remove to fail, I would not expect all my files to be opened with delete sharing enabled by default. Thanks for all the info. I'm looking at it from the point of view of a beginner or someone who just writes a quick D script that does something like this. They may find it confusing that it works on linux but doesn't work on Windows, especially given the confusing error message. But it is good practice to close a file before deleting and if D prefers to have thin wrappers around OS APIs, that implies less hand-holding like this, so maybe we just tell such people to close the file first.
Re: dmd & dub from git master
On Sunday, 6 July 2014 at 11:25:04 UTC, w0rp wrote: I hit this myself also. I was trying to use the master branch DMD, druntime, and phobos with a recent vibe.d for building the documentation with ddox, and I ran into the reliance on std.metastrings. I got things to work after some cleanups of the DUB installations. I don't know exactly how...but no things work :)
Re: Ranges & containers : is it possible to get a SortedRange from a RedBlackTree ?
On Monday, 7 July 2014 at 14:51:37 UTC, Fr wrote: The solution of making an array from the range works, but I'm concerned about the cost of instantiating a (potentially very large) array each time I need to walk across the set. Unless doing that is costless in D for any reason, it does not seem practical in my case. No array is created in the example. Where do you think an array is created? And when trying to compile the above example I got the following error: Error: template instance std.range.SortedRange!(InputRange!int) does not match template declaration SortedRange(Range, alias pred = "a < b") if (isRandomAccessRange!Range && hasLength!Range) Oh, must be a restriction that's going to be lifted in 2.066. I'm using git head, so I didn't realize that it doesn't work in 2.065. RedBlackTree's range is sorted, of course, but it's not a random access range. The documentation says that "SortedRange could accept ranges weaker than random-access, but it is unable to provide interesting functionality for them". I don't know what to do about this. Looks like you can't get binary search through SortedRange over a Range of a RedBlackTree. If you don't need that, you can just drop SortedRange (and assumeSorted) and use InputRange directly. I tried to replace SortedRange!InputRange thing with the following : RandomAccessFinite!(InputRange!MyObject) opSlice(); But then I got the folowing error: Error: template std.range.assumeSorted cannot deduce function from argument types !()(InputRange!int), candidates are: [...] And I must admit that I'm stuck on that... RandomAccessFinite is in the same family as InputRange: an `interface` that defines/requires a set of range primitives (front, popFront, etc). The template parameter is the element type (e.g. MyObject). SortedRange is a different kind of template. The template parameter is a range type (e.g. MyObject[] or RedBlackTree!MyObject.Range). Replacing the one with the other doesn't make sense, and doesn't work. Beside that I understand that range interfaces like SorteRange are not idiomatic at all in D. So I don't mind using something else, but I can't see how a could make an "abstract" range from a RedBlackTree.Range struct. SortedRange is not an interface. It's one of those static-duck-typing wrappers. Different SortedRange instances are incompatible types, even when the element types of the wrapped ranges are the same. In contrast, different instances of InputRangeObject all implement the InputRange interface (and other more advanced interfaces like RandomAccessFinite when possible). So, different instances of InputRangeObject are compatible through those interfaces, given that the element types match. Now, if you'd want to go the static-duck-typing route, you'd ditch the MyObjectSet interface. Instead, you'd pass RedBlackTree!MyObject or just RedBlackTree around as a template argument, possibly implicitly. Maybe you could give an example of how you would use MyObjectSet. Then we could think about a template-based alternative. I wouldn't mind encapsulating it in another struct or class I would define myself, but it seems I cannot access the RedBlackTree.Range struct from outside... For exemple with: RedBlackTree.Range rbtRange = this.sequence[]; I get: Error: identifier 'Range' of 'RedBlackTree.Range' is not defined Note that `sequence` is declared as RedBlackTree!MyObject, not just RedBlackTree. There is no RedBlackTree.Range, but there is RedBlackTree!MyObject.Range.
Re: recursive definition error
On Monday, 7 July 2014 at 09:56:17 UTC, Marc Schütz wrote: On Monday, 7 July 2014 at 02:57:09 UTC, Frustrated wrote: So, I took all the code surrounding the error message(which was a lot of code) and stuck it into one .d file. No errors! Works as expected. So, WTF?!?! I guess now I have to attempt to split the code across modules to see WTF is going on? Maybe this is a modules issue. I know some of the code I'm using deals with module resolution and there was some talk in the main forum about changing something to do with modules. Could this be the issue? D really needs a better fing way to debug templates or improve the error messages. I'm dealing with about 20k lines of code spread across about 100 modules and the error messages are completely useless as when I put all the code surrounding what it says is causing the error, I do not get the error. Realize, this code works fine in 2.064 so it's not a coding issue as if something magical with my fingers when I copy the code from the modules into a single .d file. Either something was "fixed" or something was "broke"... after all the work I spend trying to figure out what was causing the problem, I'm just as clueless. Have you tried dustmite? It can also reduce source code split over several files. Thanks, I'll check it out.
Re: dependency graph
Thanks! Between the -deps flag and duml I think this is exactly what I need.
Re: File needs to be closed on Windows but not on Posix, bug?
On Monday, 7 July 2014 at 14:25:54 UTC, Regan Heath wrote: If I had to guess, I would say it would still be possible to access the file. It's documented so. I guess, linux implements file deletion with delete-on-close feature too, if it exists, a separate deletion operation is not needed.
Re: [dmd 2.066-b1] std.range.array with shared objects and AA rehash
On Monday, 7 July 2014 at 09:53:22 UTC, NCrashed wrote: I am using ranges (wrapped in InputRangeObject for use in interfaces) of shared objects, with new beta some cases are broken: ``` import std.range; class A {} InputRange!(shared A) foo() { return [new A].inputRangeObject; } void bar() { auto res = foo.array; } void main() {} ``` Fails with: ``` source/app.d(7): Error: cannot implicitly convert expression (inputRangeObject([new A])) of type std.range.InputRangeObject!(A[]).InputRangeObject to std.range.InputRange!(shared(A)).InputRange /usr/include/dmd/phobos/std/conv.d(3914): Error: cannot implicitly convert expression (arg) of type shared(A) to app.A /usr/include/dmd/phobos/std/array.d(2476): Error: template instance std.conv.emplaceRef!(shared(A)).emplaceRef!(shared(A)) error instantiating /usr/include/dmd/phobos/std/array.d(64):instantiated from here: put!(shared(A)) source/app.d(12):instantiated from here: array!(InputRange!(shared(A))) ``` And also AA starts behave strange in shared context: ``` shared string[][string] map; void main() { map.rehash; } ``` My AA is stored in shared class, the shared is inferred implicitly. Also following workaround works: ``` void main() { (cast(shared(string[])[string])map).rehash; } ``` Is this behavior a bug, or it works as expected? I don't know about your second problem, but the fix for your first problem is to construct a shared A. You're trying to create a normal A and have it implicitly casted to shared, which the compiler won't do. InputRange!(shared A) foo() { //"new shared A" instead of "new A" return [new shared A].inputRangeObject; }
Re: Ranges & containers : is it possible to get a SortedRange from a RedBlackTree ?
Hi again, The solution of making an array from the range works, but I'm concerned about the cost of instantiating a (potentially very large) array each time I need to walk across the set. Unless doing that is costless in D for any reason, it does not seem practical in my case. And when trying to compile the above example I got the following error: Error: template instance std.range.SortedRange!(InputRange!int) does not match template declaration SortedRange(Range, alias pred = "a < b") if (isRandomAccessRange!Range && hasLength!Range) I tried to replace SortedRange!InputRange thing with the following : RandomAccessFinite!(InputRange!MyObject) opSlice(); But then I got the folowing error: Error: template std.range.assumeSorted cannot deduce function from argument types !()(InputRange!int), candidates are: [...] And I must admit that I'm stuck on that... Beside that I understand that range interfaces like SorteRange are not idiomatic at all in D. So I don't mind using something else, but I can't see how a could make an "abstract" range from a RedBlackTree.Range struct. I wouldn't mind encapsulating it in another struct or class I would define myself, but it seems I cannot access the RedBlackTree.Range struct from outside... For exemple with: RedBlackTree.Range rbtRange = this.sequence[]; I get: Error: identifier 'Range' of 'RedBlackTree.Range' is not defined Or is it a syntax-related problem ? Thanks again for your help ! Fred
Re: File needs to be closed on Windows but not on Posix, bug?
On Mon, 07 Jul 2014 15:18:51 +0100, Jesse Phillips wrote: On Monday, 7 July 2014 at 12:00:48 UTC, Regan Heath wrote: But! I agree with Adam, leave it as a thin wrapper. Being a windows programmer by trade I would expect the remove to fail, I would not expect all my files to be opened with delete sharing enabled by default. R And I believe behavior is still different. In Linux an open file can be accessed even after a delete operation (unlink). But in Windows is that possible? Not sure, I've never done this. It's just not something you would typically want/try to do on windows. If I had to guess, I would say it would still be possible to access the file. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: File needs to be closed on Windows but not on Posix, bug?
It can be also a bad user experience, when delete succeeds only pertially and doesn't free the disk space. Delete-on-close flag should be better in this regard.
Re: File needs to be closed on Windows but not on Posix, bug?
On Monday, 7 July 2014 at 12:00:48 UTC, Regan Heath wrote: But! I agree with Adam, leave it as a thin wrapper. Being a windows programmer by trade I would expect the remove to fail, I would not expect all my files to be opened with delete sharing enabled by default. R And I believe behavior is still different. In Linux an open file can be accessed even after a delete operation (unlink). But in Windows is that possible?
Re: Ranges & containers : is it possible to get a SortedRange from a RedBlackTree ?
Thank you very much to all of you for these very quick and precise answers !! As well as for tour recommendations about D's idiomatisms, it seems very important to me since there are so many available paradigms in D. I'll try these solutions and I'll be able to go ahead with my first D project ;) For the time being I like D very much, I think this language deserves much more audience and I hope it will continue to grow ! No doubt that having more "polished" std.streams and std.containers will really help, especially for people coming from Java where these API are quite clean. Best regards, Frédérik
Re: Ranges & containers : is it possible to get a SortedRange from a RedBlackTree ?
Meta: (a SortedRange needs a range with random access, I think SortedRange was recently improved, and now accepts more than just random access ranges. Bye, bearophile
Re: Ranges & containers : is it possible to get a SortedRange from a RedBlackTree ?
On Monday, 7 July 2014 at 12:06:21 UTC, Frédérik wrote: I'm trying to achieve something like that (approximate D code): interface MyObjectSet { void add(MyObject o); void SortedRange!MyObject opSlice(); } class SomeRedBlackBasedImplementation { private RedBlackTree!MyObject sequence = new RedBlackTree!MyObject(); void add(MyObject o) { this.sequence.insert(o); } void SortedRange!MyObject opSlice() { ? } } I would need to get the range that comes from the red black tree (as returned by this.sequence[]) but I can't figure out how to map it to a generic interface like SortedRange that would be suitable to write a clean interface above. SortedRange is not a generic interface. Its template parameter is not the element type, but the type of the underlying range. It seems to me that the Range used by RedBlackTree is a kind of private struct that does not implement an interface but just complies with some implicit contract about range properties. Am I right ? yes (it's not `private`, but it's a type specific to RedBlackTree) If so how is it possible to make it fit in a more generic framework ? Use inputRangeObject(sequence[]) to get an instance of the InputRange interface over the range. Then use assumeSorted to get a SortedRange!(InputRange!MyObject). Of course, only use assumeSorted when the range is already sorted. Otherwise, use std.algorithm.sort. Such interface/Object oriented style is not very popular in D, though, as far as I can tell. Static duck typing through templates seems to be more fashionable, e.g. what you called "some implicit contract about range properties". Full, compiling example: import std.container: RedBlackTree; import std.range; alias MyObject = int; interface MyObjectSet { void add(MyObject o); SortedRange!(InputRange!MyObject) opSlice(); } class SomeRedBlackBasedImplementation : MyObjectSet { private RedBlackTree!MyObject sequence; this() { sequence = new RedBlackTree!MyObject(); } void add(MyObject o) { this.sequence.insert(o); } SortedRange!(InputRange!MyObject) opSlice() { InputRange!MyObject r = inputRangeObject(sequence[]); return assumeSorted(r); } } void main() { MyObjectSet x = new SomeRedBlackBasedImplementation; x.add(1); x.add(3); x.add(2); import std.algorithm: equal; assert(equal(x[], [1, 2, 3])); }
Re: Ranges & containers : is it possible to get a SortedRange from a RedBlackTree ?
Frédérik: Especially I can't figure out how std.containers can connect properly with std.ranges : std.containers is still primitive, it needs to be improved and fleshed out, after Andrei's memory allocators. I would need to get the range that comes from the red black tree (as returned by this.sequence[]) but I can't figure out how to map it to a generic interface like SortedRange that would be suitable to write a clean interface above. In Phobos there are very few true interfaces. Most "interfaces" are instead compile-time protocols for templates, that create different types. But in std.range there are also (rarely used) class-based range adaptors to do what you want. Regarding RedBlackTree not already returning SortedRange, I think this could be fixed. Bye, bearophile
Re: Ranges & containers : is it possible to get a SortedRange from a RedBlackTree ?
On Monday, 7 July 2014 at 12:06:21 UTC, Frédérik wrote: Hi all, I'm discovering the D language that seems very nice in many aspects, but I'm quite confused by the container and range APIs while trying to design a very simple interface-oriented API. Especially I can't figure out how std.containers can connect properly with std.ranges : I'm trying to achieve something like that (approximate D code): interface MyObjectSet { void add(MyObject o); void SortedRange!MyObject opSlice(); } class SomeRedBlackBasedImplementation { private RedBlackTree!MyObject sequence = new RedBlackTree!MyObject(); void add(MyObject o) { this.sequence.insert(o); } void SortedRange!MyObject opSlice() { ? } } I would need to get the range that comes from the red black tree (as returned by this.sequence[]) but I can't figure out how to map it to a generic interface like SortedRange that would be suitable to write a clean interface above. It seems to me that the Range used by RedBlackTree is a kind of private struct that does not implement an interface but just complies with some implicit contract about range properties. Am I right ? If so how is it possible to make it fit in a more generic framework ? Thank you all for your help Best regards, Fred There are a few problems with your code. Here and here: void SortedRange!MyObject opSlice(); void SortedRange!MyObject opSlice() { ? } You have specified two return types; both void and SortedRange!MyObject. I'm assuming you probably want the latter. Furthermore, you can't pass just MyObject as a template argument to SortedRange. SortedRange is a struct that must be instantiated with a type that supports the range interface, and a sorting function (the default is function(a, b) { return a < b; }). However, you also can't instantiate a SortedRange with RedBlackTree, as it doesn't implement the range interface that is a convention in D. You can get a range interface from RedBlackTree, but that *also* doesn't implement the proper interface (a SortedRange needs a range with random access, which RedBlackTree's range view doesn't support). Therefore, the simplest way is probably to make an array out of the RedBlackTree's elements and then wrapping it in a SortedRange. Your function would become: import std.array; import std.range; SortedRange!(MyObject[]) opSlice() { sequence[].array.assumeSorted; } assumeSorted is a function in std.range that assumes its argument is already sorted and wraps it in a SortedRange. The array function from std.array converts its argument into an array, which is in this case a range view of sequence, which you can get by slicing it as shown. It seems like a lot of annoyance to go through just to get a SortedRange like you want, which mostly stems from the fact that RedBlackTree doesn't expose a random access range interface for implementation reasons. Maybe this will be changed in the future; I don't know. As for your other question, it's more subjective and philosophical, so I'll leave that for someone else to answer.
Re: File needs to be closed on Windows but not on Posix, bug?
On Monday, 7 July 2014 at 11:17:35 UTC, Joakim wrote: On Monday, 7 July 2014 at 10:19:01 UTC, Kagamin wrote: See if stdio allows you to specify delete sharing when opening the file. In std.stdio, File(name, mode) is forwarded to _wfopen on Windows and to fopen on posix. On Windows there are many mode flags supported by the _wfopen function (link above): If you intend to delete the file immediately after closing it, you can use the "D" mode flag when instantiating the File struct. -or- You can write your own wrapper around CreateFile/Ex WinAPI function and use FILE_SHARE_DELETE for dwSharingMode; now you can safely delete the file without closing it even from another process.
Ranges & containers : is it possible to get a SortedRange from a RedBlackTree ?
Hi all, I'm discovering the D language that seems very nice in many aspects, but I'm quite confused by the container and range APIs while trying to design a very simple interface-oriented API. Especially I can't figure out how std.containers can connect properly with std.ranges : I'm trying to achieve something like that (approximate D code): interface MyObjectSet { void add(MyObject o); void SortedRange!MyObject opSlice(); } class SomeRedBlackBasedImplementation { private RedBlackTree!MyObject sequence = new RedBlackTree!MyObject(); void add(MyObject o) { this.sequence.insert(o); } void SortedRange!MyObject opSlice() { ? } } I would need to get the range that comes from the red black tree (as returned by this.sequence[]) but I can't figure out how to map it to a generic interface like SortedRange that would be suitable to write a clean interface above. It seems to me that the Range used by RedBlackTree is a kind of private struct that does not implement an interface but just complies with some implicit contract about range properties. Am I right ? If so how is it possible to make it fit in a more generic framework ? Thank you all for your help Best regards, Fred
Re: File needs to be closed on Windows but not on Posix, bug?
On Mon, 07 Jul 2014 12:17:34 +0100, Joakim wrote: On Monday, 7 July 2014 at 10:19:01 UTC, Kagamin wrote: See if stdio allows you to specify delete sharing when opening the file. I don't know what delete sharing is exactly, but the File constructor simply calls fopen and I don't see any option for the Windows fopen that seems to do it: http://msdn.microsoft.com/en-us/library/yeby3zcb.aspx The fopen variant that allows you to specify sharing is: http://msdn.microsoft.com/en-us/library/8f30b0db.aspx But it does not mention delete sharing there. CreateFile allows sharing to be specified for delete however: http://msdn.microsoft.com/en-gb/library/windows/desktop/aa363858(v=vs.85).aspx So... you could: - Call CreateFile giving you a "handle" - Call _open_osfhandle to get a "file descriptor" - Call _fdopen on the file descriptor to get a FILE* for it But! I agree with Adam, leave it as a thin wrapper. Being a windows programmer by trade I would expect the remove to fail, I would not expect all my files to be opened with delete sharing enabled by default. R -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: File needs to be closed on Windows but not on Posix, bug?
On Monday, 7 July 2014 at 10:19:01 UTC, Kagamin wrote: See if stdio allows you to specify delete sharing when opening the file. I don't know what delete sharing is exactly, but the File constructor simply calls fopen and I don't see any option for the Windows fopen that seems to do it: http://msdn.microsoft.com/en-us/library/yeby3zcb.aspx
Re: Visual D: Settings to Improve compil and link process
On Sunday, 6 July 2014 at 19:27:38 UTC, Rainer Schuetze wrote: Ok, that allows separate compilation of the class, but templates are still compiled with the rest of the program. I thought the templates were the part that cause the slow compilation. I had no chance to profile till now, but I don't think that the templates are slow. They just extract type information from primitive or struct arrays, and pass the type info and void array on. I have the impression that the whole rebuild-relink process of the library itself was taking so long, so I wanted ensure that the non-templte code ( the majority ) does not have to be compiled over and over again. These object files are in the library ;-) That means manual selection, though, as incremental builds to multiple object files don't work with dmd, and single file compilation is painfully slow. Not sure if I am getting this right, so when one object file has to be recompiled all other object files, even if up to date, would be recompiled ? The modules form MyProject do import the MyLib modules properly, I do not get compiler errors. However, the compiler should create Object files from MyLib modules, and the linker should link them. But he does not. On the other hand, when I add MyLib modules to MyProject ( Rightclick MyProject - add - existing item... MyLib source files ) then linking works. I do not understand why the later step is necessary. dmd does not compile imported modules, but rdmd does. Ähm ... not seeing the connection here either, why is this significant ? I feel that I could not explain my problem properly, so one example: Importing phobos modules. I do not have to define any import path or lib file in the project settings, I just need to import std.somthing. That's because the import path for phobos modules are stored in the dmd sc.ini file. When I want to import my modules which are somewhere on my hard-drive and not added to my project I need to tell the compiler where these modules can be found, using the additional import path project setting. That's fine, doing this. But result is, std.somthing works, my modules in a path known by the compiler don't work, giving me linker errors. Why ? ( I do not create a lib, I just want to import the module. )
Re: File needs to be closed on Windows but not on Posix, bug?
On windows files are traditionally opened without delete sharing, such files can't be deleted until closed, because all sharing options are always honored.
Re: File needs to be closed on Windows but not on Posix, bug?
See if stdio allows you to specify delete sharing when opening the file.
Re: recursive definition error
On Monday, 7 July 2014 at 02:57:09 UTC, Frustrated wrote: So, I took all the code surrounding the error message(which was a lot of code) and stuck it into one .d file. No errors! Works as expected. So, WTF?!?! I guess now I have to attempt to split the code across modules to see WTF is going on? Maybe this is a modules issue. I know some of the code I'm using deals with module resolution and there was some talk in the main forum about changing something to do with modules. Could this be the issue? D really needs a better fing way to debug templates or improve the error messages. I'm dealing with about 20k lines of code spread across about 100 modules and the error messages are completely useless as when I put all the code surrounding what it says is causing the error, I do not get the error. Realize, this code works fine in 2.064 so it's not a coding issue as if something magical with my fingers when I copy the code from the modules into a single .d file. Either something was "fixed" or something was "broke"... after all the work I spend trying to figure out what was causing the problem, I'm just as clueless. Have you tried dustmite? It can also reduce source code split over several files.
[dmd 2.066-b1] std.range.array with shared objects and AA rehash
I am using ranges (wrapped in InputRangeObject for use in interfaces) of shared objects, with new beta some cases are broken: ``` import std.range; class A {} InputRange!(shared A) foo() { return [new A].inputRangeObject; } void bar() { auto res = foo.array; } void main() {} ``` Fails with: ``` source/app.d(7): Error: cannot implicitly convert expression (inputRangeObject([new A])) of type std.range.InputRangeObject!(A[]).InputRangeObject to std.range.InputRange!(shared(A)).InputRange /usr/include/dmd/phobos/std/conv.d(3914): Error: cannot implicitly convert expression (arg) of type shared(A) to app.A /usr/include/dmd/phobos/std/array.d(2476): Error: template instance std.conv.emplaceRef!(shared(A)).emplaceRef!(shared(A)) error instantiating /usr/include/dmd/phobos/std/array.d(64):instantiated from here: put!(shared(A)) source/app.d(12):instantiated from here: array!(InputRange!(shared(A))) ``` And also AA starts behave strange in shared context: ``` shared string[][string] map; void main() { map.rehash; } ``` My AA is stored in shared class, the shared is inferred implicitly. Also following workaround works: ``` void main() { (cast(shared(string[])[string])map).rehash; } ``` Is this behavior a bug, or it works as expected?