Re: avoid toLower in std.algorithm.sort compare alias
On Sunday, April 22, 2012 08:20:13 Jay Norwood wrote: > The comment below worries me a little bit about std.string.icmp. > What if they are two 1MB strings that differ in he first > character? Does it really convert both strings to lower case > before comparing the first character? > > http://dlang.org/phobos/std_string.html#icmp > > "Technically, icmp(r1, r2) is equivalent to > cmp!"std.uni.toLower(a) < std.uni.toLower(b)"(r1, r2). " You can look at the code. It checks each of the characters in place. Unlike toLower, it doesn't need to generate a new string. But as far as the comparison goes, they're the same - hence that line in the docs. - Jonathan M Davis
Re: avoid toLower in std.algorithm.sort compare alias
On Sunday, 22 April 2012 at 02:29:45 UTC, Jonathan M Davis wrote: Regardless of whether it's the Big(O) complexity or the constant factor that's the problem here, clearly there's enough additional overhead that it's causing problems for Jay's particular case. It's also the sort of thing that can be easy to miss and then end up wondering why your code is so slow (if it actually matters in your particular situation). - Jonathan M Davis I haven't looked at strncmpi code, but I suspect it is a lot more efficient. For example, in comparing AbbbCdddEfffXabcdEfgh AbbbCdddEfffYabcdEfgh it is not necessary to do case conversion on anything except X and Y, and if isUpper(X)==isUpper(Y) then X and Y can be compared without conversion, and since X and Y are not equal the remaining characters don't have to be converted. The comment below worries me a little bit about std.string.icmp. What if they are two 1MB strings that differ in he first character? Does it really convert both strings to lower case before comparing the first character? http://dlang.org/phobos/std_string.html#icmp "Technically, icmp(r1, r2) is equivalent to cmp!"std.uni.toLower(a) < std.uni.toLower(b)"(r1, r2). "
Re: arrays and foreach
On Sat, 2012-04-21 at 22:14 -0700, Ali Çehreli wrote: [...] > That part is done: > >http://ddili.org/ders/d.en/hello_world.html As you are emphasizing use of dmd, and the initial programs will all be relatively small scripts, I wonder if using rdmd would be a good move. Shortening the edit--compile--execute by avoiding the two stage compile--execute is likely to lead to more energy on the part of the user: having an edit--execute cycle makes things a lot easier for developing small programs. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: arrays and foreach
On Sun, 2012-04-22 at 06:59 +0100, Russel Winder wrote: > On Sat, 2012-04-21 at 22:14 -0700, Ali Çehreli wrote: > [...] > > That part is done: > > > >http://ddili.org/ders/d.en/hello_world.html > > Surely "Hello World" shows just a few, and definitely not all, of the > essential concepts of a programming language. Crikey, my browser just updated with an edit :-) -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: arrays and foreach
On Sat, 2012-04-21 at 22:14 -0700, Ali Çehreli wrote: [...] > That part is done: > >http://ddili.org/ders/d.en/hello_world.html Surely "Hello World" shows just a few, and definitely not all, of the essential concepts of a programming language. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: arrays and foreach
On 04/18/2012 01:26 AM, Somedude wrote: > For a complete beginner, it's very frustrating to have to read 4 > chapters of fluff, then write the program, and still not knowing how to > run the program. Where is the fun ? I can guarantee that at this point, > 9 out of 10 beginners will drop the reading. [...] > The order of the beginning chapters I think should be: > Intro > Practice of programming > Hello world > writeln and write > Compiler > Fundamental types That part is done: http://ddili.org/ders/d.en/hello_world.html Thank you, Ali
Re: avoid toLower in std.algorithm.sort compare alias
On Saturday, April 21, 2012 18:26:42 H. S. Teoh wrote: > Actually, I don't think the nested loops affect Big-O complexity at all. > The O(l) complexity (where l = string length) is already inherent in the > string comparison "str < otherStr". Adding more loops over the strings > doesn't change the Big-O complexity (you just make O(l) into 3*O(l) > which is the same as O(l)). If the loop is really nested, then it will increase the Big(O) complexity, whereas if it's parallel to a similar loop, it will just increase the constant factor. Which it really is in this case, I don't know without sitting down and sketching out the exact algorithm, but certainly upon a first glance, it was my conclusion that the loops were nested. If they're not, then they're not. Regardless of whether it's the Big(O) complexity or the constant factor that's the problem here, clearly there's enough additional overhead that it's causing problems for Jay's particular case. It's also the sort of thing that can be easy to miss and then end up wondering why your code is so slow (if it actually matters in your particular situation). - Jonathan M Davis
Re: toLower() and Unicode are incomplete was: Re: avoid toLower in std.algorithm.sort compare alias
On Saturday, April 21, 2012 18:43:23 Ali Çehreli wrote: > On 04/21/2012 04:24 PM, Jay Norwood wrote: > > While playing with sorting the unzip archive entries I tried use of the > > last example in http://dlang.org/phobos/std_algorithm.html#sort > > > > std.algorithm.sort!("toLower(a.name) < > > toLower(b.name)",std.algorithm.SwapStrategy.stable)(entries); > > Stealing this thread to point out that converting a letter to upper or > lower case cannot be done without knowing the writing system. Phobos's > toLower() documentation currently says: "Returns a string which is > identical to s except that all of its characters are lowercase (in > unicode, not just ASCII)." > > Unicode cannot define the conversions of at least the following letters > without knowing the actual alphabet that the text is written in: > > - Lowercase of I is ı in some alphabets[*] and i in many others. > > - Uppercase of i is İ in some alphabets[*] and I in many others. > > Ali > > [*] Turkish, Azeri, Chrimean Tatar, Gagauz, Celtic, etc. toLower and toUpper get pretty screwing with unicode. I don't know enough about non-English alphabets to know what affects what, but at minimum, there are a number of cases where toLower does not reverse toUpper (and vice versa). Rather, it converts the character into yet another letter. So, toLower to toUpper with unicode and definitely a bit iffy. I suppose that they do the job if you call them enough on the string that it doesn't change anymore, but I don't know. I also don't know how they act with regards to the various alphabets and how their implementation was decided upon. IIRC, Walter wrote them, and I'm sure that they're based on the unicode standard, but what that amounts to, I don't know. - Jonathan M Davis
Re: avoid toLower in std.algorithm.sort compare alias
On Sunday, April 22, 2012 03:47:30 Jay Norwood wrote: > On Saturday, 21 April 2012 at 23:54:26 UTC, Jonathan M Davis > > wrote: > > Yeah. toLower would be called on both strings on _every_ > > compare. And since > > that involves a loop, that would make the overall call to sort > > an order of > > magnitude worse than if you didn't call toLower at all. I'm not > > sure if it's > > an order of magnitude worse than your solution though, since > > it's been a while > > since I studied Big(O) notation (doing the conversion only once > > is still more > > expensive than not converting, but I'm not sure how much more > > expensive - it > > might cost less than sort such that it actually doesn't matter > > as for as > > Big(O) goes though). > > > > - Jonathan M Davis > > use of toLower in the sort expression adds around 11.2 secs > overhead to a 0.3 sec operation which reads and sorts the 34k > directory entries in this 2GB layout on the ssd drive, so it > isn't an option for me. > > finished! time:312 ms > > finished! time:11598 ms > > std.algorithm.sort!("toLower(a) < > toLower(b)",std.algorithm.SwapStrategy.stable)(dirs); > //std.algorithm.sort!("a < b", > std.algorithm.SwapStrategy.stable)(dirs); It wasn't saying that it _was_ an option. I was just trying to point out the likely reason why it's so bad with toLower - algorithmically-speaking. This definitely appears to be a case where doing some extra computation ahead of time will save you a lot later. - Jonathan M Davis
Re: avoid toLower in std.algorithm.sort compare alias
On Saturday, 21 April 2012 at 23:54:26 UTC, Jonathan M Davis wrote: Yeah. toLower would be called on both strings on _every_ compare. And since that involves a loop, that would make the overall call to sort an order of magnitude worse than if you didn't call toLower at all. I'm not sure if it's an order of magnitude worse than your solution though, since it's been a while since I studied Big(O) notation (doing the conversion only once is still more expensive than not converting, but I'm not sure how much more expensive - it might cost less than sort such that it actually doesn't matter as for as Big(O) goes though). - Jonathan M Davis use of toLower in the sort expression adds around 11.2 secs overhead to a 0.3 sec operation which reads and sorts the 34k directory entries in this 2GB layout on the ssd drive, so it isn't an option for me. finished! time:312 ms finished! time:11598 ms std.algorithm.sort!("toLower(a) < toLower(b)",std.algorithm.SwapStrategy.stable)(dirs); //std.algorithm.sort!("a < b", std.algorithm.SwapStrategy.stable)(dirs);
toLower() and Unicode are incomplete was: Re: avoid toLower in std.algorithm.sort compare alias
On 04/21/2012 04:24 PM, Jay Norwood wrote: > While playing with sorting the unzip archive entries I tried use of the > last example in http://dlang.org/phobos/std_algorithm.html#sort > > std.algorithm.sort!("toLower(a.name) < > toLower(b.name)",std.algorithm.SwapStrategy.stable)(entries); Stealing this thread to point out that converting a letter to upper or lower case cannot be done without knowing the writing system. Phobos's toLower() documentation currently says: "Returns a string which is identical to s except that all of its characters are lowercase (in unicode, not just ASCII)." Unicode cannot define the conversions of at least the following letters without knowing the actual alphabet that the text is written in: - Lowercase of I is ı in some alphabets[*] and i in many others. - Uppercase of i is İ in some alphabets[*] and I in many others. Ali [*] Turkish, Azeri, Chrimean Tatar, Gagauz, Celtic, etc.
Re: avoid toLower in std.algorithm.sort compare alias
On Sat, Apr 21, 2012 at 05:45:35PM -0700, Jonathan M Davis wrote: > On Saturday, April 21, 2012 20:36:18 bearophile wrote: > > Jonathan M Davis: > > > I'm not sure if it's an order of magnitude worse than your > > > solution though, since it's been a while since I studied Big(O) > > > notation (doing the conversion only once is still more expensive > > > than not converting, but I'm not sure how much more expensive - it > > > might cost less than sort such that it actually doesn't matter as > > > for as Big(O) goes though). > > > > Performing the toLower every time the cmp function is called doesn't change > > the O complexity. > > Yes it does. It adds a loop to each comparison (two loops actually, > but since they're not nested, Big(O) only cares about the one), since > toLower has to loop over all of the characters. As sort loops over > each of the strings to compare them for moving them into a sorted > position or not, it calls toLower, which adds a nested loop, so it > increases the Big(O) complexity. Something like this > > foreach(str; strings) > str < otherStr; > > becomes > > foreach(str; strings) > { > foreach(dchar c; str) > //lower characters > > foreach(dchar c; otherStr) > //lower characters > > str < otherStr; > } > > though that's obviously very pseudo-code-ish and not exactly what sort > does. Regardless, those extra loops when the comparison happens are > nested and therefore increase the Big(O) complexity of the overall > algorithm. [...] Actually, I don't think the nested loops affect Big-O complexity at all. The O(l) complexity (where l = string length) is already inherent in the string comparison "str < otherStr". Adding more loops over the strings doesn't change the Big-O complexity (you just make O(l) into 3*O(l) which is the same as O(l)). However, always remember that Big-O notation hides constant factors and terms. These factors are negligible given a sufficiently large problem size, but for small problem sizes, the hidden constants are very much significant. An O(n log n) algorithm may actually take n*log(10*n) steps or 1000*n*log(n) steps; for large enough n, they're approximately the same, but when n is small, the 1000 has a very significant hit on observed performance. That's why optimizing the constant factors is sometimes necessary (provided you've already minimized the big-O complexity to the full, since otherwise you're just pinching pennies yet freely spending $100 bills). Inner loop optimization, like strength reduction, loop invariant hoisting, etc., are examples of where constant factors get optimized. If you have a loop: real x; for (i=0; i < n; i++) { // bigComplexCalculation is independent of i real n = bigComplexCalculation(x); // make use of n in some way } Then moving the bigComplexCalculation() call outside the loop improves the observed performance significantly, even though you're not changing the big-O complexity: a small change from 10*n to 8*n means a 20% improvement in observed performance, even though the algorithm still degrades linearly with problem size just like before. T -- Microsoft is to operating systems & security ... what McDonalds is to gourmet cooking.
Re: avoid toLower in std.algorithm.sort compare alias
On Saturday, April 21, 2012 20:36:18 bearophile wrote: > Jonathan M Davis: > > I'm not sure if it's > > an order of magnitude worse than your solution though, since it's been a > > while since I studied Big(O) notation (doing the conversion only once is > > still more expensive than not converting, but I'm not sure how much more > > expensive - it might cost less than sort such that it actually doesn't > > matter as for as Big(O) goes though). > > Performing the toLower every time the cmp function is called doesn't change > the O complexity. Yes it does. It adds a loop to each comparison (two loops actually, but since they're not nested, Big(O) only cares about the one), since toLower has to loop over all of the characters. As sort loops over each of the strings to compare them for moving them into a sorted position or not, it calls toLower, which adds a nested loop, so it increases the Big(O) complexity. Something like this foreach(str; strings) str < otherStr; becomes foreach(str; strings) { foreach(dchar c; str) //lower characters foreach(dchar c; otherStr) //lower characters str < otherStr; } though that's obviously very pseudo-code-ish and not exactly what sort does. Regardless, those extra loops when the comparison happens are nested and therefore increase the Big(O) complexity of the overall algorithm. - Jonathan M Davis
Re: avoid toLower in std.algorithm.sort compare alias
Jonathan M Davis: > I'm not sure if it's > an order of magnitude worse than your solution though, since it's been a > while > since I studied Big(O) notation (doing the conversion only once is still more > expensive than not converting, but I'm not sure how much more expensive - it > might cost less than sort such that it actually doesn't matter as for as > Big(O) goes though). Performing the toLower every time the cmp function is called doesn't change the O complexity. In Phobos there is an alternative sorting (Schwartzian sorting routime) that applies a function to each item before sorting them, usually is much slower than the normal sorting, but maybe this time it's convenient. The performance improvement in the OP message is large, maybe it's a problem of memory allocations of the converted strings... More info on the original code is needed to give better answers. Bye, bearophile
Regarding the more precise GC
In the main D newsgroup I have seen the two recent threads regarding a more precise GC in D. I have two questions about that, that seem more fit for D.learn. 1) I have not fully understood the performance and memory implications of the more precise GC. In the thread I think I've seen a memory overhead in every allocated struct. Is it possible to disable this bookkeeping/overhead for smaller programs that enjoy/need a GC but probably don't need a precise GC because they run only for no more than 30 seconds? Many of my small D programs are command-line utilities with a short run-time, but they often need a GC. 2) If I have a tagged union, like: static bool isPointer; union Foo { size_t count; int* ptr; } In every point of my program I know that inside a Foo there is a pointer or a size_t according to the value isPointer (a similar case is if I use a single bit tagging inside a size_t to denote if it's a pointer or an integral value. The D docs say that in the current conservative GC design such pointer tagging with a single bit is not allowed if the pointer is to CG-managed memory, but the union is allowed. Maybe with the more precise GC even the pointer tagging gets possible). Is it possible to tell to the precise GC every time it performs a collection if a Foo contains a pointer to follow, or if it instead contains just an integral value to ignore? I think it needs to be a function pointer or some kind of callback. Bye and thank you, bearophile
Re: Keyword to avoid not null references
I just pushed an update to git with a few changes people have suggested. I removed one of the old opAssigns to keep a static type check. Added assumeNotNull and checkNotNull as entry points. Made the data member private. I think that's closer to what everyone wants.
Re: avoid toLower in std.algorithm.sort compare alias
On Sunday, April 22, 2012 01:24:56 Jay Norwood wrote: > While playing with sorting the unzip archive entries I tried use > of the last example in > http://dlang.org/phobos/std_algorithm.html#sort > > std.algorithm.sort!("toLower(a.name) < > toLower(b.name)",std.algorithm.SwapStrategy.stable)(entries); > > It was terribly slow for sorting the 34k entries in my test > case. I'd guess it is doing the toLower call on both strings for > every compare. > > It was much, much faster to add an entries.lowerCaseName = > std.string.toLower(entries.name) foreach entry prior to the sort > execution and then use > > std.algorithm.sort!("a.lowerCaseName < b.lowerCaseName > ",std.algorithm.SwapStrategy.stable)(entries); > > The difference was on the order of 10 secs vs no noticeable delay > when executing the sort operation in the debugger. Yeah. toLower would be called on both strings on _every_ compare. And since that involves a loop, that would make the overall call to sort an order of magnitude worse than if you didn't call toLower at all. I'm not sure if it's an order of magnitude worse than your solution though, since it's been a while since I studied Big(O) notation (doing the conversion only once is still more expensive than not converting, but I'm not sure how much more expensive - it might cost less than sort such that it actually doesn't matter as for as Big(O) goes though). - Jonathan M Davis
Re: Keyword to avoid not null references
On Saturday, 21 April 2012 at 23:26:04 UTC, bearophile wrote: I think before putting something in Phobos it's generally better to have used it in Real Code for some time. I agree, but this comes up a LOT on the newsgroup, so I figure we need to get something up there to point people to. I am not sure a mostly-library-defined solution (mostly because @disable is a built-in) lol, all library implementations use language features! I will try to use your NotNull struct. Thanks! Let you know what you think of it. I'm sure we can do a good job with this.
Re: Keyword to avoid not null references
On Saturday, 21 April 2012 at 23:27:38 UTC, Namespace wrote: But one thing: i missed there an invariant which check if t is null. If i write "f.t = null;" no error occured. Don't do that! Maybe I should make t private...
Re: Keyword to avoid not null references
On Saturday, 21 April 2012 at 23:18:40 UTC, Namespace wrote: I see you're right. Great! But it is only on git hub and not in the standard typecons header in 2.059, right? Right, I missed the deadline for that.
Re: Keyword to avoid not null references
On Saturday, 21 April 2012 at 23:18:40 UTC, Namespace wrote: I see you're right. Great! But it is only on git hub and not in the standard typecons header in 2.059, right? But one thing: i missed there an invariant which check if t is null. If i write "f.t = null;" no error occured.
Re: Keyword to avoid not null references
Adam D. Ruppe: We can do not null in the library reasonably well. I have a basic one in github: https://github.com/D-Programming-Language/phobos/pull/477 It says: I haven't actually used any NotNull in practice, but from the attached tests, it looks like it will work well - hence, the pull request.< I think before putting something in Phobos it's generally better to have used it in Real Code for some time. I am not sure a mostly-library-defined solution (mostly because @disable is a built-in) is good enough compared to a solution built in the type system. I will try to use your NotNull struct. Bye, bearophile
avoid toLower in std.algorithm.sort compare alias
While playing with sorting the unzip archive entries I tried use of the last example in http://dlang.org/phobos/std_algorithm.html#sort std.algorithm.sort!("toLower(a.name) < toLower(b.name)",std.algorithm.SwapStrategy.stable)(entries); It was terribly slow for sorting the 34k entries in my test case. I'd guess it is doing the toLower call on both strings for every compare. It was much, much faster to add an entries.lowerCaseName = std.string.toLower(entries.name) foreach entry prior to the sort execution and then use std.algorithm.sort!("a.lowerCaseName < b.lowerCaseName ",std.algorithm.SwapStrategy.stable)(entries); The difference was on the order of 10 secs vs no noticeable delay when executing the sort operation in the debugger.
Re: Keyword to avoid not null references
I see you're right. Great! But it is only on git hub and not in the standard typecons header in 2.059, right?
Re: Keyword to avoid not null references
On Saturday, 21 April 2012 at 22:48:27 UTC, Namespace wrote: So every time i want to avoid null references i have to write "NotNull!(Foo) f" (or better, because it's a struct: "ref NotNull!(Foo) f")? It is already a reference! Otherwise, it couldn't be null anyway. But, yes, you'd write NotNull!Foo. If "NotNull" is too long for you, you could always alias it to something else. alias NotNull n; n!Foo f; whatever floats your boat. And therefore i must initialize them with NotNull!(Foo) f = new Foo();? That would be a little annoying. If you don't initialize it, it would be null... so yes, you have to initialize it. What if i needed in function bar only Foo f which can be null but in quatz i need a not null Reference? If it can be null, you check for null or assume it isn't and just pass it straight to NotNull. One of the pull request comments suggests adding assumeNotNull and checkNotNull to help with this. I'll add that later. In my opinion the best way would be to initialize them with Foo f = new Foo(); and if i pass them to bar, it will be implicit cast to NotNull!(Foo). An implicit cast to not null would defeat the point of the new type! It implicitly casts to the regular (nullable) type, but going from null to not null implicitly means you have no help in catching it from the type system.
Re: Keyword to avoid not null references
On 04/22/2012 12:48 AM, Namespace wrote: On Saturday, 21 April 2012 at 22:18:02 UTC, Adam D. Ruppe wrote: We can do not null in the library reasonably well. I have a basic one in github: https://github.com/D-Programming-Language/phobos/pull/477 So every time i want to avoid null references i have to write "NotNull!(Foo) f" (or better, because it's a struct: "ref NotNull!(Foo) f")? And therefore i must initialize them with NotNull!(Foo) f = new Foo();? That would be a little annoying. What if i needed in function bar only Foo f which can be null but in quatz i need a not null Reference? In my opinion the best way would be to initialize them with Foo f = new Foo(); and if i pass them to bar, it will be implicit cast to NotNull!(Foo). But this implies a runtime check. I think, that would be the best idea. The only thing that disturbing me, is, that it is a struct and therefore it passes by value instead as reference You might have a wrong mental model of how classes and structs work in D. A class reference is much like a struct of the following form: struct ClassRef{ ClassImpl* impl; } and that it is more to write as just "@" or "@ref". And only the trivial cases are catched during compilation.
Re: Keyword to avoid not null references
On 04/21/2012 11:40 PM, Namespace wrote: My question is, why D hasn't got an explicit Keyword to check at compile time for non null references? It shouldn't be a special keyword. If the compiler can do the necessary analysis to actually enforce that the reference cannot hold a null reference, then it should be the default. Most references are not null. I understand that such check when they're implicit and refer to all objects they slow down the programm, How would such a check slow down the program? The rest of your post seems to indicate that you want a compile time check. but why doesn't exist an explicit keyword like @ref or a simple '@' before the Object name or value. Right now it's very annoying because i get a cryptical error message "Access violation" without any further informations and I have to debug. Only that way I can find where the Null references would access and then, why _and_ where the null references came from. That sucks. I hate it and so i write in every method to avoid null references "assert(obj !is null);". Now i get an assertion if obj is null and also the file and line. 50% less work then before. But it's still a runtime error and explicit work which can easily be checked by the compiler at compile time. 'Easily' would be an oversimplification. There are distinct issues to be solved by the type system, mostly surrounding initialisation. Then i know: "oh there are null references and there shouldn't be any". So what are the reasons against a special keyword to let the compiler check for non references? There are seldom reasons _against_ a language feature. To make it in, there must be reasons to adapt it. And even more importantly, there must be a good design that integrates well with the rest of the language. Having a non-null type system would certainly be desirable, but it would be a breaking language change if it was actually designed to be useful. I didn't understood it. I heard similar regressions from C# and Java, In what way would that be a regression? so why didn't D made it better and did implement something for that? Some variants I have already seen: const Foo @obj, const @Foo obj or my favourite: const @ref Foo obj. Greetz Well, that is the grammar of the feature, but you have not described how it should work. (Saying that the compiler should emit an error for null references does not cut it.)
Re: Keyword to avoid not null references
On Saturday, 21 April 2012 at 22:18:02 UTC, Adam D. Ruppe wrote: We can do not null in the library reasonably well. I have a basic one in github: https://github.com/D-Programming-Language/phobos/pull/477 So every time i want to avoid null references i have to write "NotNull!(Foo) f" (or better, because it's a struct: "ref NotNull!(Foo) f")? And therefore i must initialize them with NotNull!(Foo) f = new Foo();? That would be a little annoying. What if i needed in function bar only Foo f which can be null but in quatz i need a not null Reference? In my opinion the best way would be to initialize them with Foo f = new Foo(); and if i pass them to bar, it will be implicit cast to NotNull!(Foo). I think, that would be the best idea. The only thing that disturbing me, is, that it is a struct and therefore it passes by value instead as reference and that it is more to write as just "@" or "@ref".
using ntfs write_through option to create an efficient unzipped layout
Below are measured times on operations on an unzipped 2GB layout. My observation is that use of a slightly modified version of std.file.write for the creation of the unzipped files results in a folder that is much more efficient for sequential file system operations. In particular, the ntfs rmdir takes 6 sec vs 161 sec when removing the layout. I don't have a clear explanation why this is faster, but there is some mention in the article bleow about lazy writes by ntfs if you don't use write-through, and I suspect that is involved. http://msdn.microsoft.com/en-us/library/windows/desktop/aa364218(v=vs.85).aspx All times on a seagate 7200rpm hard drive on win7-64 unzip rmd2 cpd rmdir (ntfs) xcopy (ntfs) uzp SEQ Par 86 secs 171 secs 21 secs 169 secs 91 secs uzp NS WT 157 secs12 secs 13 secs 6 sec 43 secs uzp NS WT Par 87 secs 16 secs 17 secs 17 sec 48 secs 7zip unzip 127 secs151 secs 135 secs 161 sec 68 secs myDefrag +15 min 3.5 secs 54.3 secs 4.3 sec 90 secs uzp SEQ Par is using the current std.file.write. Parallel ops during decompress. uzp NS WTis using a modified version of std.file.write, no SEQ, added WRITE_THROUGH uzp NS WT Par is same as above, but write operations parallel, 100 files per thread myDefrag is using sortByName to defrag the unzipped folder rmd2 is a parallel unzip, with 100 files per thread cpd is parallel copy with 100 files per thread copy from the hard drive to an ssd rmdir is the regular file system rdmir /q /s xcopy is ntfs xcopy /q /e /I from the hard drive to an ssd void writeThrough(in char[] name, const void[] buffer) { version(Windows) { alias TypeTuple!(GENERIC_WRITE, 0, null, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH, HANDLE.init) defaults; auto h = useWfuncs ? CreateFileW(std.utf.toUTF16z(name), defaults) : CreateFileA(toMBSz(name), defaults); cenforce(h != INVALID_HANDLE_VALUE, name); scope(exit) cenforce(CloseHandle(h), name); DWORD numwritten; cenforce(WriteFile(h, buffer.ptr, to!DWORD(buffer.length), &numwritten, null) == 1 && buffer.length == numwritten, name); } else version(Posix) return writeImpl(name, buffer, O_CREAT | O_WRONLY | O_TRUNC); }
Re: Question about arrays
On 4/22/12, Stephen Jones wrote: > My C programming lies in cobwebs but from memory an array was a > pointer to the zeroth index of a set of uniformly sized chunks of > memory. I am perplexed to find that in D a call to an array (of > float vertices for example) cannot be accomplished by handing &v > to functions that need the zeroth index. Is this because D holds > a pointer to an array object and the zeroth index is accessed > (via compiler background work) to &v[0]? > D array -> struct of a length and pointer to the first element. If you want to pass arrays to C functions you can do either of these: float[] arr; cFunc(arr.ptr, arr.length) cFunc(&arr[0], arr.length); I'm assuming the C function needs a length. Maybe this will make things clearer: void main() { int[] a = new int[](10); size_t count = *cast(size_t*)&a; // first element is the count assert(count == 10); a[0] = 5; a[1] = 100; int* iter = &a[0]; // or use a.ptr assert(*iter == 5); ++iter; assert(*iter == 100); } Of course you wouldn't really use this style of code in D, but if you have to pass arrays to C use the .ptr field or &arr[0]. On the other hand, passing jagged multidimensional arrays via .ptr to C functions isn't going to work out of the box, but that's another topic (and there's a workaround). A good article about D arrays/slices is here: http://dlang.org/d-array-article.html
Re: Question about arrays
On 04/21/2012 03:05 PM, Stephen Jones wrote: > My C programming lies in cobwebs but from memory an array was a pointer > to the zeroth index of a set of uniformly sized chunks of memory. Yes and no. :) What you are describing is the feature where an array decays to what you describe. But there is also the concept of array in C, which is a collection of elements side by side. When you apply sizeof to such a thing, you get the size of the whole thing. So, the whole thing is the array. But you are right, when passed to functions, they decay to "pointer to first element." > I am > perplexed to find that in D a call to an array (of float vertices for > example) cannot be accomplished by handing &v to functions that need the > zeroth index. Is this because D holds a pointer to an array object and > the zeroth index is accessed (via compiler background work) to &v[0]? In D, arrays are what they should have been in C :). A pointer and a size. Something the equivalent of the following (for the int type): struct int_Array { int * elements; size_t number_of_elements; } Correction: That is a slice (aka dynamic array). There is also the fixed-length arrays (aka static arrays) in D. If you pass the address of a slice, you are passing the address of such a struct variable. So don't bother with the address at all, just pass the array object by value. Ali
Re: Derelict2 openGL3 issues
Am 21.04.2012 23:49, schrieb Stephen Jones: On Saturday, 21 April 2012 at 11:02:51 UTC, David wrote: glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, null);//is this right casting a void pointer for 0 offset? I do it like this: cast(void*)OFFSET; e.g. cast(void*)12; Thankyou David. Just to complete the code for those who follow: it works if you change the above as follows: glBufferData(GL_ARRAY_BUFFER, v.length * GL_FLOAT.sizeof, &v, GL_STATIC_DRAW); to: glBufferData(GL_ARRAY_BUFFER, v.length * GL_FLOAT.sizeof, &v[0], GL_STATIC_DRAW); The null value in: glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, null); can be replaced with cast(void*)0 as David suggests, but the code runs either way. I don't quite understand the sizeof comment as writeln(GL_FLOAT.sizeof) gives me 4 which is what I expect. Although this is not the place for it, I would just like to plug Pelles C ide: http://my.opera.com/run3/blog/2012/02/09/d-programming-in-pelles-c Simple to set up. null is cast(void*)0, but sometimes you need differen offsets, that's why I showed you the cast(void*)-way. GL_FLOAT is an alias to float, it's just a personal thing, that I like to use the type (not an alias) of the array directly (to make things clearer) PS: &v[0] works, but you should use v.ptr, it is exactly what you want and it's the D-way.
Re: Keyword to avoid not null references
We can do not null in the library reasonably well. I have a basic one in github: https://github.com/D-Programming-Language/phobos/pull/477
Re: Broken link to D Programming Language Specification
On Saturday, 21 April 2012 at 20:56:27 UTC, Kamil Slowikowski wrote: This link fails to load for me: http://digitalmars.com/d/2.0/dlangspec.mobi I'd really like a copy for myself. Can I get it elsewhere? The eBook is a compilation of the pages on dlang.org, which sources are hosted on Github: https://github.com/D-Programming-Language/d-programming-language.org To generate the eBook, run: make dlangspec.mobi You will need the catdoc tool from the tools collection: https://github.com/D-Programming-Language/tools You will also need the kindlegen command line tool. The link should really be fixed too, but I'm not sure where it should point, and I'm not sure if dlangspec.mobi is part of the 'all' makefile target so that it's automatically built every time...
Question about arrays
My C programming lies in cobwebs but from memory an array was a pointer to the zeroth index of a set of uniformly sized chunks of memory. I am perplexed to find that in D a call to an array (of float vertices for example) cannot be accomplished by handing &v to functions that need the zeroth index. Is this because D holds a pointer to an array object and the zeroth index is accessed (via compiler background work) to &v[0]?
Re: Docs: Section on local variables
On Saturday, April 21, 2012 18:26:52 Andrej Mitrovic wrote: > On 4/21/12, H. S. Teoh wrote: > > It would be a major pain if every > > single time you need to temporarily suppress a section of code, you also > > have to hunt down every last stray variable that's now no longer > > referenced in the function and comment them out as well. > > Next thing you know the compiler will start warning me when I indent > my code with uneven number of spaces! It's not quite as bad as all that. It works reasonably well in Java and C# and for the most part isn't a big deal, but for D, init already solves the larger problem of variables with garbage values, and adding forced initializations on top of that definitely isn't worth it - especially when it requires flow control and can give false positives at times. I don't think that there's much question that Java and C#'s solution is better than the lack of one in C/C++. But D already has a solution and does not Java and C#'s on top of it. - Jonathan M Davis
Re: Derelict2 openGL3 issues
On Saturday, 21 April 2012 at 11:02:51 UTC, David wrote: glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, null);//is this right casting a void pointer for 0 offset? I do it like this: cast(void*)OFFSET; e.g. cast(void*)12; Thankyou David. Just to complete the code for those who follow: it works if you change the above as follows: glBufferData(GL_ARRAY_BUFFER, v.length * GL_FLOAT.sizeof, &v, GL_STATIC_DRAW); to: glBufferData(GL_ARRAY_BUFFER, v.length * GL_FLOAT.sizeof, &v[0], GL_STATIC_DRAW); The null value in: glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, null); can be replaced with cast(void*)0 as David suggests, but the code runs either way. I don't quite understand the sizeof comment as writeln(GL_FLOAT.sizeof) gives me 4 which is what I expect. Although this is not the place for it, I would just like to plug Pelles C ide: http://my.opera.com/run3/blog/2012/02/09/d-programming-in-pelles-c Simple to set up.
Keyword to avoid not null references
My question is, why D hasn't got an explicit Keyword to check at compile time for non null references? I understand that such check when they're implicit and refer to all objects they slow down the programm, but why doesn't exist an explicit keyword like @ref or a simple '@' before the Object name or value. Right now it's very annoying because i get a cryptical error message "Access violation" without any further informations and I have to debug. Only that way I can find where the Null references would access and then, why _and_ where the null references came from. That sucks. I hate it and so i write in every method to avoid null references "assert(obj !is null);". Now i get an assertion if obj is null and also the file and line. 50% less work then before. But it's still a runtime error and explicit work which can easily be checked by the compiler at compile time. Then i know: "oh there are null references and there shouldn't be any". So what are the reasons against a special keyword to let the compiler check for non references? I didn't understood it. I heard similar regressions from C# and Java, so why didn't D made it better and did implement something for that? Some variants I have already seen: const Foo @obj, const @Foo obj or my favourite: const @ref Foo obj. Greetz
Re: Nested RegEx
On 21.04.2012 22:46, H. S. Teoh wrote: On Sat, Apr 21, 2012 at 09:41:18PM +0400, Dmitry Olshansky wrote: On 21.04.2012 21:24, nrgyzer wrote: Hi guys, I'm trying to use std.regex to parse a string like the following: string myString = "preOuter {if condition1} content1 {if condition2} content2 {elseif condition3} content3 {else}any other content{/if}{/if} postOuter"; Simply put pure regex is incapable of arbitrary-nested if-else statements. In a sense if... /if is a case of balanced parens problem and it's widely know to form non-regular language. This is of theoretical interest to me. Very often I find myself wanting a concise way to express patterns with nested matching delimiters, but regexes can't do it. But to jump to a full-blown stack-based language seems like an overkill to me: stack languages can express *much* more than just nested delimiters, most of which is difficult to encapsulate in a nice, concise syntax like regexes. All I want is a simple way to express the kind of simple nesting that matching delimiters give. Recursive descent is not particularly bad unless minimal "grammar descent depth" is high. Example: a+b-c uses a quite a lot of recursive calls for grammar with e.g. 10+ operator precedence levels. I'm thinking of merging operator precedence parser with regex might be a happy marriage you know. Back to OP topic something along the lines of this will do it (beware of stack overflow): void parseIf(){ static int ifNest; if(input.startWith("{if")){ ifNest++; scope(exit) ifNest--; enforce(ifNest < 1, "conservative stack overflow"); parseCond(input[2..$-1]);//regex that does condition enforce(input[$-1] == '}', "close that if"); parseIf();//parse body or another nested if //parseElse();//goes here, as does elif } else parseBody();// the regex you used before } [...] One day I may add push-pop stack extensions (that allow this kind of thing) into regex but I'd have to think hard to make it efficient. [...] Plus, have a nice concise syntax for it (otherwise I might as well just write a recursive descent parser for it in the first place). Concise syntax & lots of power is a priority actually, because I can detect if push-pop stuff is used or not and pick the right engine for the job. So different big-oh complexity is not important. -- Dmitry Olshansky
Re: Operator overloading
Thank you very very much, Dmitry. Now all it's fine! Xan. On Friday, 20 April 2012 at 19:51:40 UTC, Dmitry Olshansky wrote: On 20.04.2012 23:33, Xan wrote: Yes, you're wright. So in. But what fails? I reveice these errors and I have no idea what fails! Sorry, the errors are: $ gdmd-4.6 algorisme.d algorisme.d:35: Error: 'this' is only defined in non-static member functions, not __funcliteral1 Easy - _this_ inside of function (T t) { return this.funcio(alg.funcio(t)); } Is not going to fly because there is no way to "store" _this_ in function, use delegates (this is a context and it has to be "copied" -> use delegates). But then you'd have to change to delegate everywhere. (and there is toDelegate function in std.functional, that converts function to delegate) algorisme.d:35: Error: function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary.__funcliteral1 cannot access frame of function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary algorisme.d:35: Error: function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary.__funcliteral1 cannot access frame of function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary algorisme.d:35: Error: function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary.__funcliteral1 cannot access frame of function algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int).opBinary algorisme.d:35: Error: constructor algorisme.Algorisme!(int,int).Algorisme.this (string nom, uint versio, int function(int) funcio) is not callable using argument types (string,int,_error_ function(int t) nothrow @system) algorisme.d:35: Error: cannot implicitly convert expression (__funcliteral1) of type _error_ function(int t) nothrow @system to int function(int) algorisme.d:52: Error: template instance algorisme.Algorisme!(int,int).Algorisme.opBinary!("*",int) error instantiating I update the gist: https://gist.github.com/2429005
Re: Nested RegEx
On Sat, Apr 21, 2012 at 09:41:18PM +0400, Dmitry Olshansky wrote: > On 21.04.2012 21:24, nrgyzer wrote: > >Hi guys, > > > >I'm trying to use std.regex to parse a string like the following: > > > >string myString = "preOuter {if condition1} content1 {if condition2} content2 > >{elseif condition3} content3 {else}any other content{/if}{/if} postOuter"; > > > > Simply put pure regex is incapable of arbitrary-nested if-else > statements. In a sense if... /if is a case of balanced parens > problem and it's widely know to form non-regular language. This is of theoretical interest to me. Very often I find myself wanting a concise way to express patterns with nested matching delimiters, but regexes can't do it. But to jump to a full-blown stack-based language seems like an overkill to me: stack languages can express *much* more than just nested delimiters, most of which is difficult to encapsulate in a nice, concise syntax like regexes. All I want is a simple way to express the kind of simple nesting that matching delimiters give. [...] > One day I may add push-pop stack extensions (that allow this kind of > thing) into regex but I'd have to think hard to make it efficient. [...] Plus, have a nice concise syntax for it (otherwise I might as well just write a recursive descent parser for it in the first place). T -- The day Microsoft makes something that doesn't suck is probably the day they start making vacuum cleaners... -- Slashdotter
Re: Docs: Section on local variables
On Sat, Apr 21, 2012 at 06:26:52PM +0200, Andrej Mitrovic wrote: > On 4/21/12, H. S. Teoh wrote: > > It would be a major pain if every single time you need to > > temporarily suppress a section of code, you also have to hunt down > > every last stray variable that's now no longer referenced in the > > function and comment them out as well. > > Next thing you know the compiler will start warning me when I indent > my code with uneven number of spaces! And dlang.org gets mysteriously renamed to python4.org ... :-P T -- Programming is not just an act of telling a computer what to do: it is also an act of telling other programmers what you wished the computer to do. Both are important, and the latter deserves care. -- Andrew Morton
Re: Docs: Section on local variables
On Sat, Apr 21, 2012 at 06:42:06PM +0200, bearophile wrote: > H. S. Teoh: > > >>Why do you want to be able to declare local variables and then > >>never use them? > >[...] > > > >It happens a lot when you're debugging code (temporarily comment out > >some stuff for testing purposes). It would be a major pain if every > >single time you need to temporarily suppress a section of code, you > >also have to hunt down every last stray variable that's now no longer > >referenced in the function and comment them out as well. And then do > >the reverse after you're done testing whatever it is you're trying to > >debug. [...] > So are you saying that in 'finished' code (when you aren't working on > it) you don't want unused variables? In finished code, it's obviously a bad thing to have unused variables (unless the compiler optimizes them away, but that's not happening 'cos it depends on flow analysis, which would have let us spit out warnings about it in the first place.) > So do you prefer just an unused variable warning that comes out only > when you use "-wi/-w"? A problem I've seen in D.learn is that lot of > people here doesn't seem to use -wi/-w. Or maybe, on the contrary, > this unused variable error should be suppressed only if the D code is > compiled with "-debug"? I don't know if conflating unused variable warnings with -debug is a good thing. Just like the conflation of -release with the opposite of -debug or -unittest. > >(Yes, yes, I know variables are supposed to be declared right before > >they're used, not at the top of the function... but sometimes things > >move apart after enough code iterations.) > > Then adding some pressure to remind to keep such distance short may be > a good thing :-) This is not always possible. Sometimes you *need* to declare a variable outside a loop, which is only used much deeper inside the loop, because it needs to persist across iterations. Moving it close to where it's used breaks its semantics. > And beside unused variables, there is also this: > http://d.puremagic.com/issues/show_bug.cgi?id=4694 [...] In my mind, that's a more general issue that includes detecting unused variables as a special case. Both depend on flow analysis, which apparently Walter is not fond of (I can't tell why). Both are nice to have, but I don't know if it will happen. T -- Without outlines, life would be pointless.
Re: variadic mixin templates and other stuff
On 20.4.2012 19:00, John Chapman wrote: > On Friday, 20 April 2012 at 14:57:03 UTC, Martin Drasar wrote: >> On 20.4.2012 16:09, Timon Gehr wrote: >> >> I tried but it still refuses to compile: >> >> string interfaceGuid(string ifaceName) >> { >> return ifaceName ~ "Guid"; >> } >> >> mixin template EXPOSE_INTERFACES(T...)(T args) > > Try this: > > mixin template EXPOSE_INTERFACES(T...) > >> { >> void QueryInterface(ref IComponent comp, string guid) >> { >> foreach (arg; args) > > and this: > > foreach (arg; T) > >> { >> if (mixin(interfaceGuid(arg)) == guid) {} >> } >> } >> } >> Hi John, thanks very much. That did the trick. I am still wondering - why my previous code did not work? This is the syntax I have adopted from variadic functions in TDPL. Why does it work with functions and not mixin templates? Thanks, Martin
Re: Nested RegEx
On 21.04.2012 21:24, nrgyzer wrote: Hi guys, I'm trying to use std.regex to parse a string like the following: string myString = "preOuter {if condition1} content1 {if condition2} content2 {elseif condition3} content3 {else}any other content{/if}{/if} postOuter"; Simply put pure regex is incapable of arbitrary-nested if-else statements. In a sense if... /if is a case of balanced parens problem and it's widely know to form non-regular language. The way out is to either preconstruct regex pattern for a given maximum depth or just use handwritten parser (it may use regex for parts of input internally). One day I may add push-pop stack extensions (that allow this kind of thing) into regex but I'd have to think hard to make it efficient. (look at .NET regex they kind of have syntax for this but it's too underpowered for my taste) Is there any chance to use std.regex to parse the string above? I currently used the following expression: auto r = regex(`(.*?)\{if:(?P(.+?))\}(?P(.*))(\{/if\}) (.*)`, "g"); but it doesn't fit my nested if- and else-statements correctly. Thanks in advance for any suggestions! -- Dmitry Olshansky
Nested RegEx
Hi guys, I'm trying to use std.regex to parse a string like the following: string myString = "preOuter {if condition1} content1 {if condition2} content2 {elseif condition3} content3 {else}any other content{/if}{/if} postOuter"; Is there any chance to use std.regex to parse the string above? I currently used the following expression: auto r = regex(`(.*?)\{if:(?P(.+?))\}(?P(.*))(\{/if\}) (.*)`, "g"); but it doesn't fit my nested if- and else-statements correctly. Thanks in advance for any suggestions!
Re: Docs: Section on local variables
H. S. Teoh: Why do you want to be able to declare local variables and then never use them? [...] It happens a lot when you're debugging code (temporarily comment out some stuff for testing purposes). It would be a major pain if every single time you need to temporarily suppress a section of code, you also have to hunt down every last stray variable that's now no longer referenced in the function and comment them out as well. And then do the reverse after you're done testing whatever it is you're trying to debug. How do Go programmers cope with this (I think in Go unused variables are errors)? So are you saying that in 'finished' code (when you aren't working on it) you don't want unused variables? So do you prefer just an unused variable warning that comes out only when you use "-wi/-w"? A problem I've seen in D.learn is that lot of people here doesn't seem to use -wi/-w. Or maybe, on the contrary, this unused variable error should be suppressed only if the D code is compiled with "-debug"? (Yes, yes, I know variables are supposed to be declared right before they're used, not at the top of the function... but sometimes things move apart after enough code iterations.) Then adding some pressure to remind to keep such distance short may be a good thing :-) And beside unused variables, there is also this: http://d.puremagic.com/issues/show_bug.cgi?id=4694 Bye, bearophile
Re: Docs: Section on local variables
On 4/21/12, H. S. Teoh wrote: > It would be a major pain if every > single time you need to temporarily suppress a section of code, you also > have to hunt down every last stray variable that's now no longer > referenced in the function and comment them out as well. Next thing you know the compiler will start warning me when I indent my code with uneven number of spaces!
Re: BigInt Bug or just me?
Al 21/04/12 16:42, En/na Tyro[17] ha escrit: > Actually, in that case it only happens when compiling to 64-bit. > > Note: comb1(BigInt(40), BigInt(20))/2; The the BigInt version is > being divided by two (on MAC OS X) in order to yield the > correct result. > You are right, sorry. My test was done in a Linux 64-bit. -- Jordi Sayol
Re: Docs: Section on local variables
On Sat, Apr 21, 2012 at 01:03:13PM +0100, Stewart Gordon wrote: > On 20/04/2012 01:53, Andrej Mitrovic wrote: [...] > >It is an error to declare a local variable that is never referred to. > >Dead variables, like anachronistic dead code, are just a source of > >confusion for maintenance programmers. " > > > Why do you want to be able to declare local variables and then never > use them? [...] It happens a lot when you're debugging code (temporarily comment out some stuff for testing purposes). It would be a major pain if every single time you need to temporarily suppress a section of code, you also have to hunt down every last stray variable that's now no longer referenced in the function and comment them out as well. And then do the reverse after you're done testing whatever it is you're trying to debug. (Yes, yes, I know variables are supposed to be declared right before they're used, not at the top of the function... but sometimes things move apart after enough code iterations.) T -- Democracy: The triumph of popularity over principle. -- C.Bond
Re: BigInt Bug or just me?
On Saturday, 21 April 2012 at 14:30:49 UTC, Jordi Sayol wrote: Al 21/04/12 16:07, En/na Tyro[17] ha escrit: Why does the following implementation of the binomial coefficient yield two different answers? Only happens when compiling to 32-bit. 32-bit: (40 20) = 137846528820 (40 20) = 68923264410 64-bit: (40 20) = 137846528820 (40 20) = 137846528820 Actually, in that case it only happens when compiling to 64-bit. Note: comb1(BigInt(40), BigInt(20))/2; The the BigInt version is being divided by two (on MAC OS X) in order to yield the correct result.
Re: BigInt Bug or just me?
Al 21/04/12 16:07, En/na Tyro[17] ha escrit: > Why does the following implementation of the binomial coefficient yield two > different answers? > Only happens when compiling to 32-bit. 32-bit: (40 20) = 137846528820 (40 20) = 68923264410 64-bit: (40 20) = 137846528820 (40 20) = 137846528820 -- Jordi Sayol
BigInt Bug or just me?
Why does the following implementation of the binomial coefficient yield two different answers? import std.stdio, std.bigint; void main() { // Correct result when using long writeln("(40 20) = ", binomial(40L, 20L)); // 2 times the expected result when using BigInt writeln("(40 20) = ", binomial(BigInt(40), BigInt(20))/2); } T binomial(T)(T n, T k) { T iter(T n, T k, T i, T prev) { if (i >= k) return prev; return iter(n, k, i+1, ((n-i)*prev)/(i+1)); } if (k > (n-1)) return iter(n, k, cast(T)0, cast(T)1); return iter(n, (n-k), cast(T)0, cast(T)1); } Additionally, why is there no implicit conversion from integer to BigInt? Surely now precision will be lost when performing this conversion. All those casts are butt ugly if you ask me. I believe one should be able to assign any integral value to BigInt and reasonably expect that it be implicitly converted. Thanks, Andrew
Re: Docs: Section on local variables
On 20/04/2012 01:53, Andrej Mitrovic wrote: Can I remove this section from the D docs, in functions? : " Local Variables It is an error to use a local variable without first assigning it a value. The implementation may not always be able to detect these cases. Other language compilers sometimes issue a warning for this, but since it is always a bug, it should be an error. This does seem to be a total contradiction of the principle that's stated elsewhere in the D spec that variables are always initialised. It is an error to declare a local variable that is never referred to. Dead variables, like anachronistic dead code, are just a source of confusion for maintenance programmers. " Why do you want to be able to declare local variables and then never use them? Stewart.
Re: Formatting dates in std.datetime?
On 20/04/2012 21:29, H. S. Teoh wrote: Is there a way to format std.datetime.Date objects with a custom format string? My utility library has a datetime module with a custom formatting facility. http://pr.stewartsplace.org.uk/d/sutil/ The format string scheme is one of my own design, using repeated-letter format specifiers similar to those found in some other schemes, and designed to be logical, natural-looking, extensible and easy to remember. It doesn't currently have functions to convert between its types and those in std.datetime, but it's straightforward to construct a DateTimeComponents from a std.datetime.Date structure and then call its format method, if you still want to use the std.datetime API and just use my library for formatting. In particular, I'd like to reuse month short names defined in std.datetime, but it appears that the names are private. I'd really rather not duplicate them by hand, if there's a way to get them. My library has these arrays public. But I agree that it was somewhat gratuitous to make them private in std.datetime. Stewart.
Re: Derelict2 openGL3 issues
Am 21.04.2012 01:16, schrieb Stephen Jones: glBufferData(GL_ARRAY_BUFFER, v.length * GL_FLOAT.sizeof, &v, GL_STATIC_DRAW); Error spotted! This has to be: glBufferData(GL_ARRAY_BUFFER, v.length * float.sizeof, v.ptr, GL_STATIC_DRAW); float.sizeof is just cosmetic, the important thing is v.ptr, &v returns a pointer to a D array not the raw data in memory.
Re: Derelict2 openGL3 issues
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, null);//is this right casting a void pointer for 0 offset? I do it like this: cast(void*)OFFSET; e.g. cast(void*)12;
Re: Equivalents to policy classes in D
On 20/04/12 04:36, Joseph Rushton Wakeling wrote: On 03/04/12 02:24, Cristi Cobzarenco wrote: Mixins templates would be the answer: OK, I've had a go at writing up some mixin template-based policy code of my own. Oh, fun. You can even have the constructor provided by a template mixin ... ! :-D