Re: [Phoronix] D Language Still Showing Promise, Advancements
Am Thu, 20 Jun 2013 22:53:13 +0200 schrieb Adam D. Ruppe destructiona...@gmail.com: On Thursday, 20 June 2013 at 20:47:19 UTC, Michael wrote: Also 3 types of pointers scares me. This actually doesn't scare me because it is kinda useful for certain situations. However, I don't think it needs to be built into the language because library types can do the same kind of thing. Yes, once you know about UniquePtr, NotNullable, RefCounted and such, 3 pointer types isn't scary are all. But Rust pointers don't map 100% to library types. They have compiler support which removes the syntactical noise of templates and makes them behave more natural. For example in D everything becomes a struct once you add functionality around it and creates corner cases that aren't supported. I wonder how many D programmers actually use Phobos' library pointer types. -- Marco
Re: [Phoronix] D Language Still Showing Promise, Advancements
On Sunday, 23 June 2013 at 15:30:16 UTC, Marco Leise wrote: They have compiler support which removes the syntactical noise of templates and makes them behave more natural. Indeed. I don't mind the syntax (actually, I prefer RefCounted!T to ~T or whatever symbol rust uses) but there's some other things their compiler does like forbid reassigning a refcounted thing if you have a pointer to it still in scope that D can't do in the library. But the library types can do the bulk of it, and disabling certain problematic parts of the struct helps keep it sane. I wonder how many D programmers actually use Phobos' library pointer types. Ironically, I don't, but I do use similar recreations for certain tasks.
Re: LDC in LLVM Release Notes
On 6/19/2013 11:02 PM, Kai Nacke wrote: On Wednesday, 19 June 2013 at 20:40:39 UTC, qznc wrote: LDC is explicitly mentioned in the LLVM 3.3 Release Notes [0]. In contrast to other frontends, LDC seems to follow upstream much more closely (or maybe is forced to due to bugs?). Anyhow, kudos to David Nadlinger and whoever else was involved! [0] http://llvm.org/releases/3.3/docs/ReleaseNotes.html#ldc-the-llvm-based- d-compiler LDC is mentioned in all release notes of LLVM starting with 3.1. I follow LLVM development closely and try to keep LDC head in sync with LLVM trunk. Personally I think that the release notes of LLVM are really good to spread the word about LDC and D. So I made sure that LDC is mentioned as external project. :-) Awesome!
Re: DConf 2013 Day 3 Talk 5: Effective SIMD for modern architectures by Manu Evans
Manu: This is interesting. I didn't know about this. An important thing here is: what's the semantics present in that language that is missing in D (and that is useful for the optimizer)? Is it possible/worth to add it? Bye, bearophile
Re: D/Objective-C, extern (Objective-C)
Jacob Carlborg: http://michelf.ca/projects/d-objc/syntax/ Instead of: extern (Objective-C) Is it better to use a naming more D-idiomatic? extern (Objective_C) Regarding this syntax: void insertItem(ObjcObject object, NSInteger value) [insertItemWithObjectValue:atIndex:]; Is it possible and good to replace it with some UDA? I'm planning to create a DIP for this and would really like this to be folded into main line. It seems contain some different things/syntax. I don't know how much WalterCo will appreciate it. Bye, bearophile
Re: D/Objective-C, extern (Objective-C)
On 2013-06-23, 23:02, bearophile wrote: Jacob Carlborg: http://michelf.ca/projects/d-objc/syntax/ Instead of: extern (Objective-C) Is it better to use a naming more D-idiomatic? extern (Objective_C) There's already some precedence in extern (C++). -- Simen
Re: D vs Haskell
On Saturday, 22 June 2013 at 21:45:48 UTC, Juan Manuel Cabo wrote: Right, the author of the article used ldc. I'm always used to dmd. You know that you can use ldmd2 to invoke LDC using the same flags as DMD? This time I used LDC 0.11.0, with: ldc2 -O -release -disable-boundscheck Times (minimum of 10 runs): before: 1617 ms after: 554 ms Conclusion: using byWords was 3.4 times faster with DMD and 2.9 times faster with LDC. Any chance of GDC results? You can again use gdmd for DMD-like interface.
Re: What features of D are you using now which you thought you'd never goint to use?
On Sunday, 23 June 2013 at 04:08:22 UTC, Vladimir Panteleev wrote: On Saturday, 22 June 2013 at 20:09:01 UTC, monarch_dodra wrote: #2: Extremelly bad compatibility with simple no bidir/non-slicing ranges: There is no way to iterate over a specific part of a range, and making a range out of what was just iterated over. For example Get the beggining of this range until the first x: not possible without slicing. Not sure if I understood the question correctly, but the way I understood it: 1) To iterate over a specific part of a non-random-access range, you can use `drop` in conjunction with `take` or `takeExactly`. 2) To get an existing foreach loop to emit a range, move its body to the predicate of `map`, and break conditions to the predicate of `until` / `countUntil`. 3) As I understand, get the beggining of this range until the first x, without slicing is what `until` (or `countUntil` + `take`) does. All of these will *iterate* over part of said range, but none will actually return the subrange I iterated on. V [ . . X . . . . . . . . ] I want: [ . . X ] D gives me: [ X . . . . . . . . ] countUntil + take can kind of mitigate the problem, but that warps the type system: The type of take is not the type of the range.
Re: What features of D are you using now which you thought you'd never goint to use?
rvalue references SCNR
Re: memory allocation in dmd
On 2013-06-22 23:41, Walter Bright wrote: Compiling std.algorithm for unittests consumes all the memory on many machines. I've been looking into what is allocating all that memory, and it isn't so easy without adding instrumentation code anywhere. Anyone know of a convenient tool to do this on Linux? (valgrind just hangs, or at least I gave up on it after 6 hours) There's a tool called dtrace on Mac OS X and *BSD which possibly could be used for this. Don't know if there's a corresponding tool for Linux. Hmm, seems to be available on Oracle Linux. http://en.wikipedia.org/wiki/DTrace -- /Jacob Carlborg
Re: What features of D are you using now which you thought you'd never goint to use?
On Sunday, 23 June 2013 at 09:10:03 UTC, monarch_dodra wrote: All of these will *iterate* over part of said range, but none will actually return the subrange I iterated on. `until` does not iterate, it simply returns a range which ends when your condition is satisfied. V [ . . X . . . . . . . . ] I want: [ . . X ] Isn't this what `until` does? countUntil + take can kind of mitigate the problem, but that warps the type system: The type of take is not the type of the range. I believe wrapper ranges like `take` return ranges with the same capabilities as the ranges they wrap. This modularity design assumes that you will use the result in functions that accept ranges, i.e. templated functions that expect that the types of their parameters satisfy the is*Range constraints. To avoid misunderstanding or miscommunication, could you post the practical problem you encountered, with context?
Re: What features of D are you using now which you thought you'd never goint to use?
On Sunday, 23 June 2013 at 09:44:09 UTC, Vladimir Panteleev wrote: On Sunday, 23 June 2013 at 09:10:03 UTC, monarch_dodra wrote: All of these will *iterate* over part of said range, but none will actually return the subrange I iterated on. `until` does not iterate, it simply returns a range which ends when your condition is satisfied. Lazily iterates range until value sentinel is found, at which point it stops. V [ . . X . . . . . . . . ] I want: [ . . X ] Isn't this what `until` does? Not quite, it returns an object that returns those items when iterated on. But it is not the same type. countUntil + take can kind of mitigate the problem, but that warps the type system: The type of take is not the type of the range. I believe wrapper ranges like `take` return ranges with the same capabilities as the ranges they wrap. This modularity design assumes that you will use the result in functions that accept ranges, i.e. templated functions that expect that the types of their parameters satisfy the is*Range constraints. Same capabilities, different types. To avoid misunderstanding or miscommunication, could you post the practical problem you encountered, with context? The problem always boils down the fact that while we can get the same iteration scheme, it's never the same range type: Range r = some_range; r = r.until!a == 5; //Does not compile Until!Range and Range do not match r = r.take(5); //Does not compile: Take!Range and Range do not match
Re: What features of D are you using now which you thought you'd never goint to use?
On Sunday, 23 June 2013 at 09:54:56 UTC, monarch_dodra wrote: Isn't this what `until` does? Not quite, it returns an object that returns those items when iterated on. But it is not the same type. OK, I think we had a misunderstanding what iterate meant. I used it in the meaning iterate the range at the time of the call as opposed to return a range that, when iterated, iterates its parameter. The problem always boils down the fact that while we can get the same iteration scheme, it's never the same range type: Range r = some_range; r = r.until!a == 5; //Does not compile Until!Range and Range do not match r = r.take(5); //Does not compile: Take!Range and Range do not match So is it all about reusing a variable? For this, you can use the InputRange interface, and the InputRangeObject template which creates a crass type that inherits from the InputRange interface. Of course, since what you are requesting is essentially runtime polymorphism, this will come with a performance cost of a virtual method call for every range primitive.
Re: What features of D are you using now which you thought you'd never goint to use?
On Sunday, 23 June 2013 at 10:37:34 UTC, Vladimir Panteleev wrote: The problem always boils down the fact that while we can get the same iteration scheme, it's never the same range type: Range r = some_range; r = r.until!a == 5; //Does not compile Until!Range and Range do not match r = r.take(5); //Does not compile: Take!Range and Range do not match So is it all about reusing a variable? It's a bit more than that, it's also about limiting template bloat. For example: R range; auto r3 = findSplit(range); void do_it(r3[0]); void do_it(r3[1]); void do_it(r3[2]); This will actually instantiate 2 different do_it functions. This might sound trivial, but these things scale. It also means iteration will be more expensive than necessary (take will compare both length and empty). Also, and this is subtle: If you use take, your range will have a fixed size, whereas a true bidirectional range will be defined by a start and end point. For example, with the above find split, taken from a DList: If I add elements to the DList, a DList.Range will grow to accomodate new elements that where inserted between its bounds. Take!(DList.Range), on the other hand, will *not* grow, and as elements are inserted, the back elements will be pushed outside of the Range. It might not sound like much, but have you *tried* using DList? Or writing an algo meant to specifically exploit DList mechanics? With ranges, it just doesn't really work quite as well as it should...
Re: What features of D are you using now which you thought you'd never goint to use?
On 06/23/2013 10:54 AM, monarch_dodra wrote: Not quite, it returns an object that returns those items when iterated on. But it is not the same type. Why does that matter to you? One of the nice things about ranges is that the strict object type seems to matter less than the interface and the type that .front returns. E.g. someRange.takeExactly(10) is not of the same type as someRange, but I find that largely irrelevant when using it. Not intending to dismiss your concern, just curious to understand your requirements.
Re: What features of D are you using now which you thought you'd never goint to use?
On Sunday, 23 June 2013 at 11:06:07 UTC, Joseph Rushton Wakeling wrote: On 06/23/2013 10:54 AM, monarch_dodra wrote: Not quite, it returns an object that returns those items when iterated on. But it is not the same type. Why does that matter to you? One of the nice things about ranges is that the strict object type seems to matter less than the interface and the type that .front returns. E.g. someRange.takeExactly(10) is not of the same type as someRange, but I find that largely irrelevant when using it. Not intending to dismiss your concern, just curious to understand your requirements. That's a very I have a range and want to iterate on it view. Which is fine and it works in that case (and I have no problems there). But as soon as you need an algorithm that actually *handles* ranges: swaps them, merges them, searches in them and splices them, then things get hairy. For example, try implementing a sort (either merge or q) with a non-sliceable range... very very hard...
Re: What features of D are you using now which you thought you'd never goint to use?
On 06/23/2013 12:34 PM, monarch_dodra wrote: That's a very I have a range and want to iterate on it view. Which is fine and it works in that case (and I have no problems there). But as soon as you need an algorithm that actually *handles* ranges: swaps them, merges them, searches in them and splices them, then things get hairy. For example, try implementing a sort (either merge or q) with a non-sliceable range... very very hard... I would take that as a fault in the adaptor, surely? A well designed implementation of take or takeExactly or until or any of these other range adaptors ought to preserve as many properties of the input range as possible.
std.net.curl broken?
I just wanted to get the contents of a smiple html page using std.net.curl (on Windows) So I did (exactly like in the library documentation example) string contents = get(dlang.org); But this won't even compile, not with dmd 2.062 and not with 2.063 main.d(8): Error: cannot implicitly convert expression (get(dlang.org, AutoProtocol())) of type char[] to string C:\digital-mars\dmd2-63\windows\bin\..\..\src\phobos\std\range.d(611): Error: static assert Cannot put a const(dchar) into a Appender!(char[]) C:\digital-mars\dmd2-63\windows\bin\..\..\src\phobos\std\format.d(2160): instantiated from here: put!(Appender!(char[]), const(dchar)) C:\digital-mars\dmd2-63\windows\bin\..\..\src\phobos\std\format.d(2207): instantiated from here: formatChar!(Appender!(char[])) C:\digital-mars\dmd2-63\windows\bin\..\..\src\phobos\std\typecons.d(581): instantiated from here: formatElement!(Appender!(string), char[], char) C:\digital-mars\dmd2-63\windows\bin\..\..\src\phobos\std\net\curl.d(1873): ... (4 instantiations, -v to show) ... C:\digital-mars\dmd2-63\windows\bin\..\..\src\phobos\std\net\curl.d(374): instantiated from here: get!(FTP, char) main.d(8): instantiated from here: get!(AutoProtocol, char) Are the exampels not tested? What is wrong here? Kind Regards Benjamin Thaut
Re: What features of D are you using now which you thought you'd never goint to use?
On Sunday, 23 June 2013 at 11:04:17 UTC, monarch_dodra wrote: It's a bit more than that, it's also about limiting template bloat. For example: To mitigate template bloat, you can downgrade compile-time polymorphism to runtime polymorphism. D provides the facilities for this, e.g. using the above-mentioned pre-made InputRange interface, or using the new `wrap` template from std.typecons in git / 2.064. It also means iteration will be more expensive than necessary (take will compare both length and empty). FWIW, `takeExactly` does not. Also, and this is subtle: If you use take, your range will have a fixed size, whereas a true bidirectional range will be defined by a start and end point. For example, with the above find split, taken from a DList: If I add elements to the DList, a DList.Range will grow to accomodate new elements that where inserted between its bounds. Take!(DList.Range), on the other hand, will *not* grow, and as elements are inserted, the back elements will be pushed outside of the Range. Then the answer would be to not use `take` on ranges that might change. `take` is one way to limit the length of a range (by a number), but it is not the only way to limit the length of a range. For example, try implementing a sort (either merge or q) with a non-sliceable range... very very hard... Are we talking about random-access range types that do not implement opSlice? Wouldn't it be easy to create a wrapper range on top of any random-access range that does implement opSlice? Otherwise, I don't see how it's even possible (or desirable) to sort a non-random-access range. It might not sound like much, but have you *tried* using DList? No. I clearly do not have the same experience with using ranges as you. It's just that the problems that you have presented, as you have presented them, appeared to me to have obvious solutions.
Re: std.net.curl broken?
On Sunday, 23 June 2013 at 12:08:08 UTC, Benjamin Thaut wrote: I just wanted to get the contents of a smiple html page using std.net.curl (on Windows) So I did (exactly like in the library documentation example) string contents = get(dlang.org); Looks like a documentation bug. `get(dlang.org)` will return a char[], not a string. The unrelated errors in std.range an std.format are caused by a DMD bug (7904, I believe).
Re: memory allocation in dmd
Am 22.06.2013 23:41, schrieb Walter Bright: Compiling std.algorithm for unittests consumes all the memory on many machines. I've been looking into what is allocating all that memory, and it isn't so easy without adding instrumentation code anywhere. Anyone know of a convenient tool to do this on Linux? (valgrind just hangs, or at least I gave up on it after 6 hours) there are sometimes better tools on windows or commercials - you should try these http://www.softwareverify.com/cpp-memory.php - i like this one http://mtuner.net/ http://www.puredevsoftware.com/MemPro.htm all for memory leak detection, but also doing memory profiling
Re: std.net.curl broken?
Am 23.06.2013 14:08, schrieb Benjamin Thaut: I just wanted to get the contents of a smiple html page using std.net.curl (on Windows) So I did (exactly like in the library documentation example) string contents = get(dlang.org); But this won't even compile, not with dmd 2.062 and not with 2.063 main.d(8): Error: cannot implicitly convert expression (get(dlang.org, AutoProtocol())) of type char[] to string C:\digital-mars\dmd2-63\windows\bin\..\..\src\phobos\std\range.d(611): Error: static assert Cannot put a const(dchar) into a Appender!(char[]) C:\digital-mars\dmd2-63\windows\bin\..\..\src\phobos\std\format.d(2160): instantiated from here: put!(Appender!(char[]), const(dchar)) C:\digital-mars\dmd2-63\windows\bin\..\..\src\phobos\std\format.d(2207): instantiated from here: formatChar!(Appender!(char[])) C:\digital-mars\dmd2-63\windows\bin\..\..\src\phobos\std\typecons.d(581): instantiated from here: formatElement!(Appender!(string), char[], char) C:\digital-mars\dmd2-63\windows\bin\..\..\src\phobos\std\net\curl.d(1873): ... (4 instantiations, -v to show) ... C:\digital-mars\dmd2-63\windows\bin\..\..\src\phobos\std\net\curl.d(374): instantiated from here: get!(FTP, char) main.d(8): instantiated from here: get!(AutoProtocol, char) Are the exampels not tested? What is wrong here? Kind Regards Benjamin Thaut Nevermind, I found the problem, all the error message noise made me miss it.
Re: D vs Haskell
On 06/23/2013 05:42 AM, Joseph Rushton Wakeling wrote: On Saturday, 22 June 2013 at 21:45:48 UTC, Juan Manuel Cabo wrote: Right, the author of the article used ldc. I'm always used to dmd. You know that you can use ldmd2 to invoke LDC using the same flags as DMD? This time I used LDC 0.11.0, with: ldc2 -O -release -disable-boundscheck Times (minimum of 10 runs): before: 1617 ms after: 554 ms Conclusion: using byWords was 3.4 times faster with DMD and 2.9 times faster with LDC. Any chance of GDC results? You can again use gdmd for DMD-like interface. The computer where I tested has Kubuntu 12.04, which is too old even for gcc-4.7, and I cannot compile GDC there. The gdc version which comes in the repository fails to compile the program, even after some rearranging so that it doesn't use UFCS. Anyway, using my byWord range to iterate the string will surely be faster with GDC too, because tr and split can be a little slow, especially since the string is big (5MB). I tested a little more and found that using a handcoded function instead of tr, and using splitter instead of split, it's almost as fast as the byWord version. The handcoded function assumes ascii and preallocates the resulting string (with result.length = source.length). --jm
Re: memory allocation in dmd
On Sunday, 23 June 2013 at 09:37:26 UTC, Jacob Carlborg wrote: On 2013-06-22 23:41, Walter Bright wrote: Compiling std.algorithm for unittests consumes all the memory on many machines. I've been looking into what is allocating all that memory, and it isn't so easy without adding instrumentation code anywhere. Anyone know of a convenient tool to do this on Linux? (valgrind just hangs, or at least I gave up on it after 6 hours) There's a tool called dtrace on Mac OS X and *BSD which possibly could be used for this. Don't know if there's a corresponding tool for Linux. Hmm, seems to be available on Oracle Linux. http://en.wikipedia.org/wiki/DTrace That would be SystemTap on Linux. However, I wonder if it is the right tool for the job.
Re: SIMD on Windows
On 22.06.2013 02:07, Manu wrote: It would certainly be nice in Win32, but I tend to think Win32 COFF should be much higher priority. I have removed the dust from these patches and pushed them successfully through the test suite and unittests: https://github.com/rainers/dmd/tree/coff32 https://github.com/rainers/druntime/tree/coff32 https://github.com/rainers/phobos/tree/coff32 Compile dmd as usual, but druntime and phobos with something like druntime: make -f win64.mak MODEL=32ms CC=path-to-32bit-cl phobos: make -f win64.mak MODEL=32ms CC=path-to-32bit-cl AR=path-to-32bit-lib COFF32 files are generated when -m32ms is used on the command line. If you put the resulting libraries into the lib folder, using a standard installation of VS2010 might work, but I recommend adding a new section to sc.ini and adjust paths there. Mine looks like this: [Environment32ms] PATH=c:\l\vs9\Common7\IDE;%PATH% LIB=%@P%\..\..\lib32;c:\l\vs9\vc\lib;c:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib DFLAGS=%DFLAGS% -L/nologo -L/INCREMENTAL:NO LINKCMD=c:\l\vs9\vc\bin\link.exe BTW: I also found some bugs in the Win64 along the way, I'll create pull requests for these.
Re: feature request: __traits(getTemplate, A!T) = A; __traits(getTemplateArguments, A!(T,foo)) = (T,foo)
On 6/23/13, Timothee Cour thelastmamm...@gmail.com wrote: What we need: __traits(getTemplate, A!T) = A __traits(getTemplateArguments, A!(T,foo)) = (T,foo) (ie returns a tuple as in parameterTypeTuple or similar) http://d.puremagic.com/issues/show_bug.cgi?id=4265
Re: What features of D are you using now which you thought you'd never goint to use?
On 6/23/13 4:04 AM, monarch_dodra wrote: R range; auto r3 = findSplit(range); void do_it(r3[0]); void do_it(r3[1]); void do_it(r3[2]); This will actually instantiate 2 different do_it functions. Yah, this is a good summary. If individual iterators are accessible, findSplit can return three ranges of the same type. Otherwise, generally findSplit must return ranges of distinct types. Note, however, that if the initial range is strictly forward, the three resulting range may not have the same type as the initial range. As a simple example, findSplit over a singly-linked list cannot return three singly-linked lists. (I don't think template bloat is the main problem here, instead a sort of matter of principles.) Again, we can make things work by introducing a primitive for bidirectional ranges: R before(R r1, R r2); Assuming r2 is reachable from r1, returns the portion of r1 that lies before r2. (Definition: a range r2 is reachable from another range r1 if calling r1.popFront() repeatedly will at some point make r1.front and r2.front refer to the same value.) Andrei
Re: What features of D are you using now which you thought you'd never goint to use?
On 6/23/13 7:39 AM, Andrei Alexandrescu wrote: Again, we can make things work by introducing a primitive for bidirectional ranges: R before(R r1, R r2); Assuming r2 is reachable from r1, returns the portion of r1 that lies before r2. (Definition: a range r2 is reachable from another range r1 if calling r1.popFront() repeatedly will at some point make r1.front and r2.front refer to the same value.) The question is, should we add this primitive? There's discussion on adding ranges to C++, and discussion inevitably reaches an impasse when it gets to this particular matter. I personally think we should and am amazed that we made it so far without that primitive. However, unlike others, I don't think it's an essential matter. Some C++ people tend to be apprehensive when they figure they can do something with iterators that's not doable with ranges. Andrei
Re: What features of D are you using now which you thought you'd never goint to use?
23-Jun-2013 06:13, Brad Anderson пишет: On Sunday, 23 June 2013 at 01:34:53 UTC, Andrei Alexandrescu wrote: On 6/22/13 2:58 PM, monarch_dodra wrote: long story short: we don't have rfind. C++ does. We do, just that it's for random-access ranges. C++ offers it for bidirectional ranges too. We could of course support it if bidirectional ranges were required to have something like r1.before(r2) that, assuming r2 is reachable from r1, returns the portion in r1 that's before r2. Andrei That sounds like exactly what I needed for a version of toUpper I was playing with that added support for output ranges. The implementation is rather trivial: Writer toUpper(S, Writer)(S s, Writer w) @trusted And I would love to add functions of this style to the new std.uni especially as toLower is a fair bit more tricky then this. if(isSomeString!S) { size_t count = 0; foreach (c, i; s) { if (std.uni.isLower(c)) { c = std.uni.toUpper(c); } put(w, c); count = i; } return w; } Works just fine with something like Appender. The problem is that if you pass in dynamic or static array slice to store the result in you have no way of knowing how much of the target array was filled by the function. You could use save() and keep track of how many bytes were consumed and return a slice of that size but that feels very clunky (and could be tricky to implement correctly if the input string is a different encoding than the output range). -- Dmitry Olshansky
Re: memory allocation in dmd
On 2013-06-23 15:12, qznc wrote: That would be SystemTap on Linux. However, I wonder if it is the right tool for the job. Mac OS X has Instruments as well, which is used for these type of tasks. It's built on top of Dtrace: http://en.wikipedia.org/wiki/Instruments_(application) -- /Jacob Carlborg
Re: Implicit encoding conversion on string ~= int ?
I think what's happening is the compiler considers chars to be integral types (like they were in C), which means some implicit conversions between char, int, dchar, and others happen. So char[] a; int b = 1000; a ~= b; the a ~= b is more like a ~= cast(dchar) b, and then dchar - char means it may be multibyte encoded, going from utf-32 to utf-8.
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On 6/21/13 4:02 PM, Walter Bright wrote: On 6/21/2013 3:35 PM, Andrei Alexandrescu wrote: On 6/21/13 3:22 PM, Adam D. Ruppe wrote: Just for laughs I just slapped together a strstr Post it and I'll destroy it. Can I play, too? Mine from the Digital Mars C library. Haven't looked at it since 2001. == /*_ strstr.c */ /* Copyright (C) 1985-2001 by Digital Mars */ /* All Rights Reserved */ /* www.digitalmars.com */ /* Written by Walter Bright */ #include stdio.h #include ctype.h #include stddef.h #include string.h #include stdlib.h #if 0 /* Smaller but slower under many circumstances. */ char *strstr(const char *s1,const char *s2) { size_t len2; size_t len1; char c2 = *s2; len1 = strlen(s1); len2 = strlen(s2); if (!len2) return (char *) s1; while (len2 = len1) { if (c2 == *s1) if (memcmp(s2,s1,len2) == 0) return (char *) s1; s1++; len1--; } return NULL; } #else I won't comment on the B-M implementation. This brute force implementation has the problem of calling strlen on both strings upfront, which is arguably unnecessary. Although it doesn't affect complexity, it is an inefficiency hard to recover from. (The tradeoff is that memcmp will help with that.) Andrei
Re: What features of D are you using now which you thought you'd never goint to use?
On Sunday, 23 June 2013 at 14:47:17 UTC, Andrei Alexandrescu wrote: On 6/23/13 7:39 AM, Andrei Alexandrescu wrote: Again, we can make things work by introducing a primitive for bidirectional ranges: R before(R r1, R r2); Assuming r2 is reachable from r1, returns the portion of r1 that lies before r2. (Definition: a range r2 is reachable from another range r1 if calling r1.popFront() repeatedly will at some point make r1.front and r2.front refer to the same value.) The question is, should we add this primitive? There's discussion on adding ranges to C++, and discussion inevitably reaches an impasse when it gets to this particular matter. I personally think we should and am amazed that we made it so far without that primitive. However, unlike others, I don't think it's an essential matter. Some C++ people tend to be apprehensive when they figure they can do something with iterators that's not doable with ranges. Andrei Just for the record (because I'm the one that usually brings this up), I think ranges are a big win overall. I just find it frustrating every time the always shrink never grow problem gets in my way of writing simple and efficient algorithms. before might work, but it would also introduce a new primitve, as well as a new trait (isSpliceable?). There is a real gain to cost ratio, which I'm not sure is worth it. The semantics for it would also be kind of complicated: you'd have before, after, beforeIncluding, merge... I'm wondering if something along the lines of an iterable range might not be much more simple? Probably not :(
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On 6/22/13 12:28 PM, Adam D. Ruppe wrote: On Saturday, 22 June 2013 at 16:38:31 UTC, Andrei Alexandrescu wrote: Huh, even the shortest impl I can think of is about the same length: inout(char)* mystrstr(inout(char)* haystack, const(char*) needle) { assert(haystack !is null); if(needle is null) return haystack; while(*haystack) { auto h = haystack; const(char)* n = needle; while(*n == *h *n *h) { h++; n++; } if(*n == 0) return haystack; haystack++; } return null; } I like this a lot better because it is more straightforward. Still buggy. The empty string must be a prefix of any string including the empty string. I describe the canonical implementation of substring brute for string search as far as I see it http://www.serversidemagazine.com/news/10-questions-with-facebook-research-engineer-andrei-alexandrescu/. Andrei
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On Sunday, 23 June 2013 at 16:07:05 UTC, Andrei Alexandrescu wrote: Still buggy. The empty string must be a prefix of any string including the empty string. Huh. Well, that makes sense. Just change while to do while and you've got that. Probably compiles to exactly the same code as your implementation in the link at that point. But this probably told you more about my methods than getting it right the first time would have: I'll just slap something together that's good enough for the test case(s) fed to it and then change it if new stuff arises where it fails. One of the nice things about software is you generally don't have to get it right the first time since it is so easy to change. This is TDD-lite isn't it! lol http://www.serversidemagazine.com/news/10-questions-with-facebook-research-engineer-andrei-alexandrescu/. I definitely remember reading that when you posted it a while ago because I have code that does that ?d writeln(hello, world); ? laying around. http://arsdnet.net/dcode/dhp.d It works by just reading the file and translating everything outside the ?d? into a giant writeln(string literal), pasting in the D code, then compile+running it, inserting a bunch of imports so it works. dom.d now supports those kinds of tags, it could probably be even nicer, especially with a D lexer so it doesn't think ? is the same as ?. But as I'm sure I said then, this is a bad idea anyway since mixing code and html data leads to ugliness, whether the code is php or D.
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On 6/23/13 9:21 AM, Adam D. Ruppe wrote: http://arsdnet.net/dcode/dhp.d It works by just reading the file and translating everything outside the ?d? into a giant writeln(string literal), pasting in the D code, then compile+running it, inserting a bunch of imports so it works. dom.d now supports those kinds of tags, it could probably be even nicer, especially with a D lexer so it doesn't think ? is the same as ?. But as I'm sure I said then, this is a bad idea anyway since mixing code and html data leads to ugliness, whether the code is php or D. Nice! (BTW: foreach(ln; stdin.byLine) { string line = ln.idup ~ \n; is simpler written as foreach(ln; stdin.byLine(KeepTerminator.yes)) { string line = ln.idup; .) Would be awesome if an Apache extension would make it trivial to write Web pages in D. Andrei
Re: feature request: __traits(getTemplate, A!T) = A; __traits(getTemplateArguments, A!(T,foo)) = (T,foo)
Nice, thanks! Didn't know this syntax is allowed in template specialization too.
Re: What features of D are you using now which you thought you'd never goint to use?
On Sunday, 23 June 2013 at 14:47:17 UTC, Andrei Alexandrescu wrote: On 6/23/13 7:39 AM, Andrei Alexandrescu wrote: Again, we can make things work by introducing a primitive for bidirectional ranges: R before(R r1, R r2); Assuming r2 is reachable from r1, returns the portion of r1 that lies before r2. (Definition: a range r2 is reachable from another range r1 if calling r1.popFront() repeatedly will at some point make r1.front and r2.front refer to the same value.) The question is, should we add this primitive? There's discussion on adding ranges to C++, and discussion inevitably reaches an impasse when it gets to this particular matter. I personally think we should and am amazed that we made it so far without that primitive. However, unlike others, I don't think it's an essential matter. Some C++ people tend to be apprehensive when they figure they can do something with iterators that's not doable with ranges. Andrei BTW, kind of off topic, but since we are talking about bidirectional ranges, and DList is the most relevant object: Do you think you would have time to review my DList fix? https://github.com/D-Programming-Language/phobos/pull/953 As Dmity said: are we all in agreement to pull this in before release? ; which was 6 months ago :/ I think its time we deal with DList's issues.
Re: Implicit encoding conversion on string ~= int ?
Adam D. Ruppe: char[] a; int b = 1000; a ~= b; the a ~= b is more like a ~= cast(dchar) b, and then dchar - char means it may be multibyte encoded, going from utf-32 to utf-8. I didn't know that, is this already in Bugzilla? Bye, bearophile
Re: SIMD on Windows
I've said it before, but this man is a genius! :) On 23 June 2013 23:33, Rainer Schuetze r.sagita...@gmx.de wrote: On 22.06.2013 02:07, Manu wrote: It would certainly be nice in Win32, but I tend to think Win32 COFF should be much higher priority. I have removed the dust from these patches and pushed them successfully through the test suite and unittests: https://github.com/rainers/**dmd/tree/coff32https://github.com/rainers/dmd/tree/coff32 https://github.com/rainers/**druntime/tree/coff32https://github.com/rainers/druntime/tree/coff32 https://github.com/rainers/**phobos/tree/coff32https://github.com/rainers/phobos/tree/coff32 Compile dmd as usual, but druntime and phobos with something like druntime: make -f win64.mak MODEL=32ms CC=path-to-32bit-cl phobos: make -f win64.mak MODEL=32ms CC=path-to-32bit-cl AR=path-to-32bit-lib COFF32 files are generated when -m32ms is used on the command line. If you put the resulting libraries into the lib folder, using a standard installation of VS2010 might work, but I recommend adding a new section to sc.ini and adjust paths there. Mine looks like this: [Environment32ms] PATH=c:\l\vs9\Common7\IDE;%**PATH% LIB=%@P%\..\..\lib32;c:\l\**vs9\vc\lib;c:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Lib DFLAGS=%DFLAGS% -L/nologo -L/INCREMENTAL:NO LINKCMD=c:\l\vs9\vc\bin\link.**exe BTW: I also found some bugs in the Win64 along the way, I'll create pull requests for these.
Re: Implicit encoding conversion on string ~= int ?
Am Sun, 23 Jun 2013 18:37:16 +0200 schrieb bearophile bearophileh...@lycos.com: Adam D. Ruppe: char[] a; int b = 1000; a ~= b; the a ~= b is more like a ~= cast(dchar) b, and then dchar - char means it may be multibyte encoded, going from utf-32 to utf-8. No no no, this is not what happens. In my case it was: string a; int b = 228; // CP850 value for 'ä'. Note: fits in a single byte! a ~= b; Maybe it goes as follows: o compiler sees ~= to a string and becomes aware of wchar and dchar conversions to char o appended value is only checked for size (type and signedness are lost) and maps int to dchar o this dchar value is now checked for Unicode conformity and fails the test o the dchar value is now assumed to be Latin-1, Windows-1252 or similar and a conversion routine invoked o the dchar value is converted to utf-8 and... o appended as a multi-byte string to variable a. That still doesn't sound right to me thought. What if the dchar value is not valid Unicode AND = 256 ? I didn't know that, is this already in Bugzilla? Bye, bearophile I don't know what exactly is supposed to happen here. -- Marco
Re: Implicit encoding conversion on string ~= int ?
On Sunday, 23 June 2013 at 16:37:18 UTC, bearophile wrote: I didn't know that, is this already in Bugzilla? I don't know, but if it is, it is probably marked as won't fix because I'm pretty sure this has come up before, but it is actually by design because a char in C is considered an integral type too.
Re: Implicit encoding conversion on string ~= int ?
On Sunday, 23 June 2013 at 17:12:41 UTC, Marco Leise wrote: int b = 228; // CP850 value for 'ä'. Note: fits in a single byte! 228 (e4 in hex) is also the Unicode code point for ä, which is [195, 164] when encoded as UTF-8. see: http://www.utf8-chartable.de/unicode-utf8-table.pl?number=512utf8=dec While the number 228 would fit in a byte normally, utf-8 uses the high bits as markers that this is part of a multibyte sequence (this helps with ascii compatibility), so any code point 127 will always be a multibyte sequence in utf-8. see: http://en.wikipedia.org/wiki/UTF-8#Description
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On Sunday, 23 June 2013 at 16:28:56 UTC, Andrei Alexandrescu wrote: foreach(ln; stdin.byLine(KeepTerminator.yes)) { Yeah. Would be awesome if an Apache extension would make it trivial to write Web pages in D. Just use cgi or fastcgi, both are really easy to configure on apache (often needing nothing more than copying your executable into /cgi-bin/, or adding three lines to ,htaccess), and being separate processes, if you crash them it is no big deal. No need to do set up a reverse proxy or get your system administrator to load strange new Apache modules. Or if you are just playing, you can skip apache altogether and use a D http server, like my cgi.d and vibe.d both offer (vibe.d's scales way better but mine is simpler). But I kinda want to play with this now with shared libraries just for something to do so maybe I will.
Re: Implicit encoding conversion on string ~= int ?
Am Sun, 23 Jun 2013 19:12:21 +0200 schrieb Marco Leise marco.le...@gmx.de: Am Sun, 23 Jun 2013 18:37:16 +0200 schrieb bearophile bearophileh...@lycos.com: Adam D. Ruppe: char[] a; int b = 1000; a ~= b; the a ~= b is more like a ~= cast(dchar) b, and then dchar - char means it may be multibyte encoded, going from utf-32 to utf-8. No no no, this is not what happens. In my case it was: string a; int b = 228; // CP850 value for 'ä'. Note: fits in a single byte! a ~= b; Maybe it goes as follows: o compiler sees ~= to a string and becomes aware of wchar and dchar conversions to char o appended value is only checked for size (type and signedness are lost) and maps int to dchar o this dchar value is now checked for Unicode conformity and fails the test o the dchar value is now assumed to be Latin-1, Windows-1252 or similar and a conversion routine invoked o the dchar value is converted to utf-8 and... o appended as a multi-byte string to variable a. That still doesn't sound right to me thought. What if the dchar value is not valid Unicode AND = 256 ? Actually you were 100% right, Adam. I was distracted by the fact that the source was CP850. UTF-32 maps all of Latin-1 in a 1:1 correspondence and most of CP850 has the same code in Latin-1. So yes, all the compiler was doing is to append a dchar value. And with char/ubyte I do find it convenient to mix them without casting. E.g. if (someChar 0x80) and similar code. As confusing as it was for me, I agree with WONT FIX. -- Marco
Re: A little Go = Python story
I knew a little Go and then by chance had a look at Python. The similarities in syntax were striking. Because of the very quick build times, Go feels like a scripting language. However, it really falls short on OOP. Delegates in Go can mimic inheritance to some extend, but method overriding (aka virutal methods) remains impossible. I believe many Python/C++ developers won't pick Go due to its lack of OOP and more andvanced language features. Maybe as a scripting language or a languagee to write little tools or concurrent stuff. I think just being a modernized C is not enough. Even in systems programming people look for more advanced language constructs as in C++ or D. If it's about performance alone, you would just stick to C. Currently Go can compete in performance just with Java. To define a business case in spite of the simplicity of the language IMHO speed would have been to be quite better as in Java. Besides that thread multiplexing as in Go would also make a lot of sense in D. It already exists for Java (see http://hawtdispatch.fusesource.org/, https://github.com/lmax-exchange/disruptor). Maybe porting HawtDispatch to D can be done without having the approach in hatDispatch). -- Oliver
Re: memory allocation in dmd
On 6/23/2013 5:21 AM, dennis luehring wrote: Am 22.06.2013 23:41, schrieb Walter Bright: Compiling std.algorithm for unittests consumes all the memory on many machines. I've been looking into what is allocating all that memory, and it isn't so easy without adding instrumentation code anywhere. Anyone know of a convenient tool to do this on Linux? (valgrind just hangs, or at least I gave up on it after 6 hours) there are sometimes better tools on windows or commercials - you should try these http://www.softwareverify.com/cpp-memory.php - i like this one http://mtuner.net/ http://www.puredevsoftware.com/MemPro.htm all for memory leak detection, but also doing memory profiling Thanks!
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On 6/23/13 10:34 AM, Adam D. Ruppe wrote: Just use cgi or fastcgi, both are really easy to configure on apache (often needing nothing more than copying your executable into /cgi-bin/, or adding three lines to ,htaccess), and being separate processes, if you crash them it is no big deal. No need to do set up a reverse proxy or get your system administrator to load strange new Apache modules. We should do what php does, it was very successful. I assume it's a dynamic library. Or if you are just playing, you can skip apache altogether and use a D http server, like my cgi.d and vibe.d both offer (vibe.d's scales way better but mine is simpler). But I kinda want to play with this now with shared libraries just for something to do so maybe I will. Awesome! The more I think of it the more I get to the conclusion I should migrate my own website (www.erdani.com) to a 100% D toolchain. Andrei
DList (Was: What features of D are you using now which you thought you'd never goint to use?)
On 6/23/13 9:33 AM, monarch_dodra wrote: BTW, kind of off topic, but since we are talking about bidirectional ranges, and DList is the most relevant object: Do you think you would have time to review my DList fix? https://github.com/D-Programming-Language/phobos/pull/953 As Dmity said: are we all in agreement to pull this in before release? ; which was 6 months ago :/ I think its time we deal with DList's issues. LGTM modulo some nits. We should take a close look at all containers. Andrei
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On Sunday, 23 June 2013 at 17:34:52 UTC, Adam D. Ruppe wrote: Would be awesome if an Apache extension would make it trivial to write Web pages in D. Just use cgi or fastcgi, both are really easy to configure on apache (often needing nothing more than copying your executable into /cgi-bin/, or adding three lines to ,htaccess), and being separate processes, if you crash them it is no big deal. No need to do set up a reverse proxy or get your system administrator to load strange new Apache modules. Or if you are just playing, you can skip apache altogether and use a D http server, like my cgi.d and vibe.d both offer (vibe.d's scales way better but mine is simpler). Actually vibe.d embedded HTTP outperforms Apache. With high concurrency - a lot. I can see reasons for wanting to keep it behind reverse proxy like nginx, but Apache? I dream of the day this freaking monstrosity dies together with web app infrastructure it has developed. Please, don't help it survive with D module support. :(
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On Sunday, 23 June 2013 at 17:54:01 UTC, Andrei Alexandrescu wrote: On 6/23/13 10:34 AM, Adam D. Ruppe wrote: We should do what php does, it was very successful. I assume it's a dynamic library. And what reason behind this other than millions of lemmings can't be wrong? This approach is disaster when it comes to high load.
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On 6/23/13 11:04 AM, Dicebot wrote: On Sunday, 23 June 2013 at 17:54:01 UTC, Andrei Alexandrescu wrote: On 6/23/13 10:34 AM, Adam D. Ruppe wrote: We should do what php does, it was very successful. I assume it's a dynamic library. And what reason behind this other than millions of lemmings can't be wrong? This approach is disaster when it comes to high load. Would separate processes work better under high load? Educate me. Andrei
Re: SIMD on Windows
On 2013-06-23 15:33, Rainer Schuetze wrote: I have removed the dust from these patches and pushed them successfully through the test suite and unittests: https://github.com/rainers/dmd/tree/coff32 https://github.com/rainers/druntime/tree/coff32 https://github.com/rainers/phobos/tree/coff32 Compile dmd as usual, but druntime and phobos with something like druntime: make -f win64.mak MODEL=32ms CC=path-to-32bit-cl phobos: make -f win64.mak MODEL=32ms CC=path-to-32bit-cl AR=path-to-32bit-lib COFF32 files are generated when -m32ms is used on the command line. So, you have implemented support for COFF 32bit? How long have you been hiding this :) Although I'm not a Windows user I consider it great news. -- /Jacob Carlborg
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On Sunday, 23 June 2013 at 18:02:04 UTC, Dicebot wrote: I can see reasons for wanting to keep it behind reverse proxy like nginx, but Apache? Generally, I don't trust random http servers connected to the open internet for correctness, stability, security, and logging. Especially not my code, There's a lot of the http protocol I never implemented, and putting apache, nginx, IIS, whatever, I'm just using Apache here because Andrei mentioned it, out in front will filter some of that out before it gets to my app. And who knows what kinds of hidden bugs my code has, so having a tested and reliable server out there to revive my process if it dies is nice too.
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On Sunday, 23 June 2013 at 18:24:05 UTC, Andrei Alexandrescu wrote: Would separate processes work better under high load? Educate me. One nice thing is you can spread separate processes across several machines. Another advantage of *cgi|embedded_httpd is that it is portable to other web servers too, you can just drop it into a shop that uses nginx or Microsoft IIS and expect it to work, whereas an Apache module is generally apache only. I think it is just an accident of history that mod_php ever got used. Classic cgi implementations were still slow enough (especially with an interpreted language) that people wanted to try something else, but the other world of options hadn't taken root yet either (I think mod_php even slightly predates fastcgi's introduction), and continues to exist just out of inertia.
Re: Today's github tip - fixing local master
On 06/18/2013 09:41 PM, Walter Bright wrote: I often struggle with understanding how github works. A problem I was having often is that I have 3 repositories to deal with: IMHO it's much easier to understand git from bottom up. Git is based on a very simple object model. It only knows 4 types Blob, Tree, Commit and Tag. http://git-scm.com/book/en/Git-Internals-Git-Objects With that you can think of any constellation in terms of commit diagrams like these http://git-scm.com/book/ch3-6.html. And the last bit is to understand what git commands actually do. This is the problematic part of git. Some commands do basic operations others do more complicated stuff. The later usually have gotchas one needs to be aware of. I personally found that using explicit and more verbose commands was helpful to learn git faster. 1. the main one on github (upstream) 2. my github fork of the main one (origin) 3. my local git repository and (2) and (3) got out of sync with (1), causing all my pull requests to go bonkers. What I needed was a fix (2) and (3) so their masters are identical to (1)'s master. Various attempts at fixing it all failed in one way or another, often with mysterious messages, and cost me a lot of time. I never use my remote master branch (origin). What do you need it for? yebblies (Daniel Murphy) provided the solution, which is nicely generic: git checkout master git fetch upstream master git reset --hard FETCH_HEAD git push origin master -f So there it is if anyone else has this problem. I also tend to prefer the explicit fetch and rebase or reset over pull because what git pull does depends on your .gitconfig.
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
BTW I should mention, I wasn't actually trying to do an Apache module. I wanted to do a D server that watches the files for changes, then recompiles them as needed and reloads the resulting file as a shared lib. I could just run the compiled executable too, cgi style, but here I was more interested in playing with shared libraries than just getting it to work.
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On Sunday, 23 June 2013 at 17:54:01 UTC, Andrei Alexandrescu wrote: I assume it's a dynamic library. PHP can work as fastcgi too. But I kinda want to play with this now with shared libraries just for something to do so maybe I will. Awesome! Eh, not so much. I started playing and got a thing saying Runtime.loadLibrary is not yet implemented on posix... so went to do it myself and got random segfaults, relating to the garbage collector (and yes, I tried Runtime.initialize). I've never done a shared library plugin before so I could be doing something wrong, but it seems to me that druntime said it wasn't implemented yet for a reason, must still have some work to do there. Oh well, maybe I'll try again next release.
Re: TDD is BS?
Am 20.06.2013 11:26, schrieb Jacob Carlborg: On 2013-06-20 00:13, Paulo Pinto wrote: The issue is not to test third party libraries, far from it. The problem is that you cannot mock them, specially if you rely a lot on non virtual methods or pure function calls. Or on framework code that calls your code back, after certain events happened in the system. I would only mock an external service that needs to be available online. I don't mock third party code. That would be insane. There's no limit. Should I mock the standard library? No, but if your code calls something that ends up calling again other part of your code, you might need to mock it somehow. Specially if it is a library that does some IO (network, disk) in the process and is full of static methods. -- Paulo
Re: SIMD on Windows
Cool))) Any chances to see it [coff32] in official build?
Re: TDD is BS?
On 2013-06-23 21:50, Paulo Pinto wrote: No, but if your code calls something that ends up calling again other part of your code, you might need to mock it somehow. I'm using same approach there. If I'm testing method a and it also calls method b. I assume method b works and I don't mock it. Then I make sure to have a test for method b as well. A given test only tests one method. Specially if it is a library that does some IO (network, disk) in the process and is full of static methods. Especially network IO is a good idea to mock. -- /Jacob Carlborg
fun project - improving calcHash
https://github.com/D-Programming-Language/dmd/blob/master/src/root/stringtable.c#L21 Profiling shows the calcHash function is a significant contributor to compilation time (3.25% of total time). So making it faster is a win. Even making dmd 1% faster would be a nice win - all those little drops add up. There are many, many string hash functions findable through google. Anyone want to spend the effort to make a faster one? Remember, ya gotta prove it's faster! A nice timing test would be the time expending compiling Phobos. I would suggest that the 64 bit build of dmd be used for timing tests. Also, be careful, many of those hash functions on the intarnets have a license that makes it unusable for dmd.
Re: What features of D are you using now which you thought you'd never goint to use?
On 06/23/2013 01:34 PM, monarch_dodra wrote: ... But as soon as you need an algorithm that actually *handles* ranges: swaps them, merges them, searches in them and splices them, then things get hairy. For example, try implementing a sort (either merge or q) with a non-sliceable range... very very hard... Challenge accepted. http://dpaste.dzfl.pl/4407c36f
top time wasters in DMD, as reported by gprof
Flat profile: Each sample counts as 0.01 seconds. % cumulative self self total time seconds secondscalls ms/call ms/call name 5.19 0.08 0.08 945494 0.00 0.00 _aaGetRvalue(AA*, void*) 3.90 0.14 0.06 926415 0.00 0.00 Lexer::scan(Token*) 3.25 0.19 0.05 397097 0.00 0.00 calcHash(char const*, unsigned long) 2.60 0.23 0.04 373646 0.00 0.00 StringTable::search(char const*, unsigned lon 1.95 0.26 0.0333255 0.00 0.00 TemplateInstance::semantic(Scope*, ArrayExpr 1.30 0.28 0.02 968985 0.00 0.00 ScopeDsymbol::search(Loc, Identifier*, int) 1.30 0.30 0.02 424079 0.00 0.00 calccodsize 1.30 0.32 0.02 234547 0.00 0.00 Parser::parseShiftExp() 1.30 0.34 0.02 168933 0.00 0.00 AliasDeclaration::toAlias() 1.30 0.36 0.02 136371 0.00 0.00 _aaGet(AA**, void*) 1.30 0.38 0.02 132102 0.00 0.00 TypeStruct::hasPointers() 1.30 0.40 0.0232490 0.00 0.00 TemplateDeclaration::matchWithInstance(Templa 1.30 0.42 0.0221666 0.00 0.00 FuncDeclaration::functionSemantic() 1.30 0.44 0.0217983 0.00 0.00 VarDeclaration::syntaxCopy(Dsymbol*) 1.30 0.46 0.0212908 0.00 0.00 TemplateDeclaration::deduceFunctionTemplateMa 1.30 0.48 0.02 6890 0.00 0.00 assignaddrc 1.30 0.50 0.02 6563 0.00 0.00 ecom(elem**) 1.30 0.52 0.02 5675 0.00 0.00 TypeInfo_Idxstr::getHash(void*) 1.30 0.54 0.02 3780 0.01 0.01 TemplateDeclaration::semantic(Scope*) 1.30 0.56 0.02 2648 0.01 0.01 operator delete(void*) 0.97 0.58 0.0242592 0.00 0.00 IdentifierExp::semantic(Scope*) 0.97 0.59 0.0236403 0.00 0.00 BinExp::syntaxCopy() 0.65 0.60 0.01 2668529 0.00 0.00 operator new(unsigned long) 0.65 0.61 0.01 2575503 0.00 0.00 Dsymbol::isTemplateMixin() 0.65 0.62 0.01 2310757 0.00 0.00 Type::toBasetype() 0.65 0.63 0.01 2096689 0.00 0.00 OutBuffer::reserve(unsigned long) 0.65 0.64 0.01 1030635 0.00 0.00 Dsymbol::isTemplateInstance() 0.65 0.65 0.01 708615 0.00 0.00 Module::search(Loc, Identifier*, int) 0.65 0.66 0.01 683509 0.00 0.00 VarDeclaration::isDataseg() 0.65 0.67 0.01 662180 0.00 0.00 Module::isModule() 0.65 0.68 0.01 567921 0.00 0.00 isType(RootObject*) 0.65 0.69 0.01 536331 0.00 0.00 Mem::realloc(void*, unsigned long) 0.65 0.70 0.01 454836 0.00 0.00 Parameter::foreach(ArrayParameter*, int (*) 0.65 0.71 0.01 375732 0.00 0.00 Type::merge() 0.65 0.72 0.01 353615 0.00 0.00 Mem::free(void*) 0.65 0.73 0.01 348546 0.00 0.00 isDsymbol(RootObject*) 0.65 0.74 0.01 339336 0.00 0.00 exceptionOrCantInterpret(Expression*) 0.65 0.75 0.01 311493 0.00 0.00 isTuple(RootObject*) 0.65 0.76 0.01 300069 0.00 0.00 TypeBasic::isscalar() 0.65 0.77 0.01 270438 0.00 0.00 VarDeclaration::hasPointers() 0.65 0.78 0.01 248163 0.00 0.00 Identifier::equals(RootObject*) 0.65 0.79 0.01 234806 0.00 0.00 Parser::parseAddExp()
Re: fun project - improving calcHash
On 06/23/2013 11:22 PM, Walter Bright wrote: https://github.com/D-Programming-Language/dmd/blob/master/src/root/stringtable.c#L21 Profiling shows the calcHash function is a significant contributor to compilation time (3.25% of total time). So making it faster is a win. Even making dmd 1% faster would be a nice win - all those little drops add up. There are many, many string hash functions findable through google. Anyone want to spend the effort to make a faster one? Remember, ya gotta prove it's faster! ... It seems to be easy to make it faster without changing the algorithm significantly. There should be only one switch executed, not one per 4 characters. If the length is short enough from the start, there is no point in doing any arithmetic.
Re: proposal: lazy compilation model for compiling binaries
On 06/22/2013 11:20 AM, Dicebot wrote: D has export keyword that I always expected to do exactly this until have found out it is actually platform-dependent and useless. It's buggy and useful. http://d.puremagic.com/issues/show_bug.cgi?id=9816 We should try to strive for -fvisibility=hidden on UNIX because it allows to optimize non-exported symbols and because we need explicit exports for anyhow.
Re: fun project - improving calcHash
On 06/23/2013 06:22 PM, Walter Bright wrote: https://github.com/D-Programming-Language/dmd/blob/master/src/root/stringtable.c#L21 Profiling shows the calcHash function is a significant contributor to compilation time (3.25% of total time). So making it faster is a win. Even making dmd 1% faster would be a nice win - all those little drops add up. There are many, many string hash functions findable through google. Anyone want to spend the effort to make a faster one? Remember, ya gotta prove it's faster! A nice timing test would be the time expending compiling Phobos. I would suggest that the 64 bit build of dmd be used for timing tests. Also, be careful, many of those hash functions on the intarnets have a license that makes it unusable for dmd. I performed a quick test, and I don't think that the original function can be improved for speed (though it might be improved for less collisions): https://gist.github.com/jmcabo/5847036 I used words and lines from the complete works of Shakespeare. I tested separating the loop from the switch, as was suggested in Timon Gehr post. It didn't improve the speed when compiled with g++ -O3, though it improved it a bit without -O3. I also tested removing the multiplication by 37. It didn't improve the speed. With g++ -O3 they are all the same. So, unless I'm measuring it wrong, the algorithm is as fast as can be (as fast as just adding chars). --jm
Re: proposal: lazy compilation model for compiling binaries
On 06/22/2013 06:45 AM, Timothee Cour wrote: Example2: auto foo(){return import std.stdio;;} mixin(foo); void fun2(){import b;} void main(){writeln(ok);} lazy semantic analysis will analyze main, foo but not fun2, which is not used. foo is analyzed because it is used in a module-level mixin declaration. Overall it's a good idea. There are already some attempts to shift to lazy semantic analysis, mainly to solve any remaining forward reference issues. Also for non-optimized builds parsing takes a huge part of the compilation time so that would remain, I don't have detailed numbers though.
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On Sunday, 23 June 2013 at 17:54:01 UTC, Andrei Alexandrescu wrote: Awesome! I realized initializing the runtime might have been a mistake when loading the .so and moreover I was using the wrong calling convention. Fixed that and now the shared library thing works. On Linux at least, I hardcoded .so so don't try it anywhere else. Here's some code: http://arsdnet.net/dcode/dhp.zip unzip it, hit make. dhp2.d is the main file here, it also uses some helper libraries you can see in the arsd folder. Then run ./dhp2 in another window or something. It is a long running process that serves http. Head over to your browser and surf to http://localhost:8085/ It will take a couple seconds to load the first time, because it needs to compile the code. Subsequent loads will pull it from a cache and be faster. Anyway it will show you some stuff and a link. These pull from the files in the zip called index.dhp and dhpt.dhp. index is just html, no D code, although it will compile it since this server compiles everything. dhpt.dhp actually includes some D: pHello, % cgi.write(cgi.request(name, user)); %, happy to see you./p Note: you access that by going to localhost:8085/dhpt, NOT /dhpt.dhp. It strips out dots from the url as a way of sanitizing the filename so keep it simple. It uses ASP style % % tags instead of ?d ? because my dom.d already understands them. (BTW this parses the .dhp files to be well-formed xml, so if you mismatch tags, it will throw. It might be fun to put the DOM node in scope to inspect too). There's a Cgi cgi in scope in the function it builds here. Use it to do communication instead of writeln() etc., as seen in this example. Here's where the shared library magic comes in: feel free to edit one of those .dhp files, or create your own, and go back to it in the browser. It will recompile and present it to you without having to restart the server. That's kinda cool. The downside is if you segfault in here it will take the whole server down so don't do that. If you fail compiling though, it will actually read dmd's output and translate the filename and line number to match the .dhp file input, instead of the .d file dmd actually sees. So it feels less like a filthy hack then. Feel free to look at index.d and dhpt.d in that same folder after you browse to them to see what the generated code looks like. S yeah. I'll probably never use this, dom templates rok so much more than anything asp/php style, but if you wanna play, feel free and let me know if you want more features or see bugs. Probably won't be too hard to fix up now that it is started.
Re: Implicit encoding conversion on string ~= int ?
On Sunday, June 23, 2013 19:25:41 Adam D. Ruppe wrote: On Sunday, 23 June 2013 at 16:37:18 UTC, bearophile wrote: I didn't know that, is this already in Bugzilla? I don't know, but if it is, it is probably marked as won't fix because I'm pretty sure this has come up before, but it is actually by design because a char in C is considered an integral type too. This is definitely by design. Walter is definitely in the camp that thinks that chars are integral types, so they follow all of the various integral conversion rules. In some cases this is nice. In others, it's bug-prone, but I think that we're stuck with it regardless of whether it's ultimately a good idea or not. I don't think that we even succeeded at coming close to convincing Walter that _bool_ isn't an integral type and shouldn't be treated as such (when it was discussed right before deconf), and that should be a far more clearcut case. - Jonathan M Davis
pull/1367: new std.traits templates: isSame, isSameTypleTuple, GetTemplateParent, GetTemplateArguments, isTemplateInstantiation
https://github.com/D-Programming-Language/phobos/pull/1367 comments welcome.
Re: fun project - improving calcHash
On 06/23/2013 11:22 PM, Walter Bright wrote: Profiling shows the calcHash function is a significant contributor to compilation time (3.25% of total time). So making it faster is a win. Even making dmd 1% faster would be a nice win - all those little drops add up. You'll find a benchmark at the end of the post. http://forum.dlang.org/thread/op.v2yky9pdsqu...@dawg-freebsd.lan Obviously the switch in a for loop is a branch prediction killer. This should work much better. for (size_t i = 0; i len / 4; ++i) { hash *= 37; hash += *(const uint32_t *)str; str += 4; } switch (len 3) { case 0: break; case 1: hash *= 37; hash += *(const uint8_t *)str; break; case 2: hash *= 37; hash += *(const uint16_t *)str; break; case 3: hash *= 37; hash += (*(const uint16_t *)str 8) + ((const uint8_t *)str)[2]; break; default: assert(0); } return hash; Finding a faster hash algorithm isn't simple because prime multiplication is so simple. At least we're not diving the hash result by 37 any longer. I think using the Hsieh hash is a good choice because it has quite an OK distribution so it leads to fewer collisions. It's also pretty fast for short strings and we already use it in druntime.
Re: proposal: lazy compilation model for compiling binaries
On 06/24/2013 02:23 AM, Martin Nowak wrote: exports for anyhow. for Windows that is
Re: fun project - improving calcHash
On 06/23/2013 09:20 PM, Juan Manuel Cabo wrote: On 06/23/2013 06:22 PM, Walter Bright wrote: https://github.com/D-Programming-Language/dmd/blob/master/src/root/stringtable.c#L21 Profiling shows the calcHash function is a significant contributor to compilation time (3.25% of total time). So making it faster is a win. Even making dmd 1% faster would be a nice win - all those little drops add up. There are many, many string hash functions findable through google. Anyone want to spend the effort to make a faster one? Remember, ya gotta prove it's faster! A nice timing test would be the time expending compiling Phobos. I would suggest that the 64 bit build of dmd be used for timing tests. Also, be careful, many of those hash functions on the intarnets have a license that makes it unusable for dmd. I performed a quick test, and I don't think that the original function can be improved for speed (though it might be improved for less collisions): https://gist.github.com/jmcabo/5847036 I used words and lines from the complete works of Shakespeare. I tested separating the loop from the switch, as was suggested in Timon Gehr post. It didn't improve the speed when compiled with g++ -O3, though it improved it a bit without -O3. I also tested removing the multiplication by 37. It didn't improve the speed. With g++ -O3 they are all the same. So, unless I'm measuring it wrong, the algorithm is as fast as can be (as fast as just adding chars). --jm Oh, it might be improved by loading 128bits at a time instead of 32bits... but that would benefit strings of more than 16 bytes. Google's CitiHash seems tuned for large strings. --jm
Re: proposal: lazy compilation model for compiling binaries
On Sun, Jun 23, 2013 at 5:36 PM, Martin Nowak c...@dawg.eu wrote: On 06/22/2013 06:45 AM, Timothee Cour wrote: Example2: auto foo(){return import std.stdio;;} mixin(foo); void fun2(){import b;} void main(){writeln(ok);} lazy semantic analysis will analyze main, foo but not fun2, which is not used. foo is analyzed because it is used in a module-level mixin declaration. Overall it's a good idea. There are already some attempts to shift to lazy semantic analysis, mainly to solve any remaining forward reference issues. Also for non-optimized builds parsing takes a huge part of the compilation time so that would remain, I don't have detailed numbers though. why 'that would remain' ? in the proposed lazy compilation model, optimization level is irrelevant. The only thing that matters is whether we have to export all symbols or only specified ones. I agree we should require marking those explicitly with 'export' on all platforms, not just windows. But in doing so we must allow to define those exported symbols outside of where they're defined, otherwise it will make code ugly (eg, what if we want to export std.process.kill in a user shared library and std.process.kill isn't marked as export) Here's a possibility module define_exported_symbols; import std.process; export std.process.kill; //export all std.process.kill overloads (just 1 function in this case) export std.process; //export all functions in std.process export std; //export all functions in std But I think the best is to keep the current export semantics (but make it work on all platforms not just windows) and provide library code to help with exporting entire modules/packages: module std.sharedlib; //helper functions for dlls on all platforms void export_module(alias module_)(module_ mymodule){ } void export_symbols(R) (R symbols) if(isInputRange!R){//export a range of symbols } /+ usage: export_module(std.process); //exports all functions in std.process export_symbols(enumerateFunctions(std.process)); //exports all functions in std.process; allows to be more flexible by exporting only a subset of those +/
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On 6/23/13 11:51 AM, Adam D. Ruppe wrote: I think it is just an accident of history that mod_php ever got used. Classic cgi implementations were still slow enough (especially with an interpreted language) that people wanted to try something else, but the other world of options hadn't taken root yet either (I think mod_php even slightly predates fastcgi's introduction), and continues to exist just out of inertia. OK so what's the way to go now? One process per request? Seems heavy to me seeing as most requests last very little. Andrei
Re: top time wasters in DMD, as reported by gprof
can you give more context ? what was the command line to get this? I thought lexing was not a bottleneck, yet it seems to be in second place? On Sun, Jun 23, 2013 at 2:28 PM, Walter Bright newshou...@digitalmars.comwrote: Flat profile: Each sample counts as 0.01 seconds. % cumulative self self total time seconds secondscalls ms/call ms/call name 5.19 0.08 0.08 945494 0.00 0.00 _aaGetRvalue(AA*, void*) 3.90 0.14 0.06 926415 0.00 0.00 Lexer::scan(Token*) 3.25 0.19 0.05 397097 0.00 0.00 calcHash(char const*, unsigned long) 2.60 0.23 0.04 373646 0.00 0.00 StringTable::search(char const*, unsigned lon 1.95 0.26 0.0333255 0.00 0.00 TemplateInstance::semantic(**Scope*, ArrayExpr 1.30 0.28 0.02 968985 0.00 0.00 ScopeDsymbol::search(Loc, Identifier*, int) 1.30 0.30 0.02 424079 0.00 0.00 calccodsize 1.30 0.32 0.02 234547 0.00 0.00 Parser::parseShiftExp() 1.30 0.34 0.02 168933 0.00 0.00 AliasDeclaration::toAlias() 1.30 0.36 0.02 136371 0.00 0.00 _aaGet(AA**, void*) 1.30 0.38 0.02 132102 0.00 0.00 TypeStruct::hasPointers() 1.30 0.40 0.0232490 0.00 0.00 TemplateDeclaration:: **matchWithInstance(Templa 1.30 0.42 0.0221666 0.00 0.00 FuncDeclaration::** functionSemantic() 1.30 0.44 0.0217983 0.00 0.00 VarDeclaration::syntaxCopy(**Dsymbol*) 1.30 0.46 0.0212908 0.00 0.00 TemplateDeclaration:: **deduceFunctionTemplateMa 1.30 0.48 0.02 6890 0.00 0.00 assignaddrc 1.30 0.50 0.02 6563 0.00 0.00 ecom(elem**) 1.30 0.52 0.02 5675 0.00 0.00 TypeInfo_Idxstr::getHash(void***) 1.30 0.54 0.02 3780 0.01 0.01 TemplateDeclaration::semantic(**Scope*) 1.30 0.56 0.02 2648 0.01 0.01 operator delete(void*) 0.97 0.58 0.0242592 0.00 0.00 IdentifierExp::semantic(Scope***) 0.97 0.59 0.0236403 0.00 0.00 BinExp::syntaxCopy() 0.65 0.60 0.01 2668529 0.00 0.00 operator new(unsigned long) 0.65 0.61 0.01 2575503 0.00 0.00 Dsymbol::isTemplateMixin() 0.65 0.62 0.01 2310757 0.00 0.00 Type::toBasetype() 0.65 0.63 0.01 2096689 0.00 0.00 OutBuffer::reserve(unsigned long) 0.65 0.64 0.01 1030635 0.00 0.00 Dsymbol::isTemplateInstance() 0.65 0.65 0.01 708615 0.00 0.00 Module::search(Loc, Identifier*, int) 0.65 0.66 0.01 683509 0.00 0.00 VarDeclaration::isDataseg() 0.65 0.67 0.01 662180 0.00 0.00 Module::isModule() 0.65 0.68 0.01 567921 0.00 0.00 isType(RootObject*) 0.65 0.69 0.01 536331 0.00 0.00 Mem::realloc(void*, unsigned long) 0.65 0.70 0.01 454836 0.00 0.00 Parameter::foreach(Array**Parameter*, int (*) 0.65 0.71 0.01 375732 0.00 0.00 Type::merge() 0.65 0.72 0.01 353615 0.00 0.00 Mem::free(void*) 0.65 0.73 0.01 348546 0.00 0.00 isDsymbol(RootObject*) 0.65 0.74 0.01 339336 0.00 0.00 exceptionOrCantInterpret(**Expression*) 0.65 0.75 0.01 311493 0.00 0.00 isTuple(RootObject*) 0.65 0.76 0.01 300069 0.00 0.00 TypeBasic::isscalar() 0.65 0.77 0.01 270438 0.00 0.00 VarDeclaration::hasPointers() 0.65 0.78 0.01 248163 0.00 0.00 Identifier::equals(RootObject***) 0.65 0.79 0.01 234806 0.00 0.00 Parser::parseAddExp()
Re: fun project - improving calcHash
On Sun, Jun 23, 2013 at 2:22 PM, Walter Bright newshou...@digitalmars.comwrote: https://github.com/D-**Programming-Language/dmd/blob/** master/src/root/stringtable.c#**L21https://github.com/D-Programming-Language/dmd/blob/master/src/root/stringtable.c#L21 Profiling shows the calcHash function is a significant contributor to compilation time (3.25% of total time). So making it faster is a win. Even making dmd 1% faster would be a nice win - all those little drops add up. There are many, many string hash functions findable through google. Anyone want to spend the effort to make a faster one? Remember, ya gotta prove it's faster! A nice timing test would be the time expending compiling Phobos. I would suggest that the 64 bit build of dmd be used for timing tests. Also, be careful, many of those hash functions on the intarnets have a license that makes it unusable for dmd. implementing this proposal: lazy compilation model for compiling binaries http://forum.dlang.org/post/mailman.1357.1371876331.13711.digitalmar...@puremagic.com would have much larger impact on compile time performance.
Re: top time wasters in DMD, as reported by gprof
On 6/23/2013 8:39 PM, Timothee Cour wrote: can you give more context ? what was the command line to get this? Compile on Linux with -pg. Run with: dmd -main -unittest std/algorithm I thought lexing was not a bottleneck, yet it seems to be in second place? The fun with profilers is they tell you things you didn't think were true.
Re: top time wasters in DMD, as reported by gprof
On Sun, Jun 23, 2013 at 8:55 PM, Walter Bright newshou...@digitalmars.comwrote: On 6/23/2013 8:39 PM, Timothee Cour wrote: can you give more context ? what was the command line to get this? Compile on Linux with -pg. Run with: dmd -main -unittest std/algorithm I thought lexing was not a bottleneck, yet it seems to be in second place? The fun with profilers is they tell you things you didn't think were true. more profiliing numbers from Ian Buclaw, for gdc: http://forum.dlang.org/post/mailman.1469.1339580395.24740.digitalmar...@puremagic.com http://iainbuclaw.wordpress.com/2010/09/18/implementing-speed-counters-in-gdc/ http://iainbuclaw.files.wordpress.com/2010/09/d2-time-report2.pdf That cam up in an old proposal i made a year ago: AST files instead of DI interface files for faster compilation and easier distribution.
Re: Implicit encoding conversion on string ~= int ?
Am Sun, 23 Jun 2013 17:50:01 -0700 schrieb Jonathan M Davis jmdavisp...@gmx.com: I don't think that we even succeeded at coming close to convincing Walter that _bool_ isn't an integral type and shouldn't be treated as such (when it was discussed right before deconf), and that should be a far more clearcut case. - Jonathan M Davis You can take bool to int promotion out of my... // best way to toggle forth and back between 0 and 1. ! returns a bool. value = !value // don't ask, I've seen this :) arr[someBool] // sometimes the bool has just the value you need length -= boolRemoveTerminator -- Marco
Re: Implicit encoding conversion on string ~= int ?
On Monday, June 24, 2013 07:20:10 Marco Leise wrote: Am Sun, 23 Jun 2013 17:50:01 -0700 schrieb Jonathan M Davis jmdavisp...@gmx.com: I don't think that we even succeeded at coming close to convincing Walter that _bool_ isn't an integral type and shouldn't be treated as such (when it was discussed right before deconf), and that should be a far more clearcut case. - Jonathan M Davis You can take bool to int promotion out of my... // best way to toggle forth and back between 0 and 1. ! returns a bool. value = !value // don't ask, I've seen this :) arr[someBool] // sometimes the bool has just the value you need length -= boolRemoveTerminator And in all those cases, you can cast to int to get the value you want. The case that brought up the big discussion on it a couple of months ago was when you had auto foo(bool b) {...} auto foo(long l) {...} Which one does foo(1) call? It calls the bool version, because of how the integer conversion rules work. IMHO, this is _very_ broken, but Walter's response is that the solution is to add the overload auto foo(int i) {...} And that does fix the code in question, but it means that bool is _not_ strongly typed in D, and you get a variety of weird cases that cause bugs because of such implicit conversions. I would strongly argue that the case where you want bool to act like an integer is by far the rarer case and that casting fixes that problem nicely. Plenty of others agree with me. But no one has been able to convince Walter. You can read the thread here: http://forum.dlang.org/post/klc5r7$3c4$1...@digitalmars.com - Jonathan M Davis
Re: OT: CS education gone wrong (Was: Re: TDD is BS?)
On Monday, 24 June 2013 at 02:39:30 UTC, Andrei Alexandrescu wrote: On 6/23/13 11:51 AM, Adam D. Ruppe wrote: I think it is just an accident of history that mod_php ever got used. Classic cgi implementations were still slow enough (especially with an interpreted language) that people wanted to try something else, but the other world of options hadn't taken root yet either (I think mod_php even slightly predates fastcgi's introduction), and continues to exist just out of inertia. OK so what's the way to go now? One process per request? Seems heavy to me seeing as most requests last very little. That is what apache used to do when mod_php was introduced anyway. This whole conversation has gone out of control :D mod_php was a way to reduce the communication overhead and avoid 2 process per request in the first place (instead of one). It become plain obvious that no silver bullet exists here. The solution seems to be a mix of fibers/threads and processes where number of each depends on your workload and the actual hardware it is running on. Most high performance and high scalability system are converging toward one flavor of that pattern.
Re: fun project - improving calcHash
https://code.google.com/p/xxhash/ BSD 2-Clause License
Re: alias c=mixin(expr); disallowed, why?
On 2013-06-22 23:47, Timon Gehr wrote: No, it is arbitrary. I think the spec says you can only mixin whole expression. But for some reason you can use a mixin in a __traits expression without having the whole expression in a mixin. -- /Jacob Carlborg
Re: Can call static method with null reference
On 2013-06-22 23:51, Timon Gehr wrote: If that is the only problem then the solution is to allow overloading on static, which is easy to do. You still need to call the static method on the class/struct if there's an ambiguity. -- /Jacob Carlborg
Good Candy Doc Forks?
Does anybody know some good looking or with good features? btw, I'm wondering why is some basic version of Candy Doc bundled with DMD. Thanks.
Re: Can call static method with null reference
On Sunday, June 23, 2013 11:30:11 Jacob Carlborg wrote: On 2013-06-22 23:51, Timon Gehr wrote: If that is the only problem then the solution is to allow overloading on static, which is easy to do. You still need to call the static method on the class/struct if there's an ambiguity. I would have thought that that was obvious, and I fail to see why that would be a problem. The only risk I see in allowing static and non-static functions to be overloaded, is that if you have static function being called with an instance, and you add a non-static overload, then the code would silently change to call the non-static function. But we have that exact same problem with UFCS and member functions as it is, and that wouldn't break any existing code (since you can't overload on static right now). It would just be a future risk of breaking code. - Jonathan M Davis
Re: Can call static method with null reference
I don't see what's so terrible about it It's bug prone. class Foo { public: static void test1() { } void test2() { } } Foo f; f.test1(); /// Oh nice, that works, f is not null. f.test2(); /// WTF? f is null? Also I don't know why I should call static methods from an instance. What's the purpose?
Re: Can call static method with null reference
On Sunday, June 23, 2013 12:02:42 Namespace wrote: I don't see what's so terrible about it It's bug prone. class Foo { public: static void test1() { } void test2() { } } Foo f; f.test1(); /// Oh nice, that works, f is not null. f.test2(); /// WTF? f is null? I fail to see what's bug-prone about that. It's confusing, but it's not causing any bugs. Also I don't know why I should call static methods from an instance. What's the purpose? It's stupid and pointless as far as I can tell, but I believe that C++, Java, C#, and D all do it, so as stupid as it is, it's a common stupidity. I certainly wish that we could change it, but I wouldn't expect Walter to agree to the change, since it would break at least some existing code, and I suspect that he doesn't consider the fact that you can call static functions on instances to be a problem. That's not the sort of thing that he generally seems to think is an issue. It's almost always stuff that causes actual bugs that he agrees to change and not things that are aesthetically displeasing or which could theoretically cause bugs. - Jonathan M Davis
Re: alias c=mixin(expr); disallowed, why?
On 06/22/13 21:52, Timothee Cour wrote: Is there a reason the language spec disallows this? void main(){ auto a=mixin(1);//OK alias b=a;//OK mixin(alias c=a;);//OK // alias c=mixin(a);//NG : Error: basic type expected, not mixin } How would that be different from auto c=mixin(a);? It's probably clear, but that error message is misleading, so i'll say it anyway - the reason why your 'alias' line does not work is because alias requires a symbol, but 'mixin()' is an expression. Special-casing mixin-expressions (so that they propagate the symbol when that is possible would be a bad idea); the other possibility is to allow aliasing /expressions/. But that's a bad idea too, and would likely not do what you expect it to do. A mixin-less version could be made to work, but there are already other ways to get the same effect. Hence the above question. artur
Re: Can call static method with null reference
On Sunday, 23 June 2013 at 10:09:39 UTC, Jonathan M Davis wrote: On Sunday, June 23, 2013 12:02:42 Namespace wrote: I don't see what's so terrible about it It's bug prone. class Foo { public: static void test1() { } void test2() { } } Foo f; f.test1(); /// Oh nice, that works, f is not null. f.test2(); /// WTF? f is null? I fail to see what's bug-prone about that. It's confusing, but it's not causing any bugs. Also I don't know why I should call static methods from an instance. What's the purpose? It's stupid and pointless as far as I can tell, but I believe that C++, Java, C#, and D all do it, so as stupid as it is, it's a common stupidity. I certainly wish that we could change it, but I wouldn't expect Walter to agree to the change, since it would break at least some existing code, and I suspect that he doesn't consider the fact that you can call static functions on instances to be a problem. That's not the sort of thing that he generally seems to think is an issue. It's almost always stuff that causes actual bugs that he agrees to change and not things that are aesthetically displeasing or which could theoretically cause bugs. - Jonathan M Davis C++ doesn't allow it. I don't know about the rest. If anything, I find overloading static non static could make sense: A.print(); //I'm an A! a.print(); //I'm an A called foo! With this in mind, it can mean that a struct can first define the static function, and in the future, add extra logic to handle information from a specific instance, yet without having to caller code.
Re: Can call static method with null reference
On Sunday, June 23, 2013 12:48:15 monarch_dodra wrote: C++ doesn't allow it. I don't know about the rest. Yes it does. I just tested it. This code compiles and runs just fine #include iostream using namespace std; class C { public: static void foo() { cout I'm static! endl; } }; int main() { C c; c.foo(); return 0; } And just like D, C++ won't allow you to overload on static (also just tested), so D's behavior in this regard appears to be identical to C++. - Jonathan M Davis
InstanceOf
I'm trying to create a fairly generic component system, where an object iterates over a bunch of other objects that all implement a certain interface. And this all works fine, however, I would also like to be able to get objects of a specific type (a la instanceOf), and I can't figure out how to do it. Could anyone help me out? [code] interface I { void update(); void write(); } class A : I { int n; void update() { n++; } void write() { writeln(n); } } class B : I { int m; void update() { m--; } void write() { writeln(m); } } class C { I[] array; void addElem(I elem) { array ~= elem; } void loop() { foreach(elem; array) elem.update(); } void writeAll() { foreach(elem; array) elem.write(); } void writeB() { // Only call .write on B's // How do I get the B's from the array of I's? } } void main() { C c = new C(); c.addElem(new A()); c.addElem(new B()); c.loop(); c.writeAll(); c.writeB(); // This is the problem } [/code]
Re: InstanceOf
On Sunday, 23 June 2013 at 11:04:59 UTC, Lemonfiend wrote: I'm trying to create a fairly generic component system, where an object iterates over a bunch of other objects that all implement a certain interface. And this all works fine, however, I would also like to be able to get objects of a specific type (a la instanceOf), and I can't figure out how to do it. Could anyone help me out? [code] interface I { void update(); void write(); } class A : I { int n; void update() { n++; } void write() { writeln(n); } } class B : I { int m; void update() { m--; } void write() { writeln(m); } } class C { I[] array; void addElem(I elem) { array ~= elem; } void loop() { foreach(elem; array) elem.update(); } void writeAll() { foreach(elem; array) elem.write(); } void writeB() { // Only call .write on B's // How do I get the B's from the array of I's? } } void main() { C c = new C(); c.addElem(new A()); c.addElem(new B()); c.loop(); c.writeAll(); c.writeB(); // This is the problem } [/code] foreach (I i; array) { if (B b = cast(B) i) { ... } }
Re: Can call static method with null reference
On Sunday, 23 June 2013 at 10:59:06 UTC, Jonathan M Davis wrote: On Sunday, June 23, 2013 12:48:15 monarch_dodra wrote: C++ doesn't allow it. I don't know about the rest. Yes it does. - Jonathan M Davis Oh. Wow. That's news to me actually. I thought I new everything about C++ ^^
Re: Good Candy Doc Forks?
Am 23.06.2013 11:47, schrieb Michal Minich: Does anybody know some good looking or with good features? btw, I'm wondering why is some basic version of Candy Doc bundled with DMD. Thanks. There is cuteDoc: https://github.com/JakobOvrum/cuteDoc - But it seems like Robik deleted his repo... And there is bootDoc: https://github.com/JakobOvrum/bootDoc (which requires JS)
Re: alias c=mixin(expr); disallowed, why?
On 06/23/13 13:23, Timon Gehr wrote: On 06/23/2013 12:19 PM, Artur Skawina wrote: On 06/22/13 21:52, Timothee Cour wrote: Is there a reason the language spec disallows this? void main(){ auto a=mixin(1);//OK alias b=a;//OK mixin(alias c=a;);//OK // alias c=mixin(a);//NG : Error: basic type expected, not mixin } How would that be different from auto c=mixin(a);? It's probably clear, but that error message is misleading, so i'll say it anyway - the reason why your 'alias' line does not work is because alias requires a symbol, but 'mixin()' is an expression. Special-casing mixin-expressions (so that they propagate the symbol when that is possible would be a bad idea); the other possibility is to allow aliasing /expressions/. But that's a bad idea too, and would likely not do what you expect it to do. A mixin-less version could be made to work, but there are already other ways to get the same effect. Hence the above question. mixin template T(alias x){ } void foo(){ import std.stdio; writeln(foo); } void main(){ auto a=mixin(1); mixin T!a; // ok mixin T!(mixin(a)); // ok mixin T!1; // ok (!) mixin T!(mixin(foo)); // ok (no implicit call) } Yes, template parms and literals are special (literals are useful as template parms, obviously). What would be the arguments for allowing these two: mixin T!(mixin(a)); // ok mixin T!(mixin(foo)); // ok (no implicit call) ? I didn't realize they were currently accepted. Is this actually documented somewhere? The fact that `mixin(foo)` and `mixin(foo+1)` mean subtly different things when used as a template parameter is a problem. artur
Re: Problem with object understanding and datatypes
Is this code available in any repo/archive somewhere? /Per
Range analysis result printing?
I am thinking about opening an enhancement request, but this time I first prefer to ask your opinion here. For this code: void main() { ubyte x; ubyte y = x 1; } The range analysis determines that it's conceivable to the result of that expression to not fit in y, so the D compiler 2.064alpha gives: temp.d(3): Error: cannot implicitly convert expression (cast(int)x 1) of type int to ubyte To help the programmer understand faster the mistake in his/her code when expressions become more complex I think it's also useful to print the range resulting from the analysis, like: temp.d(3): Error: cannot implicitly convert expression (cast(int)x 1) in interval [0 ... 510] of type int to ubyte It uses 3 dots because it's an interval that includes the right end. Otherwise if you print an interval open on the right in a case like this you have to print a ulong.max+1 value: void main() { ulong x; int y = x; } Do you like? Bye, bearophile