cl4d - OO wrapper for the OpenCL C API
Just wanted to let you know that cl4d is basically usable now. Some things like OpenGL interoperability still need to be finished though and of course it needs to be extensively tested for bugs. http://bitbucket.org/trass3r/cl4d
Re: Patterns of Bugs
On Sat, 08 Jan 2011 20:53:20 +, Iain Buclaw wrote: == Quote from Ellery Newcomer (ellery-newco...@utulsa.edu)'s article On 01/08/2011 02:37 PM, Iain Buclaw wrote: Never let indentation fool you, the else clause will be assumed to be for the first condition. :o) I don't believe you Are you saying it *isn't* interpreted as: if (i) if (j) printf(J true\n); else printf(I false\n); :o From the grammar: The 'dangling else' parsing problem is solved by associating the else with the nearest if statement. http://www.digitalmars.com/d/2.0/statement.html#IfStatement -Lars
Re: eliminate junk from std.string?
Lars T. Kyllingstad: My suggestions for things to remove: hexdigits, digits, octdigits, lowercase, letters, uppecase, whitespace - What are these arrays useful for? capwords() - It tries to do too much. zfill() - The ljustify(),rjustify(), and center() functions should instead take an optional padding character that defaults to a space. maketrans(), translate() - I don't even understand what these do. inPattern(), countchars(), removechars() - Pattern matching is std.regex's charter. squeeze(), succ(), tr(), soundex(), column() - I am having a very hard time imagining myself ever using these functions... I agree with about nothing you have said :-) How much string processing you do day by day? I am using most of those things... If you are used in using Python or Ruby you probably find most of those things useful. If Andrei removes arrays like lowercase, letters, uppecase, I will have to write them myself in code. ljustify(),rjustify(), and center() are very useful, even if they may be improved in some ways. maketrans() and translate() (as other things) come from Python string functions, and I have used them a hundred times in string processing code. I have used squeeze() some times. soundex is not hurting, because even if it's not commonly necessary, its name is easy to understand and it's not easy to miss for something different, so it doesn't add much noise to the library. And I've seen that it's easy to implement soundex wrongly, while the one in the std.string is correct. I agree that too much stuff is generally bad in a library, because searching for something requires more time if there are more items to search into. In Bugzilla I have three or four bug reports that ask for few small changes in std.string (like removing chop and keeping chomp). But please don't remove too much. In a library more is often better. Bye, bearophile
Re: eliminate junk from std.string?
On Mon, 10 Jan 2011 03:41:51 -0500, bearophile wrote: Lars T. Kyllingstad: My suggestions for things to remove: hexdigits, digits, octdigits, lowercase, letters, uppecase, whitespace - What are these arrays useful for? capwords() - It tries to do too much. zfill() - The ljustify(),rjustify(), and center() functions should instead take an optional padding character that defaults to a space. maketrans(), translate() - I don't even understand what these do. inPattern(), countchars(), removechars() - Pattern matching is std.regex's charter. squeeze(), succ(), tr(), soundex(), column() - I am having a very hard time imagining myself ever using these functions... I agree with about nothing you have said :-) How much string processing you do day by day? I am using most of those things... If you are used in using Python or Ruby you probably find most of those things useful. If Andrei removes arrays like lowercase, letters, uppecase, I will have to write them myself in code. ljustify(),rjustify(), and center() are very useful, even if they may be improved in some ways. maketrans() and translate() (as other things) come from Python string functions, and I have used them a hundred times in string processing code. I have used squeeze() some times. soundex is not hurting, because even if it's not commonly necessary, its name is easy to understand and it's not easy to miss for something different, so it doesn't add much noise to the library. And I've seen that it's easy to implement soundex wrongly, while the one in the std.string is correct. I think you may have misunderstood some of my suggestions. For instance, I never proposed to remove ljustify(), rjustify(), and center(). Rather, I would have them take an extra 'padding' parameter, so we can eliminate zfill(). Before: auto s = zfill(123, 6); After: auto s = rjustify(123, 6, '0'); As for the other things I suggested, well... those are the things i vote to remove from std.string. If they only get that one vote, they stay. ;) By the way, since you seem to be using these things quite often, maybe you can answer this: 1. What are the hexdigits, digits, octdigits, lowercase, letters, uppercase, and whitespace arrays useful for? The only thing I can think of is to check whether a character belongs to one of them, but I think that is better done with the std.ctype functions. 2. What do maketrans() and translate() do? (A brief example would be nice.) -Lars
Re: -0 assigned to a FP variable
On 10/01/11 11:27, bearophile wrote: A bug I've introduced once in my D code, are you able to spot it? void main() { double x = +0; double y = -0; } The bug: 'y' isn't the desired double -0.0 To avoid this bug DMD may keep the -0 and +0 integer literals represented in two distinct ways, so they have two different values when/if assigned to a floating point. (But here D will behave a little differently from C). An alternative is to just add a warning to DMD. A third possibility is to just ignore this probably uncommon bug :-) Bye, bearophile Hi bearophile, This time it really looks like you are trying to pull the wings off of a butterfly. But in this case me thinks the butterfly wins. Best regards and Happy New Year, Justin Johansson
Re: -0 assigned to a FP variable
On 10/01/11 11:27, bearophile wrote: A bug I've introduced once in my D code, are you able to spot it? void main() { double x = +0; double y = -0; } The bug: 'y' isn't the desired double -0.0 To avoid this bug DMD may keep the -0 and +0 integer literals represented in two distinct ways, so they have two different values when/if assigned to a floating point. (But here D will behave a little differently from C). An alternative is to just add a warning to DMD. A third possibility is to just ignore this probably uncommon bug :-) Bye, bearophile A bug I've introduced once in my D code, are you able to spot it? void main() { double x = +0; double y = -0; } The butterfly answers back to you. There is no bug. Did you mean code void main() { double x = +0.0; double y = -0.0; } /code ? Are you able to spot it? Is it still a bug? Cheers Justin
Re: std.unittests for (final?) review [Update]
Okay, here's the new code and its documentation: http://is.gd/ktURa I followed Andrei's suggestion and merged most of the functions into a highly flexible assertPred. I also renamed the functions as suggested and attempted to fully document everything with fully functional examples instead of examples using types or functions which don't actually exist. So, now there's just assertThrown, assertNotThrown, collectExceptionMsg, and assertPred (though there are eight different overloads of assertPred). So, review away. From the sounds of it, if this code gets voted in, it'll be going into std.exception. - Jonathan M Davis
Re: -0 assigned to a FP variable
Le 10/01/2011 01:27, bearophile a écrit : A bug I've introduced once in my D code, are you able to spot it? void main() { double x = +0; double y = -0; } The bug: 'y' isn't the desired double -0.0 To avoid this bug DMD may keep the -0 and +0 integer literals represented in two distinct ways, so they have two different values when/if assigned to a floating point. (But here D will behave a little differently from C). An alternative is to just add a warning to DMD. A third possibility is to just ignore this probably uncommon bug :-) Bye, bearophile Hi, Do you suggest the compiler should guess you want -0.0 and convert 0 to double before applying the unary minus operator ? I suppose such a fix would be likely to create many more bugs than the one it is suppose to solve. I don't have a clue on what kind of user code needs to differentiate 0.0 and -0.0 fp litterals, but I humbly suppose that it must be kind of rare.
Re: Assuming structs are cheap to copy?
On 10/01/11 03:06, Peter Alexander wrote: I remember there was a discussion a little while back about how Phobos would assume that structs are cheap to copy, and would simply pass them by value. Is this assumption now the D way? Should we all just pass structs by value, assuming cheap copy construction? If so, I think this needs to be documented somewhere (assuming it isn't already), because it's a radical departure from C++, and also from most other languages (where everything is a reference type). People need to be aware of this. What if the byte size of some struct is say a KB or a MB would one still think that copy construction is cheap? In this instance I would not blame poor performance on Phobos but rather than your own design. Cheers Justin
Re: Assuming structs are cheap to copy?
On 10/01/11 03:06, Peter Alexander wrote: I remember there was a discussion a little while back about how Phobos would assume that structs are cheap to copy, and would simply pass them by value. Is this assumption now the D way? Should we all just pass structs by value, assuming cheap copy construction? If so, I think this needs to be documented somewhere (assuming it isn't already), because it's a radical departure from C++, and also from most other languages (where everything is a reference type). People need to be aware of this. OTOH maybe I missed your point. Cheers Justin
Re: std.unittests for (final?) review [Update]
On Monday 10 January 2011 05:40:39 Justin Johansson wrote: On 10/01/11 23:29, Jonathan M Davis wrote: From the sounds of it, if this code gets voted in, it'll be going into std.exception. - Jonathan M Davis May it be asked by what authority you can say that (ie. as said above)? Andrei's posts in this thread. Assuming that the code passes the vote (the deadline for which he set as February 7th), he thinks that std.exception is the best place for it rather than it being in its own module. - Jonathan M Davis
Re: Assuming structs are cheap to copy?
On Sun, 09 Jan 2011 11:06:22 -0500, Peter Alexander peter.alexander...@gmail.com wrote: I remember there was a discussion a little while back about how Phobos would assume that structs are cheap to copy, and would simply pass them by value. Is this assumption now the D way? Should we all just pass structs by value, assuming cheap copy construction? The discussion was about assumptions that ranges will make on their elements. Essentially, ranges will expect their element types to be cheaply copied. This does not mean that all structs need be cheaply copyable, nor that ranges cannot be used with expensive-to-copy element types. It just means that for the algorithms defined on ranges, the complexity stated depends on the elements being cheaply copyable. If so, I think this needs to be documented somewhere (assuming it isn't already), because it's a radical departure from C++, and also from most other languages (where everything is a reference type). People need to be aware of this. AFAIK, there has not been a conclusion to this. Once there is, if cheap copy assumption is the result, then I expect documentation to reflect that (probably at top of std.range and std.algorithm). -Steve
Re: opEquals for structs
On Sun, 09 Jan 2011 11:45:31 -0500, Mafi m...@example.org wrote: Just tried to implemnt Perl6-like junctions. Despite template functions overloading against varadic and non-variadic (ie T[] and T[]...) does not work, why has a struct opEquals to be S.opEquals(ref const(S))? Why can't I compare a class against a struct or in my case a struct against an int? I can't even compare a struct against a struct of another type. I'm curious for the reason of this. It's an ill-advised design decision that was driven by the requirement to make the default opEquals be able to call it's elements' opEquals functions. The reasoning goes, a struct like this: struct S { M m; } where M is another struct or object type, which may define an opEquals, then the default opEquals defined for S should look like this: bool opEquals(ref const(S) other) const { return other.m == m; } Now, what if M did not have an equivalent opEquals signature? Then no comparison could be made. The chosen path to solve this problem is to force all structs to have that type of signature, instead of just barfing on compiling S == S. There is a bug report on this, and I believe it will be fixed eventually. Right now, the focus is on getting 64-bit dmd working. http://d.puremagic.com/issues/show_bug.cgi?id=3659 Note, as a workaround, you can define an opEquals with the *required* signature, and overload it with another. For example, you can do: struct S { M m; bool opEquals(ref const(S) other) const { return other.m == m; } bool opEquals(int other) const { return other == m.asInt; } } But you are SOL if you want to do something like templatize opEquals. Expect the situation to get better. Meanwhile, you can vote for the bug. -Steve
Forward declaration error with auto
Referring to functions declared later inside a module with return type auto causes an error, but not when the return type is explicitly declared. The same goes for calling functions in other modules with return type auto. Is this supposed to happen?
Re: Forward declaration error with auto
Sean Eskapp eatingstap...@gmail.com wrote: Referring to functions declared later inside a module with return type auto causes an error, but not when the return type is explicitly declared. The same goes for calling functions in other modules with return type auto. Is this supposed to happen? Nope. Likely bug #2810[1]. [1]: http://d.puremagic.com/issues/show_bug.cgi?id=2810 -- Simen
Re: Forward declaration error with auto
I've repoted this a few days ago: http://d.puremagic.com/issues/show_bug.cgi?id=5433
Re: eliminate junk from std.string?
Lars T. Kyllingstad pub...@kyllingen.nospamnet wrote in message news:igeia5$1t4...@digitalmars.com... 1. What are the hexdigits, digits, octdigits, lowercase, letters, uppercase, and whitespace arrays useful for? The only thing I can think of is to check whether a character belongs to one of them, but I think that is better done with the std.ctype functions. They're good for people like me who never noticed std.ctype ;)
Re: RFC: Case-Insensitive Strings (And usually they really do *have*case)
Jim bitcir...@yahoo.com wrote in message news:igfado$11g...@digitalmars.com... While writing and dealing with all that code I realized something: While programmers are usually heavily conditioned to think of case-sensitivity as an attribute of the comparison, it's very frequent that the deciding factor in which comparison to use is *not* the comparison itself but *what* gets compared. And in those cases, you have to use the awful strategy of relying on convention to make sure you get it right in *every* place that particular data gets compared. You have a point. Your case-sensitivity-aware string types will guarantee correctness in a large and complex program. I like that. Ideally though, they would only be compile-time constraints (i.e. not carrying any other data). Not carrying any other data means not caching the lowercase version, which means recreating the lowercase version more than necessary. So it's the classic speed vs. space tradeoff. I would think there would be cases where they get compared enough for that to make a difference, although I suppose we'd really need benchmarks to see. OTOH, there are certainly cases (such as my original motivating case) where the extra space is not an issue at all. But that does raise a point worth exploring: Maybe it should support both caching and non-caching behavior? I can think of at least two different ways to do this: 1. Provide a useCache template parameter. Problem with that though, is that the caching and non-caching versions end up being two distinct types. 2. Make useCache a runtime property. Since the cached foldingCase var is entirely private, the useCache flag could probably be encoded as a specific value of foldingCase.length and/or foldingCase.ptr. So the overhead of the non-cached version would only be size_t*2 instead of size_t*2+str.length. One other idea: It's possible to change it so the folding case version is only created and cached when toHash is used. For other cases, it could just use icmp. So the storage space (beyond .length and .ptr) for the folding case version would never be allocated unless you're using it as an AA key (or some other use that needs hashing). Some benchmarking would be needed to be certain, but I think that would hit a nice sweet spot between space and speed, plus it wouldn't bother the user of the type with cache or no cache?. Perhaps it's possible to create such types? CaseSensitiveString, CaseInsensitiveString, and the standard string type being unspecified. I think the standard type can be assumed to be case-sensitive since that's how it already operates.
Re: Assuming structs are cheap to copy?
On 1/10/2011 9:08 AM, Justin Johansson wrote: On 10/01/11 03:06, Peter Alexander wrote: I remember there was a discussion a little while back about how Phobos would assume that structs are cheap to copy, and would simply pass them by value. Is this assumption now the D way? Should we all just pass structs by value, assuming cheap copy construction? If so, I think this needs to be documented somewhere (assuming it isn't already), because it's a radical departure from C++, and also from most other languages (where everything is a reference type). People need to be aware of this. What if the byte size of some struct is say a KB or a MB would one still think that copy construction is cheap? In this instance I would not blame poor performance on Phobos but rather than your own design. Cheers Justin I assume it varies by architecture, but at what size threshold is it faster to copy structs by reference instead of value? If I pass a large struct by value, will dmd optimize it away as a reference?
Re: std.unittests for (final?) review [Update]
Jonathan M Davis jmdavisp...@gmx.com wrote in message news:mailman.535.1294662576.4748.digitalmar...@puremagic.com... Okay, here's the new code and its documentation: http://is.gd/ktURa I followed Andrei's suggestion and merged most of the functions into a highly flexible assertPred. I also renamed the functions as suggested and attempted to fully document everything with fully functional examples instead of examples using types or functions which don't actually exist. So, now there's just assertThrown, assertNotThrown, collectExceptionMsg, and assertPred (though there are eight different overloads of assertPred). So, review away. From the sounds of it, if this code gets voted in, it'll be going into std.exception. I like it. (I still think a way to make them collect an array of exceptions instead of throwing should make it's way in there at some point though.) Couple small things though: - The error message from the conditional version of assertPred should probably omit the two words is not. That much is already clear from the fact that assertPred threw and says failed:, and getting rid of it makes it much more readable as an expression: failed: [hello] == [goodbye] or failed: [5] [2] - The docs should have a section that gives an overview of assertPred by using a few simple examples of each of the assertPred uses. The way it is now, it's hard to see the overall logic behind the design of the assertPred's params since it's spread out all over. For instance: - //Equivalent to assert(4 = 5); assertPred!=(4, 5); //Equivalent to assert(1 * 2 == 2); assertPred!==(1 * 2, 2); //Equivalent to assert(7 + 5 == 12); assertPred!+(7, 5, 12); /* Equivalent to void func(T, U)(T lhs, U rhs) { auto result = lhs = rhs; assert(lhs == rhs); assert(result == rhs); } func(5, 7); */ assertPred!opAssign(5, 7); /* Equivalent to void func(T, U, E)(T lhs, U rhs, E expected) { auto result = lhs += rhs; assert(lhs == expected); assert(result == expected); } func(5, 7, 12); */ assertPred!-=(7, 5, 2); assertPred!*=(7, 5, 35); //Equivalent to assert(hello ~ world == hello world); assertPred!~(hello , world, hello world); //Equivalent to assert(1 == 1); assertPred!a == 1(1); //Equivalent to assert(2 * 3.0 == 6); assertPred!a * 3.0 == 6.0(2); //Equivalent to assert(42 == 42); assertPred!a == b(42, 42); //Equivalent to assert(hello ~ world == hello world); assertPred!`a ~ b == hello world`(hello , world); //Equivalent to assert((int[] range, int i){return canFind(range, i);}([1, 5, 7, 2], 7)); assertPred!((int[] range, int i){return canFind(range, i);})([1, 5, 7, 2], 7); //Equivalent to assert((int a, int b, int c){return a == b b == c;}(5, 5, 5)); assertPred!((int a, int b, int c){return a == b b == c;})(5, 5, 5); struct IntWrapper { int value; int opCmp(const ref IntWrapper rhs) const { if(value rhs.value) return -1; else if(value rhs.value) return 1; return 0; } string toString() { return to!string(value); } } // Equivalent to assert(IntWrapper(0).opCmp(IntWrapper(6)) 0); assertPred!(opCmp, )(IntWrapper(0), IntWrapper(6)); // Equivalent to assert(IntWrapper(42).opCmp(IntWrapper(42)) == 0); assertPred!(opCmp, ==)(IntWrapper(42), IntWrapper(42)); - Also notice that I cleaned up a few things, like eliminating the unnecessary struct constructor and making a few of the assert equivalents more clear.
Re: RFC: Case-Insensitive Strings (And usually they really do *have*case)
On Monday, January 10, 2011 10:46:55 Nick Sabalausky wrote: Jim bitcir...@yahoo.com wrote in message news:igfado$11g...@digitalmars.com... While writing and dealing with all that code I realized something: While programmers are usually heavily conditioned to think of case-sensitivity as an attribute of the comparison, it's very frequent that the deciding factor in which comparison to use is *not* the comparison itself but *what* gets compared. And in those cases, you have to use the awful strategy of relying on convention to make sure you get it right in *every* place that particular data gets compared. You have a point. Your case-sensitivity-aware string types will guarantee correctness in a large and complex program. I like that. Ideally though, they would only be compile-time constraints (i.e. not carrying any other data). Not carrying any other data means not caching the lowercase version, which means recreating the lowercase version more than necessary. So it's the classic speed vs. space tradeoff. I would think there would be cases where they get compared enough for that to make a difference, although I suppose we'd really need benchmarks to see. OTOH, there are certainly cases (such as my original motivating case) where the extra space is not an issue at all. Why is caching necessary? Shouldn't you just be able to use std.string.icmp() for comparisons internally, avoiding any copying or caching? That shouldn't need to duplicate anything. Or do you need to cache the lower-case version for something other than comparison? - Jonathan M Davis
Re: RFC: Case-Insensitive Strings (And usually they really do*have*case)
Jonathan M Davis jmdavisp...@gmx.com wrote in message news:mailman.538.1294690510.4748.digitalmar...@puremagic.com... On Monday, January 10, 2011 10:46:55 Nick Sabalausky wrote: Jim bitcir...@yahoo.com wrote in message news:igfado$11g...@digitalmars.com... While writing and dealing with all that code I realized something: While programmers are usually heavily conditioned to think of case-sensitivity as an attribute of the comparison, it's very frequent that the deciding factor in which comparison to use is *not* the comparison itself but *what* gets compared. And in those cases, you have to use the awful strategy of relying on convention to make sure you get it right in *every* place that particular data gets compared. You have a point. Your case-sensitivity-aware string types will guarantee correctness in a large and complex program. I like that. Ideally though, they would only be compile-time constraints (i.e. not carrying any other data). Not carrying any other data means not caching the lowercase version, which means recreating the lowercase version more than necessary. So it's the classic speed vs. space tradeoff. I would think there would be cases where they get compared enough for that to make a difference, although I suppose we'd really need benchmarks to see. OTOH, there are certainly cases (such as my original motivating case) where the extra space is not an issue at all. Why is caching necessary? Shouldn't you just be able to use std.string.icmp() for comparisons internally, avoiding any copying or caching? That shouldn't need to duplicate anything. Or do you need to cache the lower-case version for something other than comparison? Anything involving toHash (such as using Insensitive as an AA key) requires the use of a lower-case version. For anything else, you're probably right, icmp should be fine (Although I'd like to do a benchmark of icmp vs regular string comparison).
Re: RFC: Case-Insensitive Strings (And usually they really do*have*case)
Nick Sabalausky a...@a.a wrote in message news:igfq0n$22u...@digitalmars.com... Jonathan M Davis jmdavisp...@gmx.com wrote in message news:mailman.538.1294690510.4748.digitalmar...@puremagic.com... On Monday, January 10, 2011 10:46:55 Nick Sabalausky wrote: Jim bitcir...@yahoo.com wrote in message news:igfado$11g...@digitalmars.com... While writing and dealing with all that code I realized something: While programmers are usually heavily conditioned to think of case-sensitivity as an attribute of the comparison, it's very frequent that the deciding factor in which comparison to use is *not* the comparison itself but *what* gets compared. And in those cases, you have to use the awful strategy of relying on convention to make sure you get it right in *every* place that particular data gets compared. You have a point. Your case-sensitivity-aware string types will guarantee correctness in a large and complex program. I like that. Ideally though, they would only be compile-time constraints (i.e. not carrying any other data). Not carrying any other data means not caching the lowercase version, which means recreating the lowercase version more than necessary. So it's the classic speed vs. space tradeoff. I would think there would be cases where they get compared enough for that to make a difference, although I suppose we'd really need benchmarks to see. OTOH, there are certainly cases (such as my original motivating case) where the extra space is not an issue at all. Why is caching necessary? Shouldn't you just be able to use std.string.icmp() for comparisons internally, avoiding any copying or caching? That shouldn't need to duplicate anything. Or do you need to cache the lower-case version for something other than comparison? Anything involving toHash (such as using Insensitive as an AA key) requires the use of a lower-case version. For anything else, you're probably right, icmp should be fine (Although I'd like to do a benchmark of icmp vs regular string comparison). The other (smaller) thing I'm concerned about, and the reason I keep mentioning I want to do a benchmark, is that case-sensitive comparisons are able to use the max-speed memcmp whereas icmp has to not only avoid memcmp but also stick extra logic in the middle of the loop (and currently that also includes calls to utf.decode). Without checking, I'm not sure if that wouldn't make multiple calls to icmp slower than just making a lower-case version once and using case-sensitive comparisons on them.
Re: RFC: Case-Insensitive Strings (And usually they really do *have*case)
On 2011-01-10 13:46:55 -0500, Nick Sabalausky a...@a.a said: Not carrying any other data means not caching the lowercase version, which means recreating the lowercase version more than necessary. So it's the classic speed vs. space tradeoff. I would think there would be cases where they get compared enough for that to make a difference, although I suppose we'd really need benchmarks to see. OTOH, there are certainly cases (such as my original motivating case) where the extra space is not an issue at all. Comparing the lowercase version of two strings works well for ASCII, but I doubt it works very well for Unicode. Case conversion is not bidirectional (for instance both 'SS' and 'ß' become 'ss' in lowercase in German), and what's equal and what is not sometime depends on the language. Checking for string equality is a special case of the Unicode collation algorithm. I'm not sure if implementing this part of Unicode is in the scope of Phobos (probably not), but short of having Unicode support it seems the utility of having a special string type dedicated to ASCII case-insensitive strings is quite limited. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: RFC: Case-Insensitive Strings (And usually they really do *have*case)
Michel Fortin michel.for...@michelf.com wrote in message news:igft2o$291...@digitalmars.com... On 2011-01-10 13:46:55 -0500, Nick Sabalausky a...@a.a said: Not carrying any other data means not caching the lowercase version, which means recreating the lowercase version more than necessary. So it's the classic speed vs. space tradeoff. I would think there would be cases where they get compared enough for that to make a difference, although I suppose we'd really need benchmarks to see. OTOH, there are certainly cases (such as my original motivating case) where the extra space is not an issue at all. Comparing the lowercase version of two strings works well for ASCII, but I doubt it works very well for Unicode. Case conversion is not bidirectional (for instance both 'SS' and 'ß' become 'ss' in lowercase in German), and what's equal and what is not sometime depends on the language. Checking for string equality is a special case of the Unicode collation algorithm. I'm not sure if implementing this part of Unicode is in the scope of Phobos (probably not), but short of having Unicode support it seems the utility of having a special string type dedicated to ASCII case-insensitive strings is quite limited. Yea, Phobos doesn't even have folding-case functions yet (which is why I keep saying lowercase). (This is actually one place where Phobos is still behind Tango.) However, I really think that's orthogonal to this since std.string.icmp doesn't handle such non-english issues either (just the english a-z, A-Z, and that's it). When Phobos does become multilingual, then this can be updated to follow suit. One question though: Aren't 'SS' and 'ß' considered the same in german anyway? If so, how does using lowercase instead of folding case cause a problem?
Re: RFC: Case-Insensitive Strings (And usually they really do *have*case)
Am 10.01.2011 22:24, schrieb Nick Sabalausky: One question though: Aren't 'SS' and 'ß' considered the same in german anyway? If so, how does using lowercase instead of folding case cause a problem? It's not the same, see http://en.wikipedia.org/wiki/%C3%9F#Current_usage_in_German
Re: std.unittests for (final?) review [Update]
Jonathan M Davis napisał: I followed Andrei's suggestion and merged most of the functions into a highly flexible assertPred. I also renamed the functions as suggested and attempted to fully document everything with fully functional examples instead of examples using types or functions which don't actually exist. Did you zip the right file? I still see things like nameFunc and assertPlease. On the whole the examples are too long. It's just daunting I can't see docs for *one* function without scrolling. Please give them a solid hair-cut -- max 10 lines with a median of 5. The descriptions are also watered down by over-explanatory writing. So, now there's just assertThrown, assertNotThrown, collectExceptionMsg, and assertPred (though there are eight different overloads of assertPred). So, review away. Some suggestions: assertPred: Try putting expected in front; uniform call syntax can then set it apart from the operands: assertPred!%(7, 5, 2); // old 2.assertPred!%(7, 5); // new assertNotThrown: chain the original exception with AssertError as its cause? Oh, this one badly needs a real-life example. assertThrown: I'd rather see generified collectException (call it collectThrown?). assertThrown may stay as a convenience wrapper, though. Looking at the code I'm seeing the same cancerous coding style std.datetime suffered from (to a lesser extent, I admit). For instance, this routine: if(result != expected) { if(msg.empty) { throw new AssertError(format(`assertPred!%s failed: [%s] %s [%s]: actual [%s], expected [%s].`, op, lhs, op, rhs, result, expected), file, line); } else { throw new AssertError(format(`assertPred!%s failed: [%s] %s [%s]: actual [%s], expected [%s]: %s`, op, lhs, op, rhs, result, expected, msg), file, line); } } can be easily compressed to: enforce(result==expected, new AssertError( format([%s] %s [%s] failed: actual [%s], expected [%s] ~ (msg.empty ? . : : %s), op, lhs, op, rhs, result, expected, msg), file, line)); BTW, actual and expected should be in new lines directly under each other for eye-diffing (does wonders for long input): format([%s] %s [%s] failed:\n[%s] - actual\n[%s] - expected ~ ... Another example: { bool thrown = false; try assertNotThrown!AssertError(throwEx(new AssertError(It's an AssertError, __FILE__, __LINE__)), It's a message); catch(AssertError) thrown = true; assert(thrown); } can be: try { assertNotThrown!AssertError(throwEx(new AssertError(It's an AssertError, __FILE__, __LINE__)), It's a message); assert(false); } catch(AssertError) { /*OK*/ } and you don't have to introduce a new scope every time. Not to mention that such routines recur in your code with little discrepancies, so abstracting out private helpers may pay off. Fixing such readability bugs is essential for a standard library module. On the bright side, I do appreciate the thoroughness and extent of unittests in this module. Is coverage 100%? From the sounds of it, if this code gets voted in, it'll be going into std.exception. Please don't rush the adoption. This module, albeit useful, still needs work. -- Tomek
Re: RFC: Case-Insensitive Strings (And usually they really do *have*case)
Daniel Gibson metalcae...@gmail.com wrote in message news:igfttf$p4...@digitalmars.com... Am 10.01.2011 22:16, schrieb Michel Fortin: Comparing the lowercase version of two strings works well for ASCII, but I doubt it works very well for Unicode. Case conversion is not bidirectional (for instance both 'SS' and 'ß' become 'ss' in lowercase in German), That's wrong, 'ß' is lowercase and no upper-case version is used really, though one exists in Unicode (see: http://en.wikipedia.org/wiki/Capital_%C3%9F ). Sometimes, when stuff is written in fullcaps, 'ß' (which never is the first character of a word) is replaced by SS, but I wouldn't expect that to be equal on icmp(). (e.g. Strings vergleichen macht keinen Spaß! vs STRINGS VERGLEICHEN MACHT KEINEN SPASS!) Anyway, in this case comparing in lowercase would cause no trouble at all (comparing in uppercase however would, if you don't use the not-really-existing-but-defined-by-unicode-Capital-ß). I don't know if there may be problems with special characters in other languages, though. One of the unicode documents mentions an example involving the three greek sigma letters, although I never quite understood how it demonstrated the inadequacy of using lower-case: http://www.unicode.org/reports/tr21/tr21-5.html#Caseless_Matching ...Which references some information near the end of this sub-section: http://www.unicode.org/reports/tr21/tr21-5.html#Introduction Actually, what probably should be stored is a *normalized* folding-case version of the string, because then (if I understand correctly) memcmp could be used. I don't think memcpy technically works on non-ASCII (unless it's in normalized form). In any case, Phobos doesn't currently handle any of that stuff at all, so my case-insensitive string type wouldn't be taking things backwards in that regard.
Re: How to convert Map to array?
It's easier to help if you provide sample code that produces the message. I got that message today and fixed it, I just don't what was the problem. -- Atenciosamente / Sincerely, Guilherme (n2liquid) Vieira On Mon, Jan 10, 2011 at 1:25 AM, Sean Eskapp eatingstap...@gmail.comwrote: I'm trying to use the array() function in std.array to convert a transformed array using map (std.algorithm) back to a dynamic array, from a Map. I keep getting a cryptic error object.except...@c:\Program Files (x86)\D\dmd2\windows\bin\..\..\src\phobos\std\ algorithm.d(426): Cannot reduce an empty range w/o an explicit seed value.. Am I misunderstanding how this is supposed to work?
Re: RFC: Case-Insensitive Strings (And usually they really do *have*case)
Nick Sabalausky a...@a.a wrote in message news:igftls$2af...@digitalmars.com... since std.string.icmp doesn't handle such non-english issues either (just the english a-z, A-Z, and that's it). Figured this belongs in bugilla: http://d.puremagic.com/issues/show_bug.cgi?id=5443
Re: std.unittests for (final?) review [Update]
On Monday, January 10, 2011 13:48:50 Tomek Sowiński wrote: Jonathan M Davis napisał: I followed Andrei's suggestion and merged most of the functions into a highly flexible assertPred. I also renamed the functions as suggested and attempted to fully document everything with fully functional examples instead of examples using types or functions which don't actually exist. Did you zip the right file? I still see things like nameFunc and assertPlease. ??? Those are supposed to be there. All examples are tested in the unit tests exactly as they are. On the whole the examples are too long. It's just daunting I can't see docs for *one* function without scrolling. Please give them a solid hair-cut -- max 10 lines with a median of 5. The descriptions are also watered down by over-explanatory writing. Perhaps. If I cut down on the examples though, the usage wouldn't be as clear. The idea was to be thorough. Andrei wanted better examples, so I gave better examples. However, it is a bit of a balancing act, and I may have put too many in. It's debatable. Nick's suggestion of a main description before each individual overload would help with that. So, now there's just assertThrown, assertNotThrown, collectExceptionMsg, and assertPred (though there are eight different overloads of assertPred). So, review away. Some suggestions: assertPred: Try putting expected in front; uniform call syntax can then set it apart from the operands: assertPred!%(7, 5, 2); // old 2.assertPred!%(7, 5); // new I really don't see any value to this. 1. You can't do that with assert, and assertPred is essentially supposed to be a fancy assert. 2. A number of assertPred overloads don't even have an expected, so it would be inconsistent. 3. People already are annoyed enough that the operator doesn't end up between the arguments. Putting the result on the left-hand side of the operator like that would make it that much more confusing. assertNotThrown: chain the original exception with AssertError as its cause? Oh, this one badly needs a real-life example. I suppose that chaining it would be a good idea. I didn't think of that. But if you want examples, it's used in the unit tests in this very module, and I used it heavily in std.datetime. assertThrown: I'd rather see generified collectException (call it collectThrown?). assertThrown may stay as a convenience wrapper, though. ??? I don't get what you're trying for here. assertThrown isn't trying to collect exceptions at all. It's testing whether the given exception was thrown like it's supposed to be for the given function call. If it was, then the assertion succeeded. If it wasn't, then an AssertError is thrown. Just like assert. Looking at the code I'm seeing the same cancerous coding style std.datetime suffered from (to a lesser extent, I admit). For instance, this routine: if(result != expected) { if(msg.empty) { throw new AssertError(format(`assertPred!%s failed: [%s] %s [%s]: actual [%s], expected [%s].`, op, lhs, op, rhs, result, expected), file, line); } else { throw new AssertError(format(`assertPred!%s failed: [%s] %s [%s]: actual [%s], expected [%s]: %s`, op, lhs, op, rhs, result, expected, msg), file, line); } } can be easily compressed to: enforce(result==expected, new AssertError( format([%s] %s [%s] failed: actual [%s], expected [%s] ~ (msg.empty ? . : : %s), op, lhs, op, rhs, result, expected, msg), file, line)); I really have no problem with them being separate as they are. I think that I end up writing them that way because I see them as two separate code paths. It wouldn't necessarily be a bad idea to combine them, but I really don't think that it's a big deal. BTW, actual and expected should be in new lines directly under each other for eye-diffing (does wonders for long input): format([%s] %s [%s] failed:\n[%s] - actual\n[%s] - expected ~ ... Good idea. Another example: { bool thrown = false; try assertNotThrown!AssertError(throwEx(new AssertError(It's an AssertError, __FILE__, __LINE__)), It's a message); catch(AssertError) thrown = true; assert(thrown); } can be: try { assertNotThrown!AssertError(throwEx(new
Re: How to convert Map to array?
Sean Eskapp eatingstap...@gmail.com wrote in message news:igdu78$18k...@digitalmars.com... I'm trying to use the array() function in std.array to convert a transformed array using map (std.algorithm) back to a dynamic array, from a Map. I keep getting a cryptic error object.except...@c:\Program Files (x86)\D\dmd2\windows\bin\..\..\src\phobos\std\ algorithm.d(426): Cannot reduce an empty range w/o an explicit seed value.. Am I misunderstanding how this is supposed to work? You're calling reduce on an empty range. reduce!a*b([1, 2, 3]); // fine, translates to 1 * 2 * 3 reduce!a*b([7]); // also fine, translates to 7 reduce!a*b([]); // what should this be? Luckily you can call reduce with an extra argument giving the seed value: reduce!a*b(1, []); // Calculates product for both empty and non-empty ranges.
About std.container.RedBlackTree
I've had to use a search tree, so RedBlackTree was the right data structure. It seems to do what I need, so thank you for this useful data structure. Some of the things I write here are questions or things that show my ignorance about this implementation. - Please add some usage examples to this page, this is important and helps people reduce a lot the number of experiments to do to use this tree: http://www.digitalmars.com/d/2.0/phobos/std_container.html# - This doesn't seem to work, it gives a forward reference error: import std.container: RedBlackTree; RedBlackTree!int t; void main() { t = RedBlackTree!int(1); } This gives a similar error: import std.container: RedBlackTree; struct Foo { RedBlackTree!int t; void initialize() { t = RedBlackTree!int(1); } } void main() {} - I need to create an empty tree and add items to it later (where I declare a fixed-sized array of trees I don't know the items to add). How do you do it? This code doesn't work: import std.container: RedBlackTree; void main() { auto t = RedBlackTree!int(); t.insert(1); } - Is the tree insert() method documented in the HTML docs? - A tree is a kind of set, so instead of insert() I'd like a name like add(). (But maybe this is not standard in D). - In theory an helper redBlackTree() function allows to write just this, with no need to write types: redBlackTree(1, 2, 3) - I have tried to use printTree(), but I have failed. I don't know what to give to it and the docs don't say that it requires -unittest If it's a private debug function then there's no need to give it a ddoc comment. - I've seen that the tree doesn't seem to contain a length. Using walkLength is an option, but a possible idea is to replace: struct RedBlackTree(T,alias less = a b,bool allowDuplicates = false) With: struct RedBlackTree(T, alias less=a b, bool allowDuplicates=false, bool withLength=false) - If you need to add many value nodes quickly to the tree a memory pool may speed up mass allocation. This has some disadvantages too. - If I have to create a set of epsilon-approximate floating point numbers, what's the most efficient way to use a RedBlackTree to see if it contains a value x (or values very close to x), and othrwise add x to the tree? I was thinking about something like this, but it doesn't look very good because it performs three lookups (this function returns the number of items added): int approxInsert(RedBlackTree!double set, double x, double epsilon) { if (x in set) { return 0; } else { auto nextOnes = set.upperBound(x); if (!nextOnes.empty() (nextOnes.front - x) epsilon) { return 0; } auto precedentOnes = set.lowerBound(x); if (!precedentOnes.empty() (x - precedentOnes.back) epsilon) { return 0; } else { set.insert(x); return 1; } } } - This code runs with no errors, is this correct? The two Foos have the same x but different y: import std.container: RedBlackTree; struct Foo { int x, y; } void main() { auto t = RedBlackTree!(Foo, a.x b.x)(Foo(1,1)); assert(Foo(1,2) in t); } (In practice this looks like a tree map instead of a tree set.) If this is correct then I suggest to add this example to the std_container.html page. - Bye and thank you, bearophile
Re: std.unittests for (final?) review [Update]
On Monday, January 10, 2011 14:41:51 Jonathan M Davis wrote: On Monday, January 10, 2011 13:48:50 Tomek Sowiński wrote: Another example: { bool thrown = false; try assertNotThrown!AssertError(throwEx(new AssertError(It's an AssertError, __FILE__, __LINE__)), It's a message); catch(AssertError) thrown = true; assert(thrown); } can be: try { assertNotThrown!AssertError(throwEx(new AssertError(It's an AssertError, __FILE__, __LINE__)), It's a message); assert(false); } catch(AssertError) { /*OK*/ } and you don't have to introduce a new scope every time. Doesn't work actually - at least not in the general case (for this particular test, it's arguably okay). It doesn't take into account the case where an exception other than AssertError is thrown. The exception escapes instead of hitting the assertion. I believe that they are the way they are because I was essentialy re-writing assertThrown to test assertThrown. Regardless, we're talking about the unit tests here, not the actual code, so I don't think that it's as big a deal. Actually, I now remember the big reason that your version doesn't work at all. The AssertError thrown by assert(false); inside of the try block would just be caught by the catch block. So, it doesn't work at all. You have to do it pretty much the way that I did it. It was one of those nuances in writing assertNotThrown that initially missed when coming up with it in the first place. So, the ugly way is necessary. - Jonathan M Davis
Re: eliminate junk from std.string?
On 1/10/11 2:41 AM, bearophile wrote: Lars T. Kyllingstad: My suggestions for things to remove: hexdigits, digits, octdigits, lowercase, letters, uppecase, whitespace - What are these arrays useful for? capwords() - It tries to do too much. zfill() - The ljustify(),rjustify(), and center() functions should instead take an optional padding character that defaults to a space. maketrans(), translate() - I don't even understand what these do. inPattern(), countchars(), removechars() - Pattern matching is std.regex's charter. squeeze(), succ(), tr(), soundex(), column() - I am having a very hard time imagining myself ever using these functions... I agree with about nothing you have said :-) How much string processing you do day by day? I am using most of those things... If you are used in using Python or Ruby you probably find most of those things useful. If Andrei removes arrays like lowercase, letters, uppecase, I will have to write them myself in code. The arrays letters, uppercase, and lowercase aren't all that useful because they only make sense for ASCII. Besides, they should be encoded as functions. ljustify(),rjustify(), and center() are very useful, even if they may be improved in some ways. Hmmm. I suspected everyone's list will be different :o). I personally think the justification and centering functions are rarely useful - how often does one need to justify plain text? If you generate HTML the markup will do that for you and if you generate some nice text then the font will be proportional so the functions are useless. Nevertheless, I ported them (and also fixed them - they were broken for anything non-ASCII, which probably is telling of the extent of their usage). What are your use cases for these three functions? maketrans() and translate() (as other things) come from Python string functions, and I have used them a hundred times in string processing code. I have used squeeze() some times. soundex is not hurting, because even if it's not commonly necessary, its name is easy to understand and it's not easy to miss for something different, so it doesn't add much noise to the library. And I've seen that it's easy to implement soundex wrongly, while the one in the std.string is correct. I think maketrans/translate are okay (if a bit arcane) but they need to be ported to Unicode. Python apparently does mind Unicode as of 3.x, although I'm not sure exactly what the semantics are: http://stackoverflow.com/questions/3031045/how-come-string-maketrans-does-not-work-in-python-3-1. One odd thing is that you'd expect a dynamic language like Python to dynamically detect ASCII vs. non-ASCII. The example shows that Python rejects string-based translation tables even when they are, in fact, ASCII. I agree that too much stuff is generally bad in a library, because searching for something requires more time if there are more items to search into. In Bugzilla I have three or four bug reports that ask for few small changes in std.string (like removing chop and keeping chomp). But please don't remove too much. In a library more is often better. I think we should remove all functions that rely on patterns represented as strings: inPattern, countchars, removechars, squeeze, munch. Representing patterns as a convention on top of otherwise untyped strings doesn't seem a good solution for D. We should either go with regex or with a simple pattern structure and a helper function. That way people can say e.g. munch(s, pattern([0-9])). Andrei
Re: eliminate junk from std.string?
What are your use cases for these three functions? I don't know about bearophile, but I used a lot of the functions you are talking about removing in my HTML - Plain Text conversion function used for emails and other similar environments. squeeze the whitespace, align text, wrap for the target, etc.
Re: eliminate junk from std.string?
Speaking of regex.. I see there are two enums in std.regex, email and url, which are regular expressions. Why not collect more of these common regexes? And we could pack them up in a struct to avoid polluting the local namespace. I think this might encourage the use of std.regex, since the average Joe wouldn't have to reach for the regex book whenever he's processing strings. E.g.: foreach(m; match(10abc20def30, regex(patterns.number))) // std.regex.patterns.number { writefln(%s[%s]%s, m.pre, m.hit, m.post); } Just a passing thought..
Re: RFC: Case-Insensitive Strings (And usually they really do *have*case)
On 2011-01-10 16:30:50 -0500, Daniel Gibson metalcae...@gmail.com said: Am 10.01.2011 22:16, schrieb Michel Fortin: Comparing the lowercase version of two strings works well for ASCII, but I doubt it works very well for Unicode. Case conversion is not bidirectional (for instance both 'SS' and 'ß' become 'ss' in lowercase in German), That's wrong, 'ß' is lowercase and no upper-case version is used really, though one exists in Unicode (see: http://en.wikipedia.org/wiki/Capital_%C3%9F ). Oops, you're right. I got it backward. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: DVCS (was Re: Moving to D)
Sun, 09 Jan 2011 06:00:21 -0600, Christopher Nicholson-Sauls wrote: On 01/08/11 20:18, Walter Bright wrote: Vladimir Panteleev wrote: On Sun, 09 Jan 2011 00:34:19 +0200, Walter Bright newshou...@digitalmars.com wrote: Yeah, I could spend an afternoon doing that. sudo apt-get build-dep meld wget http://ftp.gnome.org/pub/gnome/sources/meld/1.5/meld-1.5.0.tar.bz2 tar jxf meld-1.5.0.tar.bz2 cd meld-1.5.0 make sudo make install You're welcome ;) Thanks, I'll give it a try! I say you should consider moving away from *Ubuntu and to something more developer-friendly such as Gentoo, where the command to install meld is just: emerge meld ...done. And yes, that's an install from source. I just did it myself, and it took right at one minute. Gentoo really needs a high-end computer to run fast. FWIW, the same meld takes 7 seconds to install on my ubuntu. That includes fetching the package from the internet (1-2 seconds). Probably even faster on Arch.
Re: RFC: Case-Insensitive Strings (And usually they really do *have*case)
On 2011-01-10 17:00:40 -0500, Nick Sabalausky a...@a.a said: Actually, what probably should be stored is a *normalized* folding-case version of the string, because then (if I understand correctly) memcmp could be used. I don't think memcpy technically works on non-ASCII (unless it's in normalized form). Actually, what would be compatible with Unicode collation is probably an array of collation elements. This would also make it useful to sort case-insensitively, not just testing for equality. Details (perhaps too much details): http://unicode.org/reports/tr10/ In any case, Phobos doesn't currently handle any of that stuff at all, so my case-insensitive string type wouldn't be taking things backwards in that regard. Probably not. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: eliminate junk from std.string?
Andrej Mitrovic andrej.mitrov...@gmail.com wrote in message news:mailman.543.1294713068.4748.digitalmar...@puremagic.com... Speaking of regex.. I see there are two enums in std.regex, email and url, which are regular expressions. Why not collect more of these common regexes? And we could pack them up in a struct to avoid polluting the local namespace. I think this might encourage the use of std.regex, since the average Joe wouldn't have to reach for the regex book whenever he's processing strings. E.g.: foreach(m; match(10abc20def30, regex(patterns.number))) // std.regex.patterns.number { writefln(%s[%s]%s, m.pre, m.hit, m.post); } Just a passing thought.. I think that's a great idea.
Re: eliminate junk from std.string?
On 1/9/11 4:51 PM, Andrei Alexandrescu wrote: There's a lot of junk in std.string that should be gone. I'm trying to motivate myself to port some functions to different string widths and... it's not worth it. What functions do you think we should remove from std.string? Let's make a string and then send them the way of the dino. Thanks, Andrei I have uploaded a preview of the changed APIs here: http://d-programming-language.org/cutting-edge/phobos/std_string.html Let's work together on improving things. Andrei
Re: DVCS (was Re: Moving to D)
Sat, 08 Jan 2011 14:34:19 -0800, Walter Bright wrote: Michel Fortin wrote: I know you had your reasons, but perhaps it's time for you upgrade to a more recent version of Ubuntu? That version is what comes with Hardy Heron (april 2008). https://launchpad.net/ubuntu/+source/meld I know. The last time I upgraded Ubuntu in place it fd up my system so bad I had to wipe the disk and start all over. It still won't play videos correctly (the previous Ubuntu worked fine), the rhythmbox music player never worked again, it wiped out all my virtual boxes, I had to spend hours googling around trying to figure out how to reconfigure the display driver so the monitor worked again, etc. I learned my lesson! Yes, I'll eventually upgrade, but I'm not looking forward to it. Ubuntu has a menu entry for restricted drivers. It provides support for both ATI/AMD (Radeon 8500 or better, appeared in 1998 or 1999!) and NVIDIA cards (Geforce 256 or better, appeared in 1999!) and I think it automatically suggests (a pop-up window) correct drivers in the latest releases right after the first install. Intel chips are automatically supported by the open source drivers. VIA and S3 may or may not work out of the box. I'm just a bit curious to know what GPU you have? If it's some ancient VLB (vesa local bus) or ISA card, I can donate $15 for buying one that uses AGP or PCI Express. Ubuntu doesn't support all video formats out of the box, but the media players and browsers automatically suggest loading missing drivers. At least in the 3 or 4 latest releases. Maybe the problem isn't the encoder, it might be the Linux incompatible web site. Or you could download the latest version from meld's website and compile it yourself. Yeah, I could spend an afternoon doing that. Another one of these jokes? Probably one of the best compiler authors in the whole world uses a whole afternoon doing something (compiling a program) that total Linux noobs do in less than 30 minutes with the help of Google search.
Re: RFC: Case-Insensitive Strings (And usually they really do *have*case)
Michel Fortin michel.for...@michelf.com wrote in message news:iggi34$cq...@digitalmars.com... On 2011-01-10 17:00:40 -0500, Nick Sabalausky a...@a.a said: Actually, what probably should be stored is a *normalized* folding-case version of the string, because then (if I understand correctly) memcmp could be used. I don't think memcpy technically works on non-ASCII (unless it's in normalized form). Actually, what would be compatible with Unicode collation is probably an array of collation elements. This would also make it useful to sort case-insensitively, not just testing for equality. Details (perhaps too much details): http://unicode.org/reports/tr10/ I'll have to take a look. (I don't even know what Unicode collation is :P ) In any case, Phobos doesn't currently handle any of that stuff at all, so my case-insensitive string type wouldn't be taking things backwards in that regard. Probably not. Actually I was (mostly) wrong: There's already unicode-compatible upper/lower case characters functions in std.uni, and these are used by std.string.toupper and std.string.tolower (as well as their InPlace coutnerparts). Which incidentally means that my Insentitive type worked correctly for unicode all along (I didn't know about icmp when I wrote it) - well, except for things that need folding case instead of lower-case. Not only that, but Andrei just committed a unicode fix for icmp (bugzilla 5443) just a few hours ago. (That's gotta be a record for fastest issue fixed in D's bug tracker!) Still no folding-case though.
Re: DVCS (was Re: Moving to D)
Sat, 08 Jan 2011 12:36:39 -0800, Walter Bright wrote: Lutger Blijdestijn wrote: Walter Bright wrote: Looks like meld itself used git as it's repository. I'd be surprised if it doesn't work with git. :-) I use git for other projects, and meld doesn't work with it. What version are you on? I'm using 1.3.2 and its supports git and mercurial (also committing from inside meld stuff, I take it this is what you mean with supporting a vcs). The one that comes with: sudo apt-get meld 1.1.5.1 One thing came to my mind. Unless you're using Ubuntu 8.04 LTS, your Ubuntu version isn't supported anymore. They might have already removed the package repositories for unsupported versions and that might indeed lead to problems with graphics and video players as you said. The support for desktop 8.04 and 9.10 is also nearing its end (April this year). I'd recommend backing up your /home and installing 10.04 LTS or 10.10 instead.
VLERange: a range in between BidirectionalRange and RandomAccessRange
I've been thinking on how to better deal with Unicode strings. Currently strings are formally bidirectional ranges with a surreptitious random access interface. The random access interface accesses the support of the string, which is understood to hold data in a variable-encoded format. For as long as the programmer understands this relationship, code for string manipulation can be written with relative ease. However, there is still room for writing wrong code that looks legit. Sometimes the best way to tackle a hairy reality is to invite it to the negotiation table and offer it promotion to first-class abstraction status. Along that vein I was thinking of defining a new range: VLERange, i.e. Variable Length Encoding Range. Such a range would have the power somewhere in between bidirectional and random access. The primitives offered would include empty, access to front and back, popFront and popBack (just like BidirectionalRange), and in addition properties typical of random access ranges: indexing, slicing, and length. Note that the result of the indexing operator is not the same as the element type of the range, as it only represents the unit of encoding. In addition to these (and connecting the two), a VLERange would offer two additional primitives: 1. size_t stepSize(size_t offset) gives the length of the step needed to skip to the next element. 2. size_t backstepSize(size_t offset) gives the size of the _backward_ step that goes to the previous element. In both cases, offset is assumed to be at the beginning of a logical element of the range. I suspect that a lot of functions in std.string can be written without Unicode-specific knowledge just by relying on such an interface. Moreover, algorithms can be generalized to other structures that use variable-length encoding, such as those used in data compression. (In that case, the support would be a bit array and the encoded type would be ubyte.) Writing to such ranges is not addressed by this design. Ideas are welcome. Adding VLERange would legitimize strings and would clarify their handling, at the cost of adding one additional concept that needs to be minded. Is the trade-off worthwhile? Andrei
filling an array of structures
Given an array of structures that you need to populate. Also assume the structure is quite large and has many elements to fill in. S s[]; while (something) { s.length += 1; auto sp = s[$-1]; // method 1 sp.a = 1; ... with (s[$-1]) { // method 2 a = 1; } ... foreach (ref sp; s[$-1..$]) { // method 3 sp.a = 1; } } I don't mind 'with' statements, but they have a readability and maintenance problem if their scope is large. The reader would have to be aware of the context of the structure and the local variables, whereas 'sp.a' is self documenting. method 3 is fine, and provides me with a reference to s[$-1], but I'd really like to have: auto sp = ref s[$-1]; // possible method 4 where sp is a reference, but no pointer arithmetic can be done on it. Another alternative would be runtime aliases. alias s[$-1] as sp; Or sp = with (s[$-1]); // I don't much like this syntax... In the meantime, I'll go with method 1. -- Brad
Re: Memory mapped IO
On Sun, 09 Jan 2011 22:44:44 -0800, Dan Olson wrote: I'm exploring D for embedded work as a nice alternative to C/C++ for the 32-bitters and am finding it has a nice set of features. But, what is the best way handle memory mapped IO? I don't see volatile like in C. Is writing asm {} the best way to ensure memory access? Thanks, Dan Olson Would std.mmfile be what you need? http://www.digitalmars.com/d/2.0/phobos/std_mmfile.html -Lars
Re: auto declarations
On Fri, 07 Jan 2011 16:30:24 -0800, Jonathan M Davis wrote: On Friday, January 07, 2011 13:32:42 Ellery Newcomer wrote: auto a = 1, b = null; int a = 1, *b = null; [...] [...] However, I'm vere suprised that the first one succeeds. I think that it should be reported as a bug. All variables declared on the same line are supposed to have the same type. If I remember correctly, TDPL explicitly states that you may use automatic type inference to declare variables of different types in one line. -Lars
Re: auto declarations
On Monday 10 January 2011 01:59:34 Lars T. Kyllingstad wrote: On Fri, 07 Jan 2011 16:30:24 -0800, Jonathan M Davis wrote: On Friday, January 07, 2011 13:32:42 Ellery Newcomer wrote: auto a = 1, b = null; int a = 1, *b = null; [...] [...] However, I'm vere suprised that the first one succeeds. I think that it should be reported as a bug. All variables declared on the same line are supposed to have the same type. If I remember correctly, TDPL explicitly states that you may use automatic type inference to declare variables of different types in one line. Well, it may. I don't know. I don't really believe in declaring multiple variables on one line in normal circumstances anyway. However, it's definitely an inconsistency in the language, and I would be inclined to argue that it should be removed and TDPL errata-ed if it does mention this feature. I don't see any real benefit of allowing this. - Jonathan M Davis
Re: Implicit type conversion
V Sun, 09 Jan 2011 21:29:32 -0800, Jonathan M Davis wrote: On Saturday 08 January 2011 13:16:54 Michal Minich wrote: Use case: import std.variant; void foo (Variant v) {} void main () { Variant v = 3; // ok, this () called v = 3; // ok, opAssing called foo (v); // ok, struct copy, this(this) called foo (3); // error } I'm trying to understand what is needed to make this work from language design perspective. Is there already known/proposed solution to make this work? What comes to my mind as first - Variant constructor should be called on last line, the same way as on the first. But maybe to solve this, another operator is needed, opImplicitConvertFrom ... There are definitely folks who want opImplicitCast (I think that it's pretty much going to be necessary to get std.typecons.Rebindable to work entirely correctly), and there's at least a decent chance that it will get added, but in general, D avoids implicit casting in order to avoid issues where you call functions which you don't really want to call (see http://is.gd/ksVli ). Regardless, opImplicitCast wouldn't help you here anyway, because you need to cast from an int to a Variant rather than the other way around, and it's not like int is going to have opImplicitCast defined, even if it did exist. Generally, you just need to give the correct type, which in this case would presumably mean foo(Variant(3)). It might be a bid annoying, but it avoids problems where you end up calling a function overload that you didn't intend to. If you really don't want to do that, then I believe that you're going to have to create another function overload for Foo which takes an int and deals with the conversion to Variant for you. Second question. Why is needed to have both - strut constructor (this) and opAssing. In variant case, constructor just forwards to opAssing. From high level point of view, I don't see any reason both should behave differently... There could be a difference of efficiency depending on the type. It could be more efficient to do something differently in one. For instance, that's why we have both opAssign and opOpAssign. Technically, you could just not have opOpAssign and use the combination of opAssign and opBinary to do it, but then you're likely to end up with extra heap allocations and the like. It could be the same with a constructor and opAssign, depending on the type. For the most part, D has tried to reduce how many operators you have to declare when they're related (such us using opCmp() to give you , =, =, and ), but it does create extra ones in cases where there's a good chance that it's more efficient to have separate definitions (such as using opEquals() for == and != rather than using opCmp() for that). - Jonathan M Davis Your suggestion to create function overload and bearophile’s bug report http://d.puremagic.com/issues/show_bug.cgi?id=5368 to remove variadic functions for class objects has given me an idea: Currently this functionality works only with non-teplated class constructors. If it were extended to support template and strut constructors, then it would make possible to construct objects/struct from function arguments, and the interaction with overloading should be more clear because of required variadic annotation on function parameter. In example: struct S { this (T…) (T val) {……} } void foo (S s…) { } //- the dots here expand the constructor parameters vod main () { foo (3); // is the same as: foo (S(3)); } But this is patchy solution. Proper way would be to make new operator function opArgConstruct, which would serve as constructor when struct is in place of function parameter. This way struct author can control availability of this idom. This function should normally just forward the call to constructor. This functionality is need usually for atomic (one valued) type wrappers like Variant, RefCounted, Rebindable... If this kind of struct constructor is constrained only to accept one argument, it would make overloading matter less, and ‘this’ can be used for construction.
Templated delegate
I would like to have a template which returns appropriate delegate, something like this: module mod1; import std.algorithm; import std.array; import std.stdio; template DG(RT, T, F) { auto DG(F fun) { RT delegate(T p)dg; dg = fun; return dg; } } void main() { string[] haystack = [item 1, item 2, item 3]; string needle = item 2; auto flt = (string s){return s == needle;}; auto dg = DG!(bool, string, typeof(flt))(flt); auto result = filter!(dg)(haystack); writeln(result); } The thing is I don't know what am I doing wrong here, because sometimes works and sometimes doesn't. For instance, if I'd added another file along with mod1.d, let's say, mod2.d which contained: module mod2; import std.conv; import std.string; import std.random; and compiled it like this: dmd mod2.d mod1.d, the program would produce segmentation fault. It works fine when packages in mod2 are omitted. What would be the correct way for templated delegate?
Re: Templated delegate
On 10/01/2011 13:02, Mitja wrote: I would like to have a template which returns appropriate delegate, something like this: For what purpose? All you seem to have is a long-winded identity function. snip and compiled it like this: dmd mod2.d mod1.d, the program would produce segmentation fault. I can't reproduce (DMD 2.051, Windows). In what setup are you experiencing the problem? It works fine when packages in mod2 are omitted. When which packages in mod2 are omitted? I can only make out that this is a compiler bug that needs to be investigated. What would be the correct way for templated delegate? It depends on what you're trying to do. Stewart.
Re: Templated delegate
Mitja odtih...@gmail.com wrote: I would like to have a template which returns appropriate delegate, something like this: So like this? module mod1; import std.algorithm; import std.functional; import std.stdio; void main( ) { auto haystack = [a,b,c]; auto needle = b; auto flt = (string s){return s == needle;}; auto dg = toDelegate( flt ); auto result = filter!dg(haystack); writeln(result); } I would have to argue that the delegate is hardly templated, though. Not sure what that means. What would be the correct way for templated delegate? Depending on what you mean by 'templated delegate', I would say std.functional's toDelegate, as used above. Perhaps if you explained what you mean by 'templated delegate', I could give a better answer. -- Simen
Re: What's wrong with this code?
On Sat, 08 Jan 2011 15:46:01 -0500, Michal Minich michal.min...@gmail.com wrote: On Sat, 08 Jan 2011 20:34:39 +, Sean Eskapp wrote: if(left == null) 1) write if (left is null) instead if checking for null. Equality operator is rewritten to a.opEquals(b), which you don't want if you checking for null. Actually, this is no longer true. For comparing two classes or interfaces, a == b becomes .opEquals(a, b) which is defined in object.di and properly handles null references. However, if checking for null, a is null is going to be more correct and as efficient as possible (a == b should be inlined to the same thing, but only if you have inlining enabled). -Steve
Re: Memory mapped IO
Lars T. Kyllingstad pub...@kyllingen.nospamnet writes: On Sun, 09 Jan 2011 22:44:44 -0800, Dan Olson wrote: I'm exploring D for embedded work as a nice alternative to C/C++ for the 32-bitters and am finding it has a nice set of features. But, what is the best way handle memory mapped IO? I don't see volatile like in C. Is writing asm {} the best way to ensure memory access? Thanks, Dan Olson Would std.mmfile be what you need? http://www.digitalmars.com/d/2.0/phobos/std_mmfile.html -Lars Ok, thanks. So I see that is a wrapper for mmap. So that would be good for user space code running on top of posix or win32. But... I'm more interested in the general embedded case with a small OS or no OS (just ISRs and main loop). I'm betting without volatile, asm {} is the next best thing for tickling a controllers peripheral registers? Yes/No? I searched the news groups and saw there used to be a volatile. But it looks like it was done away with because of how it was misused (like C volatile) for thread sharing. But this is different. This is just telling the compiler not to optimize away an access. -- Dan Olson
Re: Memory mapped IO
On Mon, 10 Jan 2011 08:38:15 -0800, Dan Olson wrote: Lars T. Kyllingstad pub...@kyllingen.nospamnet writes: On Sun, 09 Jan 2011 22:44:44 -0800, Dan Olson wrote: I'm exploring D for embedded work as a nice alternative to C/C++ for the 32-bitters and am finding it has a nice set of features. But, what is the best way handle memory mapped IO? I don't see volatile like in C. Is writing asm {} the best way to ensure memory access? Thanks, Dan Olson Would std.mmfile be what you need? http://www.digitalmars.com/d/2.0/phobos/std_mmfile.html -Lars Ok, thanks. So I see that is a wrapper for mmap. So that would be good for user space code running on top of posix or win32. But... Ah, I should have read your post more closely. I just saw memory mapped IO and latched onto that. :) I'm more interested in the general embedded case with a small OS or no OS (just ISRs and main loop). I'm betting without volatile, asm {} is the next best thing for tickling a controllers peripheral registers? Yes/No? I searched the news groups and saw there used to be a volatile. But it looks like it was done away with because of how it was misused (like C volatile) for thread sharing. But this is different. This is just telling the compiler not to optimize away an access. AFAIK, that's right. The compiler does not optimise across asm {} blocks. -Lars
Re: Templated delegate
Thanks, toDelegate is what I've been looking for. It still segfaults, though. The setup: === module mod1; import std.algorithm; import std.functional; import std.stdio; void main( ) { auto haystack = [a,b,c]; auto needle = b; auto flt = delegate(string s){return s == needle;}; auto dg = toDelegate( flt ); auto result = filter!dg(haystack); writeln(result); } = module mod2; import std.string; // or import std.conv; // or import std.random; dmd mod2.d mod1.d compiles, but compiled program segfaults. System is Debian GNU/Linux 5.0 on 2.6.26-2-686 #1 SMP i686. dmd is D 2.051. Simen kjaeraas Wrote: Mitja odtih...@gmail.com wrote: I would like to have a template which returns appropriate delegate, something like this: So like this? module mod1; import std.algorithm; import std.functional; import std.stdio; void main( ) { auto haystack = [a,b,c]; auto needle = b; auto flt = (string s){return s == needle;}; auto dg = toDelegate( flt ); auto result = filter!dg(haystack); writeln(result); } I would have to argue that the delegate is hardly templated, though. Not sure what that means. What would be the correct way for templated delegate? Depending on what you mean by 'templated delegate', I would say std.functional's toDelegate, as used above. Perhaps if you explained what you mean by 'templated delegate', I could give a better answer. -- Simen
Re: Templated delegate
Stewart Gordon Wrote: On 10/01/2011 13:02, Mitja wrote: I would like to have a template which returns appropriate delegate, something like this: For what purpose? All you seem to have is a long-winded identity function. snip and compiled it like this: dmd mod2.d mod1.d, the program would produce segmentation fault. I can't reproduce (DMD 2.051, Windows). In what setup are you experiencing the problem? The problem appears in the following setup: Debian GNU/Linux 5.0, kernel 2.6.26-2-686 #1 SMP i686. dmd is D 2.051. As well as on Windows XP as guest OS in VirtualBox. XP prints out: object.Error: Access Violation It works fine when packages in mod2 are omitted. When which packages in mod2 are omitted? I can only make out that this is a compiler bug that needs to be investigated. What would be the correct way for templated delegate? It depends on what you're trying to do. Stewart.
std.concurrency, or me?
Reddit let me to this article walking through an example of Goroutines[1]. I figured it could look about the same in D. So I set out to learn some multi-threading. And what I ended up with[2] had an issue. The mailbox size seems to be extremely small. Currently I have set the size to 10,000 and put a OnCrowding.throwException, though I wanted it to block, changing it will result in a program that won't exit, and it will not have finished processing all the calls. The last option of ignoring will result in many calls not being finished. This is tested no Linux, but I will test it on Windows tomorrow. I am running it with: ./callcenter 3 10 10 10 which says, 3 agents, 10 calls, with a maximum of 10 secs to process a call, and 10 ticks before creating the next call. 1. http://www.mprescient.com/journal/2011/1/9/concurrency-in-go-a-call-center-tutorial.html 2. https://gist.github.com/773979
[Issue 3929] Interactions between LRU array cache, memory recycling
http://d.puremagic.com/issues/show_bug.cgi?id=3929 Steven Schveighoffer schvei...@yahoo.com changed: What|Removed |Added Status|NEW |RESOLVED Resolution||FIXED --- Comment #9 from Steven Schveighoffer schvei...@yahoo.com 2011-01-10 06:59:47 PST --- Fixed in http://www.dsource.org/projects/druntime/changeset/496 Note that only destroying an array via delete arr will clear from the cache. Freeing using GC.free does not remove the data from the cache. If it becomes necessary to use GC.free to free an array because delete is deprecated, then we can revisit this problem. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5441] New: std.random.rndGen always returns Random.
http://d.puremagic.com/issues/show_bug.cgi?id=5441 Summary: std.random.rndGen always returns Random. Product: D Version: unspecified Platform: All OS/Version: All Status: NEW Severity: enhancement Priority: P2 Component: Phobos AssignedTo: and...@metalanguage.com ReportedBy: repeate...@gmail.com --- Comment #0 from Masahiro Nakagawa repeate...@gmail.com 2011-01-10 09:43:40 PST --- Created an attachment (id=867) Patch for this suggestion rndGen always returns Random(usually MT) object. This is often useful, but randomShuffle cant't take other random generators. I think following signature is better. ref RandomGen rndGen(RandomGen = Random)() But this change forces us to write parenthesis function call. rndGen;// Compilation error rndGen(); // OK, return Random object. For me, this is no problem. However I don't know the writing style of other people. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5442] New: std.algorithm.sort problem with struct with char[10]
http://d.puremagic.com/issues/show_bug.cgi?id=5442 Summary: std.algorithm.sort problem with struct with char[10] Product: D Version: D2 Platform: x86 OS/Version: Windows Status: NEW Keywords: rejects-valid Severity: normal Priority: P2 Component: Phobos AssignedTo: nob...@puremagic.com ReportedBy: bearophile_h...@eml.cc --- Comment #0 from bearophile_h...@eml.cc 2011-01-10 10:43:13 PST --- This D2 program tries to sort in-place a dynamic array of Foo according to just the first int x field (the third sort works on the whole structs), but when T is a char the program doesn't compile: import std.algorithm: sort, schwartzSort; alias char T; // doesn't work //alias int T; // works struct Foo { int x; T[10] a; } void main() { auto array = new Foo[10]; sort!(a.x b.x)(array); static bool myComp(Foo f1, Foo f2) { return f1.x f2.x; } sort!(myComp)(array); sort(array); } DMD 2.051 prints: ...\dmd\src\phobos\std\conv.d(99): Error: template std.conv.toImpl(T,S) if (!implicitlyConverts!(S,T) isSomeString!(T) isInputRange!(Unqual!(S)) isSomeChar!(ElementType!(S))) toImpl(T,S) if (!implicitlyConverts!(S,T) isSomeString!(T) isInputRange!(Unqual!(S)) isSomeChar!(ElementType!(S))) matches more than one template declaration, ...\dmd\src\phobos\std\conv.d(114):toImpl(T,S) if (!implicitlyConverts!(S,T) isSomeString!(T) isInputRange!(Unqual!(S)) isSomeChar!(ElementType!(S))) and ...\dmd\src\phobos\std\conv.d(224):toImpl(T,S) if (isStaticArray!(S)) -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5444] New: std.string.format: arguments without format specifier appended to result
http://d.puremagic.com/issues/show_bug.cgi?id=5444 Summary: std.string.format: arguments without format specifier appended to result Product: D Version: D2 Platform: Other OS/Version: Windows Status: NEW Severity: normal Priority: P2 Component: Phobos AssignedTo: nob...@puremagic.com ReportedBy: tomeks...@gmail.com --- Comment #0 from Tomasz Sowiński tomeks...@gmail.com 2011-01-10 15:11:21 PST --- assert(format(aaa, 1) == aaa); // fails, produces aaa1 assert(format(1%s3, 2, 4, '5') == 123); // fails, produces 12345 Interestingly, writefln behaves correctly. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 5443] icmp only works correctly for ASCII
http://d.puremagic.com/issues/show_bug.cgi?id=5443 Andrei Alexandrescu and...@metalanguage.com changed: What|Removed |Added Status|NEW |RESOLVED CC||and...@metalanguage.com Resolution||FIXED --- Comment #1 from Andrei Alexandrescu and...@metalanguage.com 2011-01-10 16:51:53 PST --- Fixed in http://www.dsource.org/projects/phobos/changeset/2298 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 3313] Check when immutability is really needed in std.string
http://d.puremagic.com/issues/show_bug.cgi?id=3313 Andrei Alexandrescu and...@metalanguage.com changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution||FIXED --- Comment #2 from Andrei Alexandrescu and...@metalanguage.com 2011-01-10 16:52:27 PST --- Fixed in http://www.dsource.org/projects/phobos/changeset/2298 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 4588] [lex] @ttributes are not documented
http://d.puremagic.com/issues/show_bug.cgi?id=4588 Bernard Helyer blood.of.l...@gmail.com changed: What|Removed |Added CC||blood.of.l...@gmail.com --- Comment #1 from Bernard Helyer blood.of.l...@gmail.com 2011-01-10 17:50:15 PST --- It's not that there's an alternative syntax for pure and nothrow, it's that (like immutable) they are both a storage class and attributes (the attribute form merely imbuing scoped declarations with the corresponding storage class). They should be listed in the attribute page, but aren't. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---
[Issue 4588] [lex] @ttributes are not documented
http://d.puremagic.com/issues/show_bug.cgi?id=4588 Jonathan M Davis jmdavisp...@gmx.com changed: What|Removed |Added CC||jmdavisp...@gmx.com --- Comment #2 from Jonathan M Davis jmdavisp...@gmx.com 2011-01-10 19:09:22 PST --- I would expect @pure and @nothrow to be going away. It was decided to go with pure and nothrow rather than @pure and @nothrow, so I don't see why the @ versions would be sticking around. We ended up with both, because it was debated as to what should use @ and what should be a keyword. @safe, @trusted, and @system are all valid, as is @property. However, I can't think of any others at the moment which are actually currently supposed to have @ on the front. And as for @ being a token, I'm not sure that it _is_ a token. I'd have to look at the lexer code to verify one way or another. Given the way that @ is used, I think that there's a decent chance that @safe, @trusted, @system, and @property are all considered tokens and @ isn't. I would like it to be though, since it would be necessary if we're ever going to get user-defined attributes. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email --- You are receiving this mail because: ---