Working with modules
Hi all, I have a question regarding how to lay out my code. I wish to have a project directory structure that resembles java projects (As I'm comfortable working in that sort of environment For example: $PROJHOME |-/src - Source code |-/lib - third party libraries |-/bin - Compiled binaries |-build.sh - script to build my project and stick the binary into 'bin' directory So, my src directory is where all my source code is going. Under source code, im going to have a few different folders. This is where my problem occurs. To illustrate: $PROJHOME |-/src |- utils |- Logger.d |- Properties.d |- SSHTool.d |- engine I want to put Logger.d, Properties.d and SSHTool.d into the module 'utils'. However, D's module system wont allow that, keeps throwing back errors to me saying 'utils' is conflicting (or something similar, cant remember the exact error). So, I've done a bit of reading, and found out that I should put all those classes into once source file, and put that file in the module 'utils'. Now, thats all fine and dandy, but I expect by the end of this experiment I will have quite a lot of utility classes and I really dont want them all in one source file. It becomes unwieldy imo. Does anyone here have any alternatives for me so that in my 'engine' or 'main' classes I can simply write: import utils; and still have my source files neatly laid out in manageable chunks? Thanks in advance...
Re: Working with modules
15-Feb-2013 13:51, Colin Grogan пишет: [snip] This is where my problem occurs. To illustrate: $PROJHOME |-/src |- utils |- Logger.d |- Properties.d |- SSHTool.d |- engine I want to put Logger.d, Properties.d and SSHTool.d into the module 'utils'. However, D's module system wont allow that, keeps throwing back errors to me saying 'utils' is conflicting (or something similar, cant remember the exact error). So, I've done a bit of reading, and found out that I should put all those classes into once source file, and put that file in the module 'utils'. Now, thats all fine and dandy, but I expect by the end of this experiment I will have quite a lot of utility classes and I really dont want them all in one source file. It becomes unwieldy imo. Does anyone here have any alternatives for me so that in my 'engine' or 'main' classes I can simply write: import utils; Another way is to create utils/_.d file that contains: public import utils.Logger; public import utils.Properties; public import utils.SSHTool; and import it like this: import utils._; The other popular name for this module is 'all'. and still have my source files neatly laid out in manageable chunks? Yeah, community at large wants a cleaner way to do this. It just wasn't sorted out yet: http://wiki.dlang.org/DIP14 http://wiki.dlang.org/DIP15 Thanks in advance... -- Dmitry Olshansky
Re: std.container.RedBlackTree versus C++ std::set
I am starting to understand the difficulty with ref being too restrictive. Some kind of const ref in the language would have helped indeed. But it would probably cause some allocation difficulties for actual constants... or worse? Search for 'auto ref' or right after 'rvalue references' and read some of the discussions. It's instructive and then you can understand the whole topic maybe a little more. No thread comes to a solution and unfortunately the answer of Walter and Andrei are very very thin on the subject.
Re: Working with modules
On Friday, February 15, 2013 10:51:00 Colin Grogan wrote: Does anyone here have any alternatives for me so that in my 'engine' or 'main' classes I can simply write: import utils; and still have my source files neatly laid out in manageable chunks? The only way that you can have a single import which imports multiple modules is if the module that you're importing publicly imports the other modules. And there is no way to do something like import utils.*; And remember that modules always correspond to files, and packages correspond to folders, so there's a one-to-one correspondance between what you'd import and what you'd put in the file system (unless you use public imports to make it so that importing a module imports stuff from outside that module). - Jonathan M Davis
Re: Working with modules
On Friday, 15 February 2013 at 10:01:35 UTC, Jonathan M Davis wrote: On Friday, February 15, 2013 10:51:00 Colin Grogan wrote: Does anyone here have any alternatives for me so that in my 'engine' or 'main' classes I can simply write: import utils; and still have my source files neatly laid out in manageable chunks? The only way that you can have a single import which imports multiple modules is if the module that you're importing publicly imports the other modules. And there is no way to do something like import utils.*; And remember that modules always correspond to files, and packages correspond to folders, so there's a one-to-one correspondance between what you'd import and what you'd put in the file system (unless you use public imports to make it so that importing a module imports stuff from outside that module). - Jonathan M Davis Ah, ok. So, I have my structure like so: $PROJHOME |-src |-utils |- Logger.d // contains module utils.Logger |- Props.d // contains module utils.Props |- utils.d // contains module utils; public import utils.Logger, utils.Props; Then, i just 'import utils' in my code. Or would I have to have Logger.d in a directory called src/utils/Logger/Logger.d to be able to declare the module 'utils.Logger'?
Re: Working with modules
On Friday, February 15, 2013 11:31:40 Colin Grogan wrote: So, I have my structure like so: $PROJHOME |-src | |-utils | |- Logger.d // contains module utils.Logger |- Props.d // contains module utils.Props |- utils.d // contains module utils; public import utils.Logger, utils.Props; Then, i just 'import utils' in my code. Or would I have to have Logger.d in a directory called src/utils/Logger/Logger.d to be able to declare the module 'utils.Logger'? utils/logger.d would be utils.logger. utils/logger/logger.d would be utils.logger.logger. The file paths and the import paths are identical. It's just that the file paths have slashes, and the import paths have dots. And unlike Java, there is zero connection between classes and modules. You could have many classes in a single module or none at all. Also, it's common practice to use all lowercase for module and package names (primarily to avoid any risk of different OSes treating the casing differently I believe - i.e. Windows doesn't care about casing whereas *nix does; so, on Windows, you could screw up you're casing, and it would work, whereas on Linux, it wouldn't). - Jonathan M Davis
Re: Working with modules
On Friday, 15 February 2013 at 10:31:41 UTC, Colin Grogan wrote: Ah, ok. So, I have my structure like so: $PROJHOME |-src |-utils |- Logger.d // contains module utils.Logger |- Props.d // contains module utils.Props |- utils.d // contains module utils; public import utils.Logger, utils.Props; Then, i just 'import utils' in my code. Or would I have to have Logger.d in a directory called src/utils/Logger/Logger.d to be able to declare the module 'utils.Logger'? Not exactly. With given layout you will need to use import utils.utils; in your code. There are no package imports in D currently at all. Separating modules into directories is not needed and will actually break everything. D module system maps to file system entities. File is a module. Directory is a package.
Re: Working with modules
On Friday, 15 February 2013 at 10:40:57 UTC, Dicebot wrote: On Friday, 15 February 2013 at 10:31:41 UTC, Colin Grogan wrote: Ah, ok. So, I have my structure like so: $PROJHOME |-src |-utils |- Logger.d // contains module utils.Logger |- Props.d // contains module utils.Props |- utils.d // contains module utils; public import utils.Logger, utils.Props; Then, i just 'import utils' in my code. Or would I have to have Logger.d in a directory called src/utils/Logger/Logger.d to be able to declare the module 'utils.Logger'? Not exactly. With given layout you will need to use import utils.utils; in your code. There are no package imports in D currently at all. Separating modules into directories is not needed and will actually break everything. D module system maps to file system entities. File is a module. Directory is a package. Ah ok, now I get it. Thanks for that everyone. Ill test it out once I get home. Cheers! I saw the wiki entry posted earlier with recommendations for different module/package management, is there any plans to implement any of these changes do you know?
Re: Working with modules
Ok, I had a minute so I tested it out. I had the following: src/main.d: import utils._; void main(string[] args){ logger l = new logger(); props p = new props(); l.print(); p.print(); } src/utils/_.d module utils._; public import utils.props, utils.logger; src/utils/logger.d module utils.logger; import std.stdio; public class logger{ this(){} public void print(){ writefln(This is logger...); } } src/utils/props.d module utils.props; import std.stdio; public class props{ this(){} public void print(){ writefln(This is props...); } } Compiled and ran it, and it printed out This is logger... This is props... as I expected. That's perfect, solves my problem quite well I think! Thanks all!
Re: Working with modules
On 2013-02-15 12:04, Colin Grogan wrote: Ah ok, now I get it. Note that in Java you declare a package wheres in D you declare a module. If you have something like this in Java: // Baz.java package bar.foo; You would do this in D: // Baz.d module bar.foo.Baz; -- /Jacob Carlborg
rdmd hung?
I use emacs and have command that runs rdmd. Very rarely, as a guess maybe one in 100 calls to build, rdmd does not make any progress and I have to kill it. So, a ps -efww shows something like below and over 15 minutes have passed (normally max time to build and run is a couple of seconds) UIDPID PPID C STIME TTY TIME CMD 1000 4065 4063 0 10:44 pts/12 00:00:00 rdmd -debug -g -w -property foo.d No progress is being made. So, my questions: - is this a potential deadlock in rdmd? I believe it attempts to parallelize the work. - has anyone experienced this? - on linux is there a way, once in this state to provide any information that would be helpful. strace during on a complete run could help - but it is too late for that. Thanks Dan
Re: std.container.RedBlackTree versus C++ std::set
On Thursday, 14 February 2013 at 20:33:21 UTC, Ivan Kazmenko wrote: Rob T wrote: When I look at the std.container source code, it seems that the payload element is passed by value multiple times unnecessarily, so to minimize copy construction you'll have to implement element as a class and implement a dup function for it. Thank you all for assistance, I've finally pinned it down! It's the default magic a b that devours the most copies of my precious structs! Once I change the declaration: - alias RedBlackTree !(element) container; - to - bool lessfun (ref element a, ref element b) { return a b; } alias RedBlackTree !(element, lessfun) container; - ... I get only exactly 3 * LIMIT postblit constructor calls, which is 300,000 instead of 11,389,556. While I still want to find where the excess 200,000 calls originate from, this is definitely asymptotically better than before: O (n) versus O (n log n) calls. And it is now less of a bottleneck in my original program. This raises the question to the default behavior of std.functional.binaryFun. Sure, for integers, class references and small types, the current way is the best. On the other hand, for large structs and maybe some other complex objects that obey value semantics, it seems it would be beneficial to, given a string like a b, produce a function taking arguments by reference and not by value. Maybe there is some simple criterion (size of type greater than size_t - seems bad? type is a struct - better?) which can be used with static if to generate (ref a, ref b) instead of (a, b) version by default. Of course, all that could only work if there is a more detailed hierarchy of binary functions, at least a binaryFunConst taking const arguments. - Ivan Kazmenko. Also keep in mind that a b is implemented as two calls to a.opCmp(b), and a.opCmp(b) is itself usually implemented as two calls to something something else (!) as convenient as opCmp is for the implementation implementation, it is not always the best in terms of raw power. If you have can write a straight up less(S1, S2) function, such as a.i b.i, then using that can buy you a hefty amount of time.
Re: std.container.RedBlackTree versus C++ std::set
On Fri, 15 Feb 2013 12:11:55 -0500, monarch_dodra monarchdo...@gmail.com wrote: Also keep in mind that a b is implemented as two calls to a.opCmp(b), and a.opCmp(b) is itself usually implemented as two calls to something something else (!) Huh? a b is implemented as a.opCmp(b) 0, not two calls to a.opCmp(b). HOWEVER, when you get to the point of executing a == b, it's implemented as !(a b) !(b a), which could more efficiently be rewritten as a.opEquals(b) or a.opCmp(b) == 0. In the case of red black tree however, the nature of traversal makes it so that you only have the redundant call once (when you have found the insertion spot, you already have called one half, you just have to call the other half). For dcollections, I don't accept a b, I accept the int-returning compare function (which I think is pass by ref, so shouldn't have this problem). The std.container.RedBlackTree is a port of the same code, but adapted to the more phobos-style functions. -Steve
Re: std.container.RedBlackTree versus C++ std::set
On Friday, 15 February 2013 at 17:42:30 UTC, Steven Schveighoffer wrote: On Fri, 15 Feb 2013 12:11:55 -0500, monarch_dodra monarchdo...@gmail.com wrote: Also keep in mind that a b is implemented as two calls to a.opCmp(b), and a.opCmp(b) is itself usually implemented as two calls to something something else (!) Huh? a b is implemented as a.opCmp(b) 0, not two calls to a.opCmp(b). Yes. But isn't opCmp still more work than just ab? It must be because it returns three states instead of two. So, I think the general warning on opCmp is warranted especially with structs. For structs we could use compile time reflection to provide automatic efficient opCmp behavior. Section 3.1 here outlines a way: https://github.com/patefacio/d-help/blob/master/doc/canonical.pdf Any comments appreciated. Thanks Dan HOWEVER, when you get to the point of executing a == b, it's implemented as !(a b) !(b a), which could more efficiently be rewritten as a.opEquals(b) or a.opCmp(b) == 0.
Re: std.container.RedBlackTree versus C++ std::set
On Friday, 15 February 2013 at 17:42:30 UTC, Steven Schveighoffer wrote: On Fri, 15 Feb 2013 12:11:55 -0500, monarch_dodra monarchdo...@gmail.com wrote: Also keep in mind that a b is implemented as two calls to a.opCmp(b), and a.opCmp(b) is itself usually implemented as two calls to something something else (!) Huh? a b is implemented as a.opCmp(b) 0, not two calls to a.opCmp(b). Right... sorry. But still, calling opCmp is usually a bit more expensive that a simpler function dedicated to giving you a b. 99% of the time, I agree that it doesn't matter mutch, and the gain in semantic power trumps performance, but for a dedicated algorithm, eg sort, there is a definite performance difference... HOWEVER, when you get to the point of executing a == b, it's implemented as !(a b) !(b a), which could more efficiently be rewritten as a.opEquals(b) or a.opCmp(b) == 0. And that.
Re: std.container.RedBlackTree versus C++ std::set
On Thursday, 14 February 2013 at 20:53:26 UTC, Jonathan M Davis wrote: And Walter and Andrei both seem to think that having expensive postlbits is a design mistake. The range stuff sort of tries to support it with the move* primitives, but Andrei's been wanting to argue for just assuming that postblits are cheap. And Walter was actually arguing at one point for making it illegal (probably by getting rid of postblit all together - I don't remember the details). Plenty of the rest of us don't agree, but to some extent, it is true that having an expensive postblit is asking for it. On a related note, we still need a solution for dealing with const postblits (probably be introducing copy constructors - IIRC Andrei was considering phasing out postblits in favor of copy constructors, which would be unnecessary, but we do need a way to deal with deep copying const structs which hold reference types which need to be deep copied. When you say things like Andrei was considering phasing out postblits... I get nervous. Can we please have some comments from Andrei/Walter about what the plans are? I'm not asking for the ultimate solution - just to know the general direction and where this issue stands at present. Is there anything any of us can do to help move this forward? Regarding replacing expensive postblits with copy constructors - how does that help? The expense will remain the same - if you need a transitive copy, you need a transitive copy. Thanks Dan
Re: std.container.RedBlackTree versus C++ std::set
When you say things like Andrei was considering phasing out postblits... I get nervous. Can we please have some comments from Andrei/Walter about what the plans are? I'm not asking for the ultimate solution - just to know the general direction and where this issue stands at present. Is there anything any of us can do to help move this forward? Make a new thread where Walter and Andrei may submit an official staement. There are certainly other interested and this thread is probably not for more suitable.
Re: rdmd hung?
No progress is being made. So, my questions: - is this a potential deadlock in rdmd? I believe it attempts to parallelize the work. - has anyone experienced this? I don't remember experiencing this with rdmd, but I have seen something similar with my scripts that were starting processes from multiple threads in parallel (using std.parallelism).
Re: std.container.RedBlackTree versus C++ std::set
On Thursday, 14 February 2013 at 19:31:36 UTC, Steven Schveighoffer wrote: If it was pass by ref, then rbt.insert(5) would not work. And in fact, I wouldn't want things passed by ref if the element is int. What is the reason for the second objection - is just performance? Is performance really an issue? From this thread it looks like fundamental types by ref or value is not really a big deal in terms of performance. OTOH - as size and/or postblit execution gets expensive the cost *is* significant. --- 4 bytes: using cref_(int size) took 29[ms] 4 bytes: using inref(int size) took 29[ms] 4 bytes: using in___(int size) took 30[ms] 8 bytes: using cref_(int size) took 29[ms] 8 bytes: using inref(int size) took 28[ms] 8 bytes: using in___(int size) took 31[ms] ... 128 bytes: using cref_(int size) took 29[ms] 128 bytes: using inref(int size) took 29[ms] 128 bytes: using in___(int size) took 290[ms] --- I have to admit, I did not consider expensive postblits when I designed it. Almost all my testing is with integer types. For performance, it seems by ref should always be preferred in generic code because you can not know the cost of postblit - or copy construction if that were a future solution for structs. Granted the no rvalue passing is a pain - but is it a big deal in library/generic code? Thanks, Dan
Re: std.container.RedBlackTree versus C++ std::set
On Friday, February 15, 2013 20:12:08 Dan wrote: Granted the no rvalue passing is a pain - but is it a big deal in library/generic code? Yes, it's a big deal. Any place that it's part of an API, it's a big deal. It forces you to create what are essentially useless variables all over the place if you require ref. We _will_ have a solution similar to const at some point, and that's what the correct way to go to solve this problem will be, but that situation still needs to be sorted out (and the situation with DIP 25 - http://wiki.dlang.org/DIP25 - could have an impact on that given that it's also has to do with changes to ref). - Jonathan M Davis
Re: std.container.RedBlackTree versus C++ std::set
They're not going to do that until they've decided, and AFAIK, they haven't. Attempting to essentially confront them and get them to say what they plan to do generally doesn't get you anywhere - especially since they're unlikely to say much until they actually are planning to do it, and it's usually the case that no decision has been made. - Jonathan M Davis I did not mean the const thing. This is hopeless and will certainly take some months or years. My post was based on [...] probably by getting rid of postblit all together..
Re: std.container.RedBlackTree versus C++ std::set
On Friday, February 15, 2013 21:16:51 Namespace wrote: They're not going to do that until they've decided, and AFAIK, they haven't. Attempting to essentially confront them and get them to say what they plan to do generally doesn't get you anywhere - especially since they're unlikely to say much until they actually are planning to do it, and it's usually the case that no decision has been made. - Jonathan M Davis I did not mean the const thing. This is hopeless and will certainly take some months or years. My post was based on [...] probably by getting rid of postblit all together.. I know. And my answer is the same. There's nothing special about the const issue and how that's going. That's how it pretty much always goes. Until it becomes a priority for Walter, it'll go nowhere. Sometimes, if someone makes it a priority and implements it (creating a pull request for it), then that solves the problem, but sometimes that's still not enough, because Walter needs to sort out whether it's the direction that we want to go, which means making it a priority to sort that out, which means that the pull request sits around for a while and may or may not make it in. Bug fixes and more minor language changes do get merged all the time, but if a language change is significant enough, it generally requires that Walter spend some time on it and make a decision on it (even if he's not implementing the changes), and he's generally very slow about that if it's not near the top of his list of priorities. - Jonathan M Davis
Re: std.container.RedBlackTree versus C++ std::set
On Friday, February 15, 2013 21:37:46 Jonathan M Davis wrote: On Friday, February 15, 2013 21:16:51 Namespace wrote: They're not going to do that until they've decided, and AFAIK, they haven't. Attempting to essentially confront them and get them to say what they plan to do generally doesn't get you anywhere - especially since they're unlikely to say much until they actually are planning to do it, and it's usually the case that no decision has been made. - Jonathan M Davis I did not mean the const thing. This is hopeless and will certainly take some months or years. My post was based on [...] probably by getting rid of postblit all together.. I know. And my answer is the same. There's nothing special about the const issue and how that's going. That's how it pretty much always goes. Until it becomes a priority for Walter, it'll go nowhere. Sometimes, if someone makes it a priority and implements it (creating a pull request for it), then that solves the problem, but sometimes that's still not enough, because Walter needs to sort out whether it's the direction that we want to go, which means making it a priority to sort that out, which means that the pull request sits around for a while and may or may not make it in. Bug fixes and more minor language changes do get merged all the time, but if a language change is significant enough, it generally requires that Walter spend some time on it and make a decision on it (even if he's not implementing the changes), and he's generally very slow about that if it's not near the top of his list of priorities. I should probably add that bringing up discussions on how to solve problems in the language can be of benefit, because they often result in good discussions that help lead toward a solution, and that can lead towards that solution ending up in the language (and depending on the discussion Andrei and/or Walter will get involved). But simply asking them about the state of things or essentially contronting them and trying to get them to give official statements on their plans doesn't generally work. If nothing else, they simply don't generally say what they're planning to do before they've actually decided on it. They might start discussions to discuss something that they're considering, but they're unlikely to state any kind of actual plans before they've actually decided, which generally means no official statements about what's coming or planned. - Jonathan M Davis
Re: std.container.RedBlackTree versus C++ std::set
Again: My intention was not const. And you're right, but there was so many discussions about const (since dmd 2.057; also in the last few days) and as every discussion here: after page 2 is the topic changed. I'm also very sure that neither Walter nor Andrei see a (important) reason for something similar as const because they don't need it. And if you don't need something, the priority for such thing is very low. So everything we can do (after that much requests and discussions) is to wait what and when they will decide something. I count the versions.
Re: std.container.RedBlackTree versus C++ std::set
On Fri, 15 Feb 2013 13:14:21 -0500, Dan dbdavid...@yahoo.com wrote: When you say things like Andrei was considering phasing out postblits... I get nervous. Can we please have some comments from Andrei/Walter about what the plans are? I'm not asking for the ultimate solution - just to know the general direction and where this issue stands at present. Is there anything any of us can do to help move this forward? I think the plan was to *assume* postblits were inexpensive, not to disallow them. -Steve
Re: std.container.RedBlackTree versus C++ std::set
On Friday, February 15, 2013 22:41:24 Namespace wrote: Again: My intention was not const. I know. What I'm saying applies in general. And you're right, but there was so many discussions about const (since dmd 2.057; also in the last few days) and as every discussion here: after page 2 is the topic changed. I'm also very sure that neither Walter nor Andrei see a (important) reason for something similar as const because they don't need it. And if you don't need something, the priority for such thing is very low. So everything we can do (after that much requests and discussions) is to wait what and when they will decide something. I count the versions. They definitely agree that it's a problem. They just don't see it as having as high a priority as you do. For instance, as far as ref-related problems go, the issue that DIP 25 covers is something that they consider to be a much bigger issue (since it deals with @safe and SafeD). It'll be fixed though. It's just a question of how and when. - Jonathan M Davis
Re: std.container.RedBlackTree versus C++ std::set
On Friday, February 15, 2013 16:53:36 Steven Schveighoffer wrote: On Fri, 15 Feb 2013 13:14:21 -0500, Dan dbdavid...@yahoo.com wrote: When you say things like Andrei was considering phasing out postblits... I get nervous. Can we please have some comments from Andrei/Walter about what the plans are? I'm not asking for the ultimate solution - just to know the general direction and where this issue stands at present. Is there anything any of us can do to help move this forward? I think the plan was to *assume* postblits were inexpensive, not to disallow them. Yes, but as I recall, in discussions on const and postblit, Andrei made a comment about how postblit hadn't really worked out and we need copy constructors (in which case, we'd move to normally using copy constructors as the norm). But I don't believe that Andrei suggested getting rid of postblit completely (due to the code breakage it would cause if nothing else), and while I think that Walter and Andrei would deal with the postblit issue very differently if they were to start over, there are no plans at present to get rid of it. - Jonathan M Davis
Re: std.container.RedBlackTree versus C++ std::set
They definitely agree that it's a problem. They just don't see it as having as high a priority as you do. For me it is not a priority (anymore). I use C++ again. It's just a question of how and when. - Jonathan M Davis Yes as I said: I count the versions. :)
Re: std.container.RedBlackTree versus C++ std::set
On Fri, 15 Feb 2013 13:02:39 -0500, Dan dbdavid...@yahoo.com wrote: On Friday, 15 February 2013 at 17:42:30 UTC, Steven Schveighoffer wrote: On Fri, 15 Feb 2013 12:11:55 -0500, monarch_dodra monarchdo...@gmail.com wrote: Also keep in mind that a b is implemented as two calls to a.opCmp(b), and a.opCmp(b) is itself usually implemented as two calls to something something else (!) Huh? a b is implemented as a.opCmp(b) 0, not two calls to a.opCmp(b). Yes. But isn't opCmp still more work than just ab? It depends: bool less(int a, int b) { return a b; } In assembly (pardon my ignorance of asm syntax): ld a AX; sub AX, b; jneg L1; // jump if AX is less than zero ld AX 0; ret; L1: ld AX 1; ret; With opcmp: int opCmp(int a, int b) { return a - b; } Which simplifies the assembly significantly. Note we don't have to shoehorn the result into a bool (which must be 0 or 1). For other cases, such as a complex struct, less might be more efficient. And really, when it comes down to it, it all depends on how you use it. If most of the time you are using a b or b a, then less certainly can be more efficient (but not necessarily). But if you want to do =, ==, or =, then opCmp can be more efficient. -Steve
Re: std.container.RedBlackTree versus C++ std::set
On Friday, 15 February 2013 at 22:06:55 UTC, Steven Schveighoffer wrote: With opcmp: int opCmp(int a, int b) { return a - b; } Genius! Now I feel bad for every time I've done integral opCmp with double ternary operators :(
Re: std.container.RedBlackTree versus C++ std::set
On Fri, Feb 15, 2013 at 11:49:53PM +0100, monarch_dodra wrote: On Friday, 15 February 2013 at 22:06:55 UTC, Steven Schveighoffer wrote: With opcmp: int opCmp(int a, int b) { return a - b; } Genius! Now I feel bad for every time I've done integral opCmp with double ternary operators :( You know that this is the origin of C's strcmp, right? Ever wondered why the C standard says that it returns 0, 0, or 0, as opposed to fixed values like -1, 0, 1? Now you know why: it's because you could implement strcmp by repeatedly subtracting respective pairs of characters from the two strings, and return the result when it's no longer zero (in some CPUs' assembly language, this is a single branch-on-nonzero instruction). No need for extraneous overhead to convert the result of the comparison into fixed values of any sort. D simply inherited from the genius of C's original designers. :) Of course, this optimization may no longer be relevant in today's CPU's, due to pipelining, hazards, branch prediction, etc.. T -- If creativity is stifled by rigid discipline, then it is not true creativity.
Re: std.container.RedBlackTree versus C++ std::set
On Friday, February 15, 2013 23:49:53 monarch_dodra wrote: On Friday, 15 February 2013 at 22:06:55 UTC, Steven Schveighoffer wrote: With opcmp: int opCmp(int a, int b) { return a - b; } Genius! Now I feel bad for every time I've done integral opCmp with double ternary operators :( Except that you have to worry about overflow if you use subtraction, so it's actually a bad idea in the general case. - Jonathan M Davis
Re: std.container.RedBlackTree versus C++ std::set
On Fri, 15 Feb 2013 17:49:53 -0500, monarch_dodra monarchdo...@gmail.com wrote: On Friday, 15 February 2013 at 22:06:55 UTC, Steven Schveighoffer wrote: With opcmp: int opCmp(int a, int b) { return a - b; } Genius! Now I feel bad for every time I've done integral opCmp with double ternary operators :( Actually, I'm not as smart as you think ;) There needs to be some extra checking, possibly with the carry flag. For example: 0x7000 - (-0x7000) would be less than zero as a resulting integer. But it would work with shorts or bytes! In any case, the example was bad, the point that which is better depends on the situation is still correct. -Steve
Re: std.container.RedBlackTree versus C++ std::set
On Fri, 15 Feb 2013 18:41:51 -0500, Steven Schveighoffer schvei...@yahoo.com wrote: There needs to be some extra checking, possibly with the carry flag. And further to that point, my generated assembly for a b also is similarly flawed, so it still may be better to do opCmp. -Steve
Re: std.container.RedBlackTree versus C++ std::set
Steven Schveighoffer: Actually, I'm not as smart as you think ;) There needs to be some extra checking, possibly with the carry flag. For example: 0x7000 - (-0x7000) would be less than zero as a resulting integer. But it would work with shorts or bytes! I remember a page about such problem in the old D wiki. I was unable to find it inside the new D wiki. Bye, bearophile
Re: Aliasing specialized template stuct in his module leads troubles
One more thing about this. If I leave in the alias in the same module where the template is defined, and also re-define the same alias in the other modules that make use out of it, the libraries will compile OK, but I'll get linking errors when I try to build an executable and link in the libs. For each re-defined alias, I was able to confirm that the name mangling is identical in each module, so there's something going wrong specifically when the alias is defined in the same module where the template resides. --rt
Re: A little of coordination for Rosettacode
On 5-2-2013 23:44, bearophile wrote: Jos van Uden: Partial translation of the universal_turing_machine-Ruby: http://codepad.org/nUXLzAg2 I'd have to first read up on the subject. It's a simple task, just to implement an universal Turing machine. It's a matter of finding a balance between the too much high level Ruby version and a too much C-like version. In D a simple way to implement a tape is with two dynamic arrays, one represents all the cells on the right to the starting position, and the other array is used inverted, to represent all the cells on the left of the right position. There are faster solutions, but this is enough for the purposes of Rosettacode. The Universal Turing Machine is working. I've only tested with the given tables. I'll try some more tomorrow. I couldn't get the AA's to nest the way they do in Ruby, so I had to do it differently. This task seemed like a good candidate for using an invariant, but the loop in the run method already checks the state on every iteration, so I'm not sure what you could check except to see if all the fields have been initialized perhaps. It was a fun task. http://dpaste.dzfl.pl/3caa52e7
Re: std.container.RedBlackTree versus C++ std::set
On Friday, 15 February 2013 at 23:41:50 UTC, Steven Schveighoffer wrote: In any case, the example was bad, the point that which is better depends on the situation is still correct. The compiler has to do something with ab. I would hope for a fundamental type it can avoid the lowering and just do whatever assembly is optimal. For a non-fundamental type, what is the case where (a.opCmp(b)0) is more optimal than a comparable (a.opLess(b))? It is easy to create an inefficient implementation of opCmp that calls twice. struct S { string s; int opCmp ( const ref S other ) { if ( sother.s ) { return -1; } else if ( other.ss ) { return 1; } else { return 0; } } } My point was, you can use compile time reflection to generate a suitable opCmp that uses s.opCmp if it exists or does the long version of two comparisons if not. Thanks Dan
Re: Aliasing specialized template stuct in his module leads troubles
On Tuesday, 4 September 2012 at 22:46:00 UTC, Ivan Agafonov wrote: I have my library module: module mylib.vector; // alias Vector!(float, 4) Vector4f; struct Vector(T, uint size) { T[size] array = 0; ... } And I have client module: import mylib.vector; alias Vector!(float, 4) Vector4f; void main() { auto x = Vector4f([1.0f, 2.0f, 3.0f, 4.0f]); } If alias would be in vector module (commented there) I will have to compile both modules (otherwise I'll get link errors for some vector functions), but I want to simply import vector module and immediately use predefined aliases for vector template struct. How can I do this? I've encountered the exact same problem. I create an alias to define a specific type out of a template in the same library module that the template resides in. I can build the library OK, but when I build an executable and link in the library, the linker chokes out with an undefined symbol names. If I comment out the alias, and instead define the same alias in each module where it is being used, I can rebuild my library and the executable OK. This looks like a bug to me. The mystery is why almost no one is complaining about it, so it must be that just about nobody defines template aliases in this way. I'll wait a while to see if there are any more comments before filing a bug report --rt
Re: A little of coordination for Rosettacode
Jos van Uden: The Universal Turing Machine is working. There are many different ways to solve this Task in D. You can write a very strongly typed Ada-like program, or a weakly typed Ruby-like program. Both have advantages and disadvantages (as years pass I am leaning more toward a stronger static typing, despite I like Python). Your version is more toward the weakly typed end of the spectrum (but not as much as Ruby). I am now reading your code. - - - - - - - - - - This is bad: void move(in int dir) { final switch(dir) { case UTM.left: left(); break; case UTM.right: right(); break; case UTM.stay: stay(); break; } } final switche was introduced in D to increase safety making the code more strongly typed, but there you are relying on a DMD bug, and that piece of code is the opposite of safe. A correct D compiler must refuse your code: http://d.puremagic.com/issues/show_bug.cgi?id=5713 I have rewritten it like this: void move(in int dir) { switch(dir) { case UTM.left: left(); break; case UTM.right: right(); break; case UTM.stay: stay(); break; default: assert(0); } } If you want to write a stronger typed code you can give a name to that enum, and then it's a good idea to use a final switch. But then the associative array rules must have Tuples (or structs) as values. - - - - - - - - - - I couldn't get the AA's to nest the way they do in Ruby, so I had to do it differently. I will take a look at this later. Maybe it's a known AA bug. - - - - - - - - - - This task seemed like a good candidate for using an invariant, but the loop in the run method already checks the state on every iteration, so I'm not sure what you could check except to see if all the fields have been initialized perhaps. Seems good to do, but maybe a pre-condition is enough. - - - - - - - - - - Instead of using toString() maybe it's better to add a printTape, and let run() return nothing. I have also converted UTM to a struct, because for this little program it doesn't need to be a class (and there is no need of new). - - - - - - - - - - I am not so fond of the D idiom of using general Exceptions, I'd like to use a bit more variety of Phobos-defined exceptions. But in this little program I think using two basic Exception is acceptable. - - - - - - - - - - The two casts in your code are bad, generally in D you don't cast to mutable or to immutable, because it's dangerous and unclean. So I will (try to) remove them: this(ref TuringMachine tm) { this.tm = cast(immutable)tm; this.head = TapeHead(this.tm); } void run() { if (this.halted) throw new Exception(Machine already halted.); auto state = cast()this.tm.initialState; - - - - - - - - - - Maybe later I'll write more comments. Bye, bearophile
Re: A little of coordination for Rosettacode
Instead of using toString() maybe it's better to add a printTape, and let run() return nothing. I have also converted UTM to a struct, because for this little program it doesn't need to be a class (and there is no need of new). I meant the opposite, sorry: printTape() == toString() Bye, bearophile
Ping qznc: Re: A little of coordination for Rosettacode
On 5-2-2013 20:45, Jos van Uden wrote: By the way, I think 'Qznc' may want to have a look at 'The dining philosophers': http://rosettacode.org/wiki/Dining_philosophers
Re: A little of coordination for Rosettacode
A first revision, do you like the toString? http://codepad.org/qhH2XpMx - - - - - - - - - - - The modified code contains still an enum that gets converted to char and then to int. I am not going to write code like that in my own production code :-) - - - - - - - - - - - To improve this type soup a bit I suggest to introduce one or more alias for the types of states, etc, like: alias State = char; and then use it/them. static struct TuringMachine { char[] symbols; char blank; char initialState; char[] haltStates, runningStates; char[][string] rules; char[] input; } static struct TapeHead { const char[] symbols; const char blank; char[] tape; size_t index; ... - - - - - - - - - - - Bye, bearophile
Re: Working with modules
On Friday, 15 February 2013 at 10:01:35 UTC, Jonathan M Davis wrote: On Friday, February 15, 2013 10:51:00 Colin Grogan wrote: Does anyone here have any alternatives for me so that in my 'engine' or 'main' classes I can simply write: import utils; and still have my source files neatly laid out in manageable chunks? The only way that you can have a single import which imports multiple modules is if the module that you're importing publicly imports the other modules. And there is no way to do something like import utils.*; And remember that modules always correspond to files, and packages correspond to folders, so there's a one-to-one correspondance between what you'd import and what you'd put in the file system (unless you use public imports to make it so that importing a module imports stuff from outside that module). - Jonathan M Davis I was actually going to post a similar question, but it looks like this would be a better place to post! I know that a module can only be defined once, but I feel like there could be times where it would be helpful to be able to have the same module defined in separate files and I have an example. Right now, I am working on a binding and I am making use of the package access modifier to allow me to use internal objects that the end user will not be able to access directly. Problem is, my source files have many classes and are pretty convoluted. If I could define the module more than once I could split the source files up and it would be easier to work on, but I would still be able to share package declared objects and methods between modules like I do now. If I put the source files into their own packages, they are now hidden from source files I want them to be used in. Here's what I mean: mainpackage.system mainpackage.window mainpackage.graphics Anything defined with package is accessible between these. But... mainpackage.system.thing1 mainpackage.system.thing2 mainpackage.window.thing3 etc... Now things defined as package in mainpackage.system.thing1 are only accessible in mainpackage.system, but can't be accessed in mainpackage.window. Thoughts?
Re: Ping qznc: Re: A little of coordination for Rosettacode
On Saturday, 16 February 2013 at 02:23:42 UTC, Jos van Uden wrote: On 5-2-2013 20:45, Jos van Uden wrote: By the way, I think 'Qznc' may want to have a look at 'The dining philosophers': http://rosettacode.org/wiki/Dining_philosophers Am I the new rosetta concurency guy? :) I should find the time to solve it this weekend.
Re: Working with modules
On Saturday, 16 February 2013 at 03:50:12 UTC, Jeremy DeHaan wrote: I was actually going to post a similar question, but it looks like this would be a better place to post! I know that a module can only be defined once, but I feel like there could be times where it would be helpful to be able to have the same module defined in separate files and I have an example. Right now, I am working on a binding and I am making use of the package access modifier to allow me to use internal objects that the end user will not be able to access directly. Problem is, my source files have many classes and are pretty convoluted. If I could define the module more than once I could split the source files up and it would be easier to work on, but I would still be able to share package declared objects and methods between modules like I do now. If I put the source files into their own packages, they are now hidden from source files I want them to be used in. Here's what I mean: mainpackage.system mainpackage.window mainpackage.graphics Anything defined with package is accessible between these. But... mainpackage.system.thing1 mainpackage.system.thing2 mainpackage.window.thing3 etc... Now things defined as package in mainpackage.system.thing1 are only accessible in mainpackage.system, but can't be accessed in mainpackage.window. Thoughts? On Saturday, 16 February 2013 at 03:50:12 UTC, Jeremy DeHaan wrote: I was actually going to post a similar question, but it looks like this would be a better place to post! I know that a module can only be defined once, but I feel like there could be times where it would be helpful to be able to have the same module defined in separate files and I have an example. Right now, I am working on a binding and I am making use of the package access modifier to allow me to use internal objects that the end user will not be able to access directly. Problem is, my source files have many classes and are pretty convoluted. If I could define the module more than once I could split the source files up and it would be easier to work on, but I would still be able to share package declared objects and methods between modules like I do now. If I put the source files into their own packages, they are now hidden from source files I want them to be used in. Here's what I mean: mainpackage.system mainpackage.window mainpackage.graphics Anything defined with package is accessible between these. But... mainpackage.system.thing1 mainpackage.system.thing2 mainpackage.window.thing3 etc... Now things defined as package in mainpackage.system.thing1 are only accessible in mainpackage.system, but can't be accessed in mainpackage.window. Thoughts? I see this as more of a code architecture issue. It's up to you to decide which modules belong to which package, and that's that. If you see system and window as belonging to one package, then don't create subpackages. You can still split things up into separate modules if you need to: mainpackage.system mainpackage.systhing1 mainpackage.systhing2 mainpackage.window mainpackage.winthing3 You could keep your public-facing API in system and window or, if your design doesn't work that way, have things spread out over the various thing* modules and let system and window import them publicly. Either way, client code then imports system and window and pretends the rest don't exist. It would be nice to have a special module declaration to enforce this on the client side, something like: private module mainpackage.systhing1; Any module declared as such would not be importable outside of the package, but could still be explicitly imported into the namespace via a public import from another module in the same package.
Re: Working with modules
On Friday, February 15, 2013 20:14:41 Ali Çehreli wrote: On 02/15/2013 07:50 PM, Jeremy DeHaan wrote: I know that a module can only be defined once, but I feel like there could be times where it would be helpful to be able to have the same module defined in separate files There may be other ways of achieving that and I haven't given much thought to your question but there is also the import expression: http://dlang.org/expression.html#ImportExpression If needed, you can include D files similar to C's #include: mixin (import (part_of_my_module.d)); mixin (import (another_part_of_my_module.d)); You can play games like this if you really want to, but in general, it should be kept in mind that modules in D are designed to have a one-to-one correspondance with files, and packages are designed to have a one-to-one correspondance with directories. And in general, fighting that is just going to cause trouble and confusion. That doesn't necessarily mean that it should never be done, but in most cases, it would be far better to just reorganize your code so that it's not necessary. Also, AFAIK, mixing in imports is a very rare thing to do, so for the most part, people won't be expecting it, and it will likely cause maintenance issues for anyone else working on your project. What is more typically done when you need to split stuff up is to use internal modules which are only imported internally and are not presented as part of the public API, but even that isn't terribly common, I don't think (but unlike mixing in imports, it's something that the standard library actually does in a few places). - Jonathan M Davis