Digital Mars has been accepted for Google Summer of Code 2011
We have just got word from Google - Digital Mars has been accepted as a mentoring organization for Google Summer of Code 2011. Thanks to Trass3r for bringing up this idea, to Jens Mueller for reiterating it, and to the people who added to the project ideas wiki. These are heady times. Let's spread the word to friends and colleagues! If you're a student, consider embarking on a project. If you're experienced with D, consider applying for mentorship. Walter, please announce this on digitalmars.com and link to the project ideas page. Thanks, Andrei
Re: Digital Mars has been accepted for Google Summer of Code 2011
On Fri, 18 Mar 2011 16:01:38 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: We have just got word from Google - Digital Mars has been accepted as a mentoring organization for Google Summer of Code 2011. Thanks to Trass3r for bringing up this idea, to Jens Mueller for reiterating it, and to the people who added to the project ideas wiki. These are heady times. Let's spread the word to friends and colleagues! If you're a student, consider embarking on a project. If you're experienced with D, consider applying for mentorship. Walter, please announce this on digitalmars.com and link to the project ideas page. That's awesome :) -Steve
Re: Digital Mars has been accepted for Google Summer of Code 2011
Am 2011-03-18 21:01, schrieb Andrei Alexandrescu: We have just got word from Google - Digital Mars has been accepted as a mentoring organization for Google Summer of Code 2011. Thanks to Trass3r for bringing up this idea, to Jens Mueller for reiterating it, and to the people who added to the project ideas wiki. These are heady times. Let's spread the word to friends and colleagues! If you're a student, consider embarking on a project. If you're experienced with D, consider applying for mentorship. Walter, please announce this on digitalmars.com and link to the project ideas page. Thanks, Andrei Congratulations! Thomas
Re: Digital Mars has been accepted for Google Summer of Code 2011
On 18/03/11 8:23 PM, Thomas Mader wrote: Am 2011-03-18 21:01, schrieb Andrei Alexandrescu: We have just got word from Google - Digital Mars has been accepted as a mentoring organization for Google Summer of Code 2011. Thanks to Trass3r for bringing up this idea, to Jens Mueller for reiterating it, and to the people who added to the project ideas wiki. These are heady times. Let's spread the word to friends and colleagues! If you're a student, consider embarking on a project. If you're experienced with D, consider applying for mentorship. Walter, please announce this on digitalmars.com and link to the project ideas page. Thanks, Andrei Congratulations! Thomas Congrats :)
Re: Digital Mars has been accepted for Google Summer of Code 2011
On 2011-03-18 22:01:38 +0200, Andrei Alexandrescu said: We have just got word from Google - Digital Mars has been accepted as a mentoring organization for Google Summer of Code 2011. Thanks to Trass3r for bringing up this idea, to Jens Mueller for reiterating it, and to the people who added to the project ideas wiki. These are heady times. Let's spread the word to friends and colleagues! If you're a student, consider embarking on a project. If you're experienced with D, consider applying for mentorship. Walter, please announce this on digitalmars.com and link to the project ideas page. Thanks, Andrei This is absolutely awesome!
Re: Digital Mars has been accepted for Google Summer of Code 2011
On Fri, 18 Mar 2011 15:01:38 -0500, Andrei Alexandrescu wrote: We have just got word from Google - Digital Mars has been accepted as a mentoring organization for Google Summer of Code 2011. congrats :)
Re: Digital Mars has been accepted for Google Summer of Code 2011
On Fri, Mar 18, 2011 at 1:01 PM, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: We have just got word from Google - Digital Mars has been accepted as a mentoring organization for Google Summer of Code 2011. Great! Good for us (from a proud new Googler... :-) --bb Thanks to Trass3r for bringing up this idea, to Jens Mueller for reiterating it, and to the people who added to the project ideas wiki. These are heady times. Let's spread the word to friends and colleagues! If you're a student, consider embarking on a project. If you're experienced with D, consider applying for mentorship. Walter, please announce this on digitalmars.com and link to the project ideas page. Thanks, Andrei
Re: Digital Mars has been accepted for Google Summer of Code 2011
On 3/18/11 7:06 PM, Bill Baxter wrote: On Fri, Mar 18, 2011 at 1:01 PM, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: We have just got word from Google - Digital Mars has been accepted as a mentoring organization for Google Summer of Code 2011. Great! Good for us (from a proud new Googler... :-) Congrats on the new job! Andrei
Re: Why can't structs be derived from?
On Thursday 17 March 2011 22:12:17 Don wrote: Andrei Alexandrescu wrote: On 3/17/11 11:21 AM, Andrej Mitrovic wrote: On 3/17/11, Nick Sabalauskya@a.a wrote: I've long been convinced that alias old new; should really be alias new = old; The current way confuses me, and I *still* have to consciously stop and think about it every time I write an alias statement (including just now). I thought I was the only one. The `alias symbol this` in structs in particular always stops me and I have to think about what it means, even though it might be obvious. I'm with y'all too. Even Walter needs to stop and think for a second. We're considering enabling alias a = b; as an equivalent for alias b a; Andrei That would be great! Yes. That change would make alias much more pleasant to deal with. It's not all that big a deal with how it is, but I usually screw it up, just like I usually screw up typedefs in C++. It's just not obvious which way it goes. - Jonathan M Davis
Re: Why can't structs be derived from?
On 3/17/2011 2:36 PM, Andrei Alexandrescu wrote: I'm with y'all too. Even Walter needs to stop and think for a second. We're considering enabling alias a = b; as an equivalent for alias b a; Please yes. I'd even be in favor of deprecating the old usage, even though every project under the sun (to within experimental error) currently uses it.
Re: Library Development: What to finish/flesh out?
dsimcha wrote: I've accumulated a bunch of little libraries via various evening and weekend hacking projects over the past year or so, in various states of completion. Most are things I'm at least half-considering for Phobos, though some belong as third-party libs. I definitely don't have time to finish/flesh out all of them anytime soon, so I've decided to ask the community what to prioritize. Below is a summary of everything I've been working on, with its current level of completion. Please let me know the following: 3. TempAlloc: A memory allocator based on a thread-local segmented stack, useful for allocating large temporary buffers in things like numerics code. Also comes with a hash table, hash set and AVL tree optimized for this allocation scheme. The advantages over plain old stack allocation are that it's independent of function calls (meaning you can return pointers to TempAlloc-allocated memory from a function, etc.) and it's segmented, meaning you can allocate huge buffers w/o risking stack overflow. Its main weakness is that this stack is not scanned by the GC, meaning that you can't store the only reference to a GC-allocated piece of memory here. However, in practice large arrays of primitives are an extremely common case in performance-critical code. I find this module immensely useful in dstats and Lars Kyllingstad uses it in SciD. Getting it into Phobos would make it easy for other scientific/numerics code to use it. Completion state: Working and used. Needs a litte cleanup and documentation. (Phobos candidate) This is #1. Far and away. Belongs in druntime. I would use it instantly in BigInt.
Re: Why can't structs be derived from?
On 3/17/2011 2:36 PM, Andrei Alexandrescu wrote: I'm with y'all too. Even Walter needs to stop and think for a second. We're considering enabling alias a = b; as an equivalent for alias b a; Along similar lines (hoping this isn't too far off-topic), what's the current plan for typedef? I'm aware that it's deprecated (and for good reason), but some of my reading suggests that there's a successor on the horizon.
Re: Against enforce()
Steven Schveighoffer Wrote: As long as the delegate does not access shared/global data, it should be able to be pure. Even delegates which modify TLS data should be able to be pure (weak-pure, but still pure). Pure functions calling weakly pure functions are also weakly pure and so on. This effectively leaves you without purity.
Re: Against enforce()
Walter Bright Wrote: 1. Asserts and contracts are for detecting program BUGS. They are not for validating user input, checking for disk full, file not found errors, etc. 2. Enforce is for validating user input, checking for disk full, file not found errors, etc. Enforce is NOT for use in contracts or checking for program bugs. Any use of enforce in Phobos that is checking for program bugs is itself a bug and should be entered into bugzilla for fixing. So this is a bug? This is a contract, not a validation of user input. struct Iota(N, S) if ((isIntegral!N || isPointer!N) isIntegral!S) { private N current, pastLast; private S step; this(N current, N pastLast, S step) { enforce((current = pastLast step 0) || (current = pastLast step 0)); this.current = current; this.step = step;
Re: Against enforce()
Kagamin wrote: Steven Schveighoffer Wrote: As long as the delegate does not access shared/global data, it should be able to be pure. Even delegates which modify TLS data should be able to be pure (weak-pure, but still pure). TLS variables are global and must not be accessed from any function marked as pure. With regard to purity, there isn't any difference between shared and TLS variables. Pure functions calling weakly pure functions are also weakly pure and so on. This effectively leaves you without purity. I presume you mean Pure functions calling weakly pure functions *would also be* weakly pure and so on. ?
Re: a cabal for D ?
On Thu, 2011-03-17 at 20:44 +, Jason E. Aten wrote: Please correct me if I'm wrong, but I observe that there doesn't appear to be a package management system / standard repository for D libraries. Or is there? I'm talking about something as easy to use as R's CRAN, install.packages(rforest) or cpan for perl, ctan for latex, dpgk/apt for debian, cabal for Haskell/ Hackage, etc. Note that every language-specific package manager conflicts directly with every operating system package manager. Thus RubyGems, CPAN, Cabal, Maven, Go, etc. conflicts with the package management of Debian, Fedora, SUSE, FreeBSD, MacPorts, etc. leading to pain. Pain leads to anger. Anger leads to hate. Hate leads to suffering. If there's not a commonly utilized one currently, perhaps we could borrow cabal, with a trivial port. cabal is Haskell's package manager. Not only does having a standard package install system facilitate adoption, it greatly facilitates code sharing and library maturation. At the expense of easy system administration. I guess the only up side of language specific package management is that it enables people whose operating systems are not package structured to do things sensibly. Alternatively Windows users could switch to a sensible operating system ;-) Given that D has chosen to switch to Git for version control, doesn't this imply that package management transported over DVCS is the way forward. Go has certainly taken this route. It prioritizes Mercurial but supports Bazaar and Git as well. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: Pull requests for multiple issues?
On Thu, 17 Mar 2011 20:59:54 -0400, Nick Sabalausky wrote: I was thinking of converting my patches for various rdmd issues into github pull requests, but being relatively new to DVCSes (longtime SVN user here) I was wondering what's the kosher way to do it?: - A separate branch for each issue, with a pull request for each branch? - One branch with a separate commit for each issue, and a pull request for each commit? - One branch with a separate commit for each issue, and a pull request for the whole branch? If so, the root of the branch or the leaf of the branch? You need a separate branch for each pull request. Commits which depend on each other should of course be in a single branch. Other than that, I would recommend creating a separate branch/pull req. for each issue. That way, if the patch for issue X isn't approved, the patches for Y and Z can still be merged in. -Lars
Re: Library Development: What to finish/flesh out?
On Thu, 17 Mar 2011 15:33:10 +, dsimcha wrote: I've accumulated a bunch of little libraries via various evening and weekend hacking projects over the past year or so, in various states of completion. Most are things I'm at least half-considering for Phobos, though some belong as third-party libs. I definitely don't have time to finish/flesh out all of them anytime soon, so I've decided to ask the community what to prioritize. Below is a summary of everything I've been working on, with its current level of completion. Please let me know the following: 1. A relative ordering of how useful you think these libraries would be to the community. In order: 1. TempAlloc 2. Matrix ops (I'm biased here, of course...) 3. RandAA 4. CSV parser 5. Rational That said, it does make sense to start with the things which require the least amount of work. If it would take you half an hour to complete the rationals lib, for instance, that may be a good starting point. Regarding std.mixins, I have to agree with Andrei and the others that code should be organised by functionality and not implementation method. Having thought some more about it, I also think std.file is not the right place for GZip support. Phobos needs an std.compression package/module, and a method for bulk reading/writing of gzip files may well be a good start. Finally, I know next to nothing about machine learning, so I won't express any opinion about it. 2. In absolute terms, would you find this useful? Absolutely! 3. For the Phobos candidates, whether they're general enough to belong in the **standard** library. I agree with Don that TempAlloc is a candidate for druntime. Other than that, yes. I note that others have suggested that the matrix stuff go into Phobos. As long as it depends on BLAS, I would say that's out of the question. -Lars
Re: std.parallelism: Final review
On Fri, 04 Mar 2011 21:05:39 +, Lars T. Kyllingstad wrote: David Simcha has made a proposal for an std.parallelism module to be included in Phobos. We now begin the formal review process. The code repository and documentation can be found here: https://github.com/dsimcha/std.parallelism/wiki http://cis.jhu.edu/~dsimcha/d/phobos/std_parallelism.html I would like to remind everyone that there is now only one week left of the std.parallelism review period. If you have any comments, please speak now, so that David has time to make the changes. I realise that the module has been through several review cycles already, and that it is already in active use (by me, among others), so there probably won't be any big issues. However, if it gets voted into Phobos, that's it -- it will be an official part of the D standard library. So start nitpicking, folks! The voting will start next Friday, 25 March, and last for a week, until 1 April. -Lars
Re: Against enforce()
Don Wrote: Pure functions calling weakly pure functions are also weakly pure and so on. This effectively leaves you without purity. I presume you mean Pure functions calling weakly pure functions *would also be* weakly pure and so on. ? What's the difference?
Re: Library Development: What to finish/flesh out?
On 03/17/2011 11:25 PM, dsimcha wrote: On 3/17/2011 6:18 PM, spir wrote: I'd have much use for both below. On 03/17/2011 04:33 PM, dsimcha wrote: 1. Rational: A library for handling rational numbers exactly. Templated on integer type, can use BigInts for guaranteed accuracy, or fixed-width integers for more speed where the denominator and numerator will be small. Completion state: Mostly finished. Just need to fix a litte bit rot and submit for review. (Phobos candidate) For decimal exactitude, what about plain fixed point (with decimal factor and binary mantissa)? I wouldn't mind having this, but I see it as completely orthogonal to rational numbers and don't have any near-term intentions of implementing it. Right. 2. RandAA: A hash table implementation with deterministic memory management, based on randomized probing. Main advantage over builtin AAs is that it plays much nicer with the GC and multithreaded programs. Lookup times are also expected O(1) no matter how many collisions exist in modulus hash space, as long as there are few collisions in full 32- or 64-bit hash space. Completion state: Mostly finished. Just needs a little doc improvement, a few benchmarks and submission for review. (Phobos candidate) How complicated would it be to add (optional) support for keeping insertion order (for iteration only)? Thought at a // array with pointers to the cells holding key/value pairs. It's a good idea, but IMHO something like this should be templated on the type of the associative array and work with builtin AAs, etc., too. It should be a decorator or something: /** Wraps any type that conforms to the duck interface of an associative array to preserve ordering for iteration. */ struct OrderedAA(AA) { alias typeof(AA.init.keys.front) K; alias typeof(AA.init.values.front) V; K[] order; AA aa; void opIndexAssign(V val, K key) { if(!(key in aa)) { order ~= key; } aa[key] = val; } // opApply, etc. } Right too. But the reason I have not implemented it yet is I don't want to keep a // array of keys, which require AA lookup for each key. Instead, I thought at an array of pointers to where the (key:value) cells are stored (cell buckets), to avoid AA key lookups. This, I guess, requires tweaking the implementation of the actual data structure. Reason why I asked you as you are dfevelopping a new one (so, you may have such a use case in mind before design is frozen). I have not yet had a look at the implementation of builtin AAs to see whether this would be easy. I guess not: it just require catching the very moment where a new pair is placed into a given bucket corresponding to its hash value. (And possibly the same thing at re-hash time.) Denis -- _ vita es estrany spir.wikidot.com
Re: [TDPL] Russian translation of the book
Vladimir Panteleev vladi...@thecybershadow.net писал(а) в своём письме Wed, 16 Mar 2011 23:54:14 +0600: On Wed, 16 Mar 2011 19:10:29 +0200, Alexander Malakhov a...@programmer.net wrote: Russian publisher Символ-Плюс (Symobl-Plus) now is translating TDPL and they are asking for volunteers to * help translating guy with technical details * read final version If you wish to help, add your contacts on forum: http://www.symbol.ru/forum/viewtopic.php?f=4t=363 Note that the last message in that thread is from the last year. Actually it's from 2011.01.20. Go to the 2nd page :) [...] I've reviewed the introductions and the first chapter with over 30 corrections and some inquiries,but never got any feedback regarding them -I don't even know if they reached the translator, so I was a bit demotivated to continue. 30 corrections sounds great! Bad translations really really annoy me. If you haven't totally gave up on this, maybe you could ask on forum about what happened with your submission ? In the end it was chief editor, who started the thread, so the publisher should be serious about the book -- Alexander
Re: Against enforce()
On Fri, 18 Mar 2011 03:50:17 -0400, Kagamin s...@here.lot wrote: Steven Schveighoffer Wrote: As long as the delegate does not access shared/global data, it should be able to be pure. Even delegates which modify TLS data should be able to be pure (weak-pure, but still pure). Pure functions calling weakly pure functions are also weakly pure and so on. This effectively leaves you without purity. No. Strong-pure functions can call weak-pure functions and still can be strong-pure. That's the huge benefit of weak-pure functions -- you can modularize pure functions without having to change everything to immutable. -Steve
Re: Against enforce()
On Fri, 18 Mar 2011 04:34:54 -0400, Don nos...@nospam.com wrote: Steven Schveighoffer Wrote: As long as the delegate does not access shared/global data, it should be able to be pure. Even delegates which modify TLS data should be able to be pure (weak-pure, but still pure). TLS variables are global and must not be accessed from any function marked as pure. With regard to purity, there isn't any difference between shared and TLS variables. However, it's still not shared. This, for example, is a weak pure function: void foo(int *n) pure { *n = 5;} Because TLS variables are not shared, you should be able to do this: int x; void bar() { foo(x); } But you are right, there is a huge difference between a local reference to TLS data and directly accessing TLS data -- the latter can be obscured from the compiler, resulting in the compiler thinking the function can be strong pure. So I don't know exactly how to mitigate this, but in my mind, it feels like this should work: int foo(bool cond, lazy int n) pure { if(cond) return n; return 0;} int x; void bar() { foo(x == 4, x = 5); } It seems not too different from the above example where you pass the address of x. But obviously the x = 5 delegate cannot be pure (it modifies TLS data). We may have no recourse to get this to work. It may be a lost cause, and you just can't have lazy variables for pure functions. Cue the request for macros where you can just rewrite the syntax vs. having to use lazy in the first place... -Steve
Re: Against enforce()
On Fri, 18 Mar 2011 04:14:12 -0400, Kagamin s...@here.lot wrote: Walter Bright Wrote: 1. Asserts and contracts are for detecting program BUGS. They are not for validating user input, checking for disk full, file not found errors, etc. 2. Enforce is for validating user input, checking for disk full, file not found errors, etc. Enforce is NOT for use in contracts or checking for program bugs. Any use of enforce in Phobos that is checking for program bugs is itself a bug and should be entered into bugzilla for fixing. So this is a bug? This is a contract, not a validation of user input. struct Iota(N, S) if ((isIntegral!N || isPointer!N) isIntegral!S) { private N current, pastLast; private S step; this(N current, N pastLast, S step) { enforce((current = pastLast step 0) || (current = pastLast step 0)); this.current = current; this.step = step; This is a good example of why it's difficult to decide what user input is. One could consider that the 'user' in this case is the developer using the library, but I don't think that's the right choice. I'd say it's a bug, this is clearly a contract, since the data being passed into the ctor can easily not be user input (i.e. it's most likely two literals that will never depend on a user). If it is user input, the caller of the ctor should enforce the user input before passing it to iota. -Steve
Re: Why can't structs be derived from?
Bekenn leav...@alone.com wrote in message news:ilv2pd$1vkd$1...@digitalmars.com... On 3/17/2011 2:36 PM, Andrei Alexandrescu wrote: I'm with y'all too. Even Walter needs to stop and think for a second. We're considering enabling alias a = b; as an equivalent for alias b a; Along similar lines (hoping this isn't too far off-topic), what's the current plan for typedef? I'm aware that it's deprecated (and for good reason), but some of my reading suggests that there's a successor on the horizon. I was thinking of asking about that, too. Specifically, would it make sence for typedef b a; (or typedef a = b;) to be lowered to something like: struct a { b _tmp; alias _tmp this; } Hmm, then again, IIUC, that would allow 'a' to be implicity converted to 'b' which would defeat half the point, so maybe not.
Re: Why can't structs be derived from?
Andrei Alexandrescu seewebsiteforem...@erdani.org wrote in message news:iltv3a$2q93$2...@digitalmars.com... On 3/17/11 11:21 AM, Andrej Mitrovic wrote: On 3/17/11, Nick Sabalauskya@a.a wrote: I've long been convinced that alias old new; should really be alias new = old; The current way confuses me, and I *still* have to consciously stop and think about it every time I write an alias statement (including just now). I thought I was the only one. The `alias symbol this` in structs in particular always stops me and I have to think about what it means, even though it might be obvious. I'm with y'all too. Even Walter needs to stop and think for a second. We're considering enabling alias a = b; as an equivalent for alias b a; As a minor side-benefit, that would mean that the alias this feature *really would* involve the actual code alias this ;)
Re: Pull requests for multiple issues?
Jonathan M Davis Wrote: I would say that, generally speaking, unrelated changes should be separate pull requests, whereas related changes should be grouped together into a single pull request. Remember that it's all or nothing, so they're going to merge in all of your changes or none of them. So, if it makes sense for them to all go together, then put them together, but if they don't necessarily make sense to go together and it _would_ make sense to accept some of them but not all of them, then separate them. I thought when you were doing a pull request you could do whatever you wanted to bring in the changes you wanted, such as cherry-picking. But I agree it makes review and acceptance easier. The reviewer should be able/expected to accept all/nothing.
Re: a cabal for D ?
Russel Winder Wrote: At the expense of easy system administration. Specifics? It allows for one packaging system across all operating systems. This means you don't need to figure out how to package your source in RPM, Deb, ipgk, arc, emerge, zip, or whatever else Linux has. Otherwise I would be for using the native packaging system, but it isn't easy for the contributor, the maintainer of the server, or the one building a system that works with all of them.
Re: Pull requests for multiple issues?
Lars T. Kyllingstad wrote: On Thu, 17 Mar 2011 20:59:54 -0400, Nick Sabalausky wrote: I was thinking of converting my patches for various rdmd issues into github pull requests, but being relatively new to DVCSes (longtime SVN user here) I was wondering what's the kosher way to do it?: - A separate branch for each issue, with a pull request for each branch? - One branch with a separate commit for each issue, and a pull request for each commit? - One branch with a separate commit for each issue, and a pull request for the whole branch? If so, the root of the branch or the leaf of the branch? You need a separate branch for each pull request. Commits which depend on each other should of course be in a single branch. Other than that, I would recommend creating a separate branch/pull req. for each issue. That way, if the patch for issue X isn't approved, the patches for Y and Z can still be merged in. -Lars Cherry-picking works brilliantly in git. You don't need to worry about that. I would say, it's perfectly fine for multiple simple commits (each with 1-3 lines changed) to reside in the same branch. Something that involves many changes, especially to multiple files, should be in its own branch. If you create multiple branches and pull requests, each for single-line changes, you're just creating busywork.
Re: Against enforce()
On 03/18/2011 01:37 PM, Steven Schveighoffer wrote: This is a good example of why it's difficult to decide what user input is. One could consider that the 'user' in this case is the developer using the library, but I don't think that's the right choice. I'd say it's a bug, this is clearly a contract, since the data being passed into the ctor can easily not be user input (i.e. it's most likely two literals that will never depend on a user). If it is user input, the caller of the ctor should enforce the user input before passing it to iota. This is indeed a difficult topic. I'm a bit bluffed when reading people confidently asserting apparently clear positions about the use of enforce vs assert vs contracts and such, or whether such checks should or not stay or not in various distribution builds (mainly -release). I can see at least 5 cases, and am far to be sure what the proper tool is in every case, and in which builds it should stay. In each case, there is potential wrong input; but note the variety of cases does seems orthogonal (lol) to what kind of harm it may cause: * colleague: my code is called by code from the same app (same dev team); typically, wrong input logically cannot happen * friend: my code is called by code designed to cooperate with it; there is a kind of moral contract In both cases, wrong input reveals a bug; but in the first case, it's my own (team's) bug. I guess, but am not sure, these cases are good candidates for asserts (or contracts?), excluded from release build. * lib call: my code is a typical lib; thus, I have zero control on caller. I would let the check in release mode, thus use enforce. Or, use assert if it remains when the *caller* is compiled in debug mode. There is something unclear here, I guess. Maybe there are two sub-cases: ~ the caller logically should be able to prove its args correct ~ or not In the first case, checks should dispappear in release mode. But there is always a risk. So, what to choose if my func really requires correct input? By the way, I don't understand the diff between enforce and alwaysAssert; I thought enforce was precisely an alwaysAssert. * user input: cope with it. It's the only clear case for me. Denis -- _ vita es estrany spir.wikidot.com
Re: a cabal for D ?
2011/3/18 Jesse Phillips jessekphillip...@gmail.com: Russel Winder Wrote: At the expense of easy system administration. Specifics? It allows for one packaging system across all operating systems. This means you don't need to figure out how to package your source in RPM, Deb, ipgk, arc, emerge, zip, or whatever else Linux has. For the developer, yes. For the user, it just means that you have to learn N different packaging systems, which not uncommonly cause conflicts, for instance in language-bindings conflicting with native libraries. I know of at least one company that were quite serious about migrating their webapps from Java to Ruby/rails, but after a while cancelled due to just those packaging issues with gems creating weird conflicts and silent errors when bindings were complied slightly differently from the native C-lib. For the record, their apps were designed for deployment on Ubuntu Server, which at the time had native support for almost all Java-related packages, but less wide support for Ruby. The situation have changed a little since then, and quite a lot of Ruby-packages are now in native Ubuntu.
Re: Against enforce()
On Fri, 18 Mar 2011 11:35:22 -0400, spir denis.s...@gmail.com wrote: On 03/18/2011 01:37 PM, Steven Schveighoffer wrote: This is a good example of why it's difficult to decide what user input is. One could consider that the 'user' in this case is the developer using the library, but I don't think that's the right choice. I'd say it's a bug, this is clearly a contract, since the data being passed into the ctor can easily not be user input (i.e. it's most likely two literals that will never depend on a user). If it is user input, the caller of the ctor should enforce the user input before passing it to iota. This is indeed a difficult topic. I'm a bit bluffed when reading people confidently asserting apparently clear positions about the use of enforce vs assert vs contracts and such, or whether such checks should or not stay or not in various distribution builds (mainly -release). I can see at least 5 cases, and am far to be sure what the proper tool is in every case, and in which builds it should stay. In each case, there is potential wrong input; but note the variety of cases does seems orthogonal (lol) to what kind of harm it may cause: * colleague: my code is called by code from the same app (same dev team); typically, wrong input logically cannot happen * friend: my code is called by code designed to cooperate with it; there is a kind of moral contract In both cases, wrong input reveals a bug; but in the first case, it's my own (team's) bug. I guess, but am not sure, these cases are good candidates for asserts (or contracts?), excluded from release build. * lib call: my code is a typical lib; thus, I have zero control on caller. I would let the check in release mode, thus use enforce. Or, use assert if it remains when the *caller* is compiled in debug mode. There is something unclear here, I guess. Maybe there are two sub-cases: ~ the caller logically should be able to prove its args correct ~ or not See, this is where I feel we have issues. The clear problem with *always* checking is the iota example. One may use iota like this: foreach(i; iota(0, 5)) Why should checks in iota remain for iota to prove that 0 is less than 5? It always will be less than 5, and the check is not necessary. checks should only be in place during release when the input to the function cannot be proven at compile time. When it can be proven, then the checks should go away. The problem I see is it's iota's responsibility to do those checks, but it has no idea where the data comes from. What I would suggest is to check at the point the argument data is created, not at the point where it's used. So for instance, if you get the parameters for iota from an input file, then you need to check those arguments before passing to iota. This is a difficult problem to solve, because one party knows whether the arguments need to be checked, and the other party knows how to check the arguments. I don't know if there is a clean way to do this. My thoughts are that phobos should only use enforce where it can prove the arguments are runtime-generated, and rely on asserts otherwise. The obvious pitfall is that one could pass runtime-generated data to a phobos function which uses asserts, and the program could crash on an otherwise recoverable error because the user of phobos did not validate the input first. I think the risk here is less important than the reduction in performance that occurs when enforce is used instead. By the way, I don't understand the diff between enforce and alwaysAssert; I thought enforce was precisely an alwaysAssert. Assert throws an unrecoverable error, and its indication is that there is a problem in the code. An enforce throws a recoverable exception, and indicates there is a problem in the runtime input. -Steve
Re: Against enforce()
Steven Schveighoffer Wrote: This is a good example of why it's difficult to decide what user input is. One could consider that the 'user' in this case is the developer using the library, but I don't think that's the right choice. I'd say it's a bug, this is clearly a contract, since the data being passed into the ctor can easily not be user input (i.e. it's most likely two literals that will never depend on a user). If it is user input, the caller of the ctor should enforce the user input before passing it to iota. You can't validate all user input, so external data ends up spead across your entire application. So I don't understand obsession with -release switch, because contracts most of the time do validate user input. If we think about -release switch as a HP-hack for exotic code, there will be no ideological difference between assert and enforce.
Re: Different types with auto
On Fri, 18 Mar 2011 00:30:30 -, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 3/17/11 7:27 PM, KennyTM~ wrote: On Mar 18, 11 04:17, Jason E. Aten wrote: auto x1=1., x2=2., x3=3., x4=4., x5=5, x6=6.; If the coder wanted them to all be doubles, it's easy to require that by just saying so, and then even x5 will be a double. double x1=1., x2=2, ... So it seems to me that auto does exactly what you asked it to here, and I actually prefer this behavior for conciseness and expressiveness sake. auto x1 = templateFunctionWithComplicatedReturnType(a), x2 = templateFunctionWithComplicatedReturnType(b), x3 = templateFunctionWithComplicatedReturnType('c'), x4 = templateFunctionWithComplicatedReturnType(d); Yah, not sure what would ever be bad about that. Nor is there anything bad about this: auto x1 = templateFunctionWithComplicatedReturnType(a); auto x2 = templateFunctionWithComplicatedReturnType(b); auto x3 = templateFunctionWithComplicatedReturnType('c'); auto x4 = templateFunctionWithComplicatedReturnType(d); in fact, it lines up neatly so I prefer it :P -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Why can't structs be derived from?
On Thu, 17 Mar 2011 21:36:45 -, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 3/17/11 11:21 AM, Andrej Mitrovic wrote: On 3/17/11, Nick Sabalauskya@a.a wrote: I've long been convinced that alias old new; should really be alias new = old; The current way confuses me, and I *still* have to consciously stop and think about it every time I write an alias statement (including just now). I thought I was the only one. The `alias symbol this` in structs in particular always stops me and I have to think about what it means, even though it might be obvious. I'm with y'all too. Even Walter needs to stop and think for a second. We're considering enabling alias a = b; as an equivalent for alias b a; Yes please! -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Against enforce()
On 3/18/11 11:07 AM, Steven Schveighoffer wrote: On Fri, 18 Mar 2011 11:35:22 -0400, spir denis.s...@gmail.com wrote: On 03/18/2011 01:37 PM, Steven Schveighoffer wrote: This is a good example of why it's difficult to decide what user input is. One could consider that the 'user' in this case is the developer using the library, but I don't think that's the right choice. I'd say it's a bug, this is clearly a contract, since the data being passed into the ctor can easily not be user input (i.e. it's most likely two literals that will never depend on a user). If it is user input, the caller of the ctor should enforce the user input before passing it to iota. This is indeed a difficult topic. I'm a bit bluffed when reading people confidently asserting apparently clear positions about the use of enforce vs assert vs contracts and such, or whether such checks should or not stay or not in various distribution builds (mainly -release). I can see at least 5 cases, and am far to be sure what the proper tool is in every case, and in which builds it should stay. In each case, there is potential wrong input; but note the variety of cases does seems orthogonal (lol) to what kind of harm it may cause: * colleague: my code is called by code from the same app (same dev team); typically, wrong input logically cannot happen * friend: my code is called by code designed to cooperate with it; there is a kind of moral contract In both cases, wrong input reveals a bug; but in the first case, it's my own (team's) bug. I guess, but am not sure, these cases are good candidates for asserts (or contracts?), excluded from release build. * lib call: my code is a typical lib; thus, I have zero control on caller. I would let the check in release mode, thus use enforce. Or, use assert if it remains when the *caller* is compiled in debug mode. There is something unclear here, I guess. Maybe there are two sub-cases: ~ the caller logically should be able to prove its args correct ~ or not See, this is where I feel we have issues. The clear problem with *always* checking is the iota example. One may use iota like this: foreach(i; iota(0, 5)) Why should checks in iota remain for iota to prove that 0 is less than 5? It always will be less than 5, and the check is not necessary. [snip] This is the kind of job that the compiler could and should do. Whether it's assert and enforce, an inlining pass followed by value range propagation should simply eliminate the unnecessary tests. Andrei
internal representation of struct
Hello, I have array of type vertex_t vertices[] where vertex_t is: struct vertex_t { float[3] xyz; ubyte[4] color; ... } Now, I would like use instead of array float[3] xyz vec3f xyz, where vec3f is: struct vec3f { float x, y, z; ...some functions... } where I have defined some operators for adding and multipliing vectors etc. Is it possible? xyz must be exactly 3 floats in memory because I am sending vertices array pointer into OpenGL rendering pipeline. Will be struct vec3f represented just like 3 floats - aren't here some additional metadata - because structure contains also some functions? My additional question: What about effectivity? I would like keep struct vertex_t as simple as possible, because I need do calculations fast. Will have replacing float array to structure some impact on speed? Thank you.
Re: Against enforce()
On 03/18/2011 05:07 PM, Steven Schveighoffer wrote: On Fri, 18 Mar 2011 11:35:22 -0400, spir denis.s...@gmail.com wrote: On 03/18/2011 01:37 PM, Steven Schveighoffer wrote: This is a good example of why it's difficult to decide what user input is. One could consider that the 'user' in this case is the developer using the library, but I don't think that's the right choice. I'd say it's a bug, this is clearly a contract, since the data being passed into the ctor can easily not be user input (i.e. it's most likely two literals that will never depend on a user). If it is user input, the caller of the ctor should enforce the user input before passing it to iota. This is indeed a difficult topic. I'm a bit bluffed when reading people confidently asserting apparently clear positions about the use of enforce vs assert vs contracts and such, or whether such checks should or not stay or not in various distribution builds (mainly -release). I can see at least 5 cases, and am far to be sure what the proper tool is in every case, and in which builds it should stay. In each case, there is potential wrong input; but note the variety of cases does seems orthogonal (lol) to what kind of harm it may cause: * colleague: my code is called by code from the same app (same dev team); typically, wrong input logically cannot happen * friend: my code is called by code designed to cooperate with it; there is a kind of moral contract In both cases, wrong input reveals a bug; but in the first case, it's my own (team's) bug. I guess, but am not sure, these cases are good candidates for asserts (or contracts?), excluded from release build. * lib call: my code is a typical lib; thus, I have zero control on caller. I would let the check in release mode, thus use enforce. Or, use assert if it remains when the *caller* is compiled in debug mode. There is something unclear here, I guess. Maybe there are two sub-cases: ~ the caller logically should be able to prove its args correct ~ or not See, this is where I feel we have issues. The clear problem with *always* checking is the iota example. One may use iota like this: foreach(i; iota(0, 5)) Why should checks in iota remain for iota to prove that 0 is less than 5? It always will be less than 5, and the check is not necessary. checks should only be in place during release when the input to the function cannot be proven at compile time. When it can be proven, then the checks should go away. The problem I see is it's iota's responsibility to do those checks, but it has no idea where the data comes from. What I would suggest is to check at the point the argument data is created, not at the point where it's used. So for instance, if you get the parameters for iota from an input file, then you need to check those arguments before passing to iota. This is a difficult problem to solve, because one party knows whether the arguments need to be checked, and the other party knows how to check the arguments. I don't know if there is a clean way to do this. My thoughts are that phobos should only use enforce where it can prove the arguments are runtime-generated, and rely on asserts otherwise. The obvious pitfall is that one could pass runtime-generated data to a phobos function which uses asserts, and the program could crash on an otherwise recoverable error because the user of phobos did not validate the input first. I think the risk here is less important than the reduction in performance that occurs when enforce is used instead. Yes, I think you are correctly surrounding the issue. But my choice would rather be safety as default. Would you really let the func called by a/b non-check b!=0? Thus, I would consider allowing the caller stating don't check this call, not the opposite. Another issue is this creates one more complication in the language; and one orthogonal to the whole set of func-calls; with syntax needed, I guess. Another path is decision via compiler analysis: if arguments can be proved constant (I guess /this/ point can be made), then check is removed for release, automatically; else it cannot be removed at all. [Thanks for the precision about enforce vs alwaysAssert.] Denis -- _ vita es estrany spir.wikidot.com
Has the ban on returning function nested structs been lifted?
From TDPL, page 263: Nested struct objects cannot be returned from functions because the caller doesn't have access to their type. However auto seems to work around this limitation: module structInFunction; import std.stdio; void main() { auto local = foo(0); assert(local.sum() == 30); writeln(typeid(local)); // structInFunction.foo.Local } auto foo(int a) { int z = a + 10; struct Local { int x; int y; int sum() { return x + y + z; } } return Local(10, 10); } I don't have a use case for this, personally. But it does seem to work. Well, almost. The following issues a runtime error: module structInFunction; import std.stdio; void main() { auto local = foo(0); writeln(local.sum()); assert(local.sum() == 30); writeln(typeid(local)); // structInFunction.foo.Local } auto foo(int a) { int z = a + 10; struct Local { int x = 10; int y = 10; int sum() { return x + y + z; } } Local local; return local; } object.Error: Access Violation An explicit call to the ctor like this works with no runtime errors: auto local = Local(); return local;
Re: Dream package management system (Was: a cabal for D ?)
On 17/03/2011 22:49, Jason E. Aten wrote: Somewhat tongue in cheek, we could call it dabal. As in, get on dabal! :-) If D gets accepted for Google Summer of Code, I think this would be a great idea for a project and I would be interested in implementing it as a student. Although, it does seem overly ambitious so maybe only some of this could be for the gsoc (and if I do this It'd be great to carry on working on it anyway). What does everybody think about this? Should I draw up a proposal of some kind? Chris
Re: [TDPL] Russian translation of the book
On Fri, 18 Mar 2011 13:08:24 +0200, Alexander Malakhov a...@programmer.net wrote: Vladimir Panteleev vladi...@thecybershadow.net писал(а) в своём письме Wed, 16 Mar 2011 23:54:14 +0600: On Wed, 16 Mar 2011 19:10:29 +0200, Alexander Malakhov a...@programmer.net wrote: Russian publisher Символ-Плюс (Symobl-Plus) now is translating TDPL and they are asking for volunteers to * help translating guy with technical details * read final version If you wish to help, add your contacts on forum: http://www.symbol.ru/forum/viewtopic.php?f=4t=363 Note that the last message in that thread is from the last year. Actually it's from 2011.01.20. Go to the 2nd page :) Who puts paging controls at the top of threads? :s [...] I've reviewed the introductions and the first chapter with over 30 corrections and some inquiries,but never got any feedback regarding them -I don't even know if they reached the translator, so I was a bit demotivated to continue. 30 corrections sounds great! Bad translations really really annoy me. If you haven't totally gave up on this, maybe you could ask on forum about what happened with your submission ? In the end it was chief editor, who started the thread, so the publisher should be serious about the book I do plan to catch up - hopefully within a week or two. -- Best regards, Vladimirmailto:vladi...@thecybershadow.net
Re: Has the ban on returning function nested structs been lifted?
This seems to work with classes as well. The TDPL has an example of a class that subclasses a class definition in module scope. But this one is defined in function scope, doesn't derive, and still works: void main() { auto local = foo(0); assert(local.sum() == 30); } auto foo(int a) { int z = a + 10; class Local { int x = 10; int y = 10; int sum() { return x + y + z; } } return new Local(); }
Re: internal representation of struct
On 03/18/2011 05:34 PM, lenochware wrote: Hello, I have array of type vertex_t vertices[] where vertex_t is: struct vertex_t { float[3] xyz; ubyte[4] color; ... } Now, I would like use instead of array float[3] xyz vec3f xyz, where vec3f is: struct vec3f { float x, y, z; ...some functions... } where I have defined some operators for adding and multipliing vectors etc. Is it possible? xyz must be exactly 3 floats in memory because I am sending vertices array pointer into OpenGL rendering pipeline. I think --but not 100% sure-- you can count on having no diff in terms of memory layout. The gain in terms of code legibility is well worth it: vec.z vs vs[2] color.R vs color[0] Side-note: in the D community a coding style in starting to spread in which type names are capitalised: thus, would be Vertex instead of vertex_t, and Vec3f instead of vec3f. (This is for public code, indeed; I just inform.) Will be struct vec3f represented just like 3 floats - aren't here some additional metadata - because structure contains also some functions? Since struct member functions/methods are static, their calls are translated at compile time. There should thus be no diff with an external, free, function having a struct object as first argument. This is the main low-level diff with dynamic (virtual) methods. But don't take my words for sure information, I'd like someone to confirm this. My additional question: What about effectivity? I would like keep struct vertex_t as simple as possible, because I need do calculations fast. Will have replacing float array to structure some impact on speed? There should be no sensible difference noticeable. On modern architectures, pointer deref, array lookup and (static) member access are about the same speed. (Compared to speed of code that operates on data accessed that way). In fact, at a lower level, static member access is the same thing as array lookup (deref at base_pointer+offset). You may notice some difference on artificiallly empty benchmarks (doing nothing but accessing the data), but it's not representative. Denis -- _ vita es estrany spir.wikidot.com
Re: internal representation of struct
On 18.03.2011 17:34, lenochware wrote: Hello, I have array of type vertex_t vertices[] where vertex_t is: struct vertex_t { float[3] xyz; ubyte[4] color; ... } Now, I would like use instead of array float[3] xyz vec3f xyz, where vec3f is: struct vec3f { float x, y, z; ...some functions... } where I have defined some operators for adding and multipliing vectors etc. Is it possible? xyz must be exactly 3 floats in memory because I am sending vertices array pointer into OpenGL rendering pipeline. Will be struct vec3f represented just like 3 floats - aren't here some additional metadata - because structure contains also some functions? There is no metadata in structs. The only thing there is padding in order to align the fields. But floats have a size of 4 and alignment the same, so your vec3f will be exactly 12 bytes without any problem (done it myself for OpenGL) My additional question: What about effectivity? I would like keep struct vertex_t as simple as possible, because I need do calculations fast. Will have replacing float array to structure some impact on speed? depends: When you want to to a component-wise vector multiplication, you want the compiler to use SSE and alike. With float[3] a,b,c; c[] = a[]*b[]; That will probably work (that is one reason the []-notion exists in the first place). But with vec3f a,b,c; c.x = a.x*b.x; c.y=a.y*b.y; c.z=a.z*b.z; it really depends on the quality of the compiler if it sees the opportunity for optimisation. If you want to be sure, I suggest the following: struct vec3 { float[3] data; vec3 opMul(vec3 other) { vec3 tmp = this; tmp.data[] *= other.data[]; } } As a last note: When you do OpenGL, the biggest part of calculations should be done on the GPU, so the few on the CPU might not be performance critical at all. But that depends of course on the exact thing you want to do. - Krox
Re: Dream package management system (Was: a cabal for D ?)
On 03/18/2011 06:04 PM, Chris Manning wrote: On 17/03/2011 22:49, Jason E. Aten wrote: Somewhat tongue in cheek, we could call it dabal. As in, get on dabal! :-) If D gets accepted for Google Summer of Code, I think this would be a great idea for a project and I would be interested in implementing it as a student. Although, it does seem overly ambitious so maybe only some of this could be for the gsoc (and if I do this It'd be great to carry on working on it anyway). +++ What does everybody think about this? Should I draw up a proposal of some kind? Dunno how it's supposed to be done... Denis -- _ vita es estrany spir.wikidot.com
Re: Has the ban on returning function nested structs been lifted?
On 03/18/2011 06:05 PM, Andrej Mitrovic wrote: From TDPL, page 263: Nested struct objects cannot be returned from functions because the caller doesn't have access to their type. However auto seems to work around this limitation: module structInFunction; import std.stdio; void main() { auto local = foo(0); assert(local.sum() == 30); writeln(typeid(local)); // structInFunction.foo.Local } auto foo(int a) { int z = a + 10; struct Local { int x; int y; int sum() { return x + y + z; } } return Local(10, 10); } I don't have a use case for this, personally. But it does seem to work. Well, almost. The following issues a runtime error: module structInFunction; import std.stdio; void main() { auto local = foo(0); writeln(local.sum()); assert(local.sum() == 30); writeln(typeid(local)); // structInFunction.foo.Local } auto foo(int a) { int z = a + 10; struct Local { int x = 10; int y = 10; int sum() { return x + y + z; } } Local local; return local; } object.Error: Access Violation An explicit call to the ctor like this works with no runtime errors: auto local = Local(); return local; Great magic auto is. Auto with you be. Denis -- _ vita es estrany spir.wikidot.com
clear() not implemented as object method?
I just wondered why clear() which is there to call the desctructor of an object is implemented as a module function instead of being an object method in object_d. Is there a technical reason for it I don't recognise? unittest { auto b = new Buffer; clear(b); // Wouldn't b.clear() be nicer? } Thomas
Re: clear() not implemented as object method?
On Fri, 18 Mar 2011 13:13:27 -0400, Thomas Mader thomas.ma...@gmail.com wrote: I just wondered why clear() which is there to call the desctructor of an object is implemented as a module function instead of being an object method in object_d. Is there a technical reason for it I don't recognise? unittest { auto b = new Buffer; clear(b); // Wouldn't b.clear() be nicer? } It's a template that handles any type, class object, struct instance, int, float, etc. -Steve
Re: Against enforce()
On Fri, 18 Mar 2011 12:31:23 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 3/18/11 11:07 AM, Steven Schveighoffer wrote: On Fri, 18 Mar 2011 11:35:22 -0400, spir denis.s...@gmail.com wrote: On 03/18/2011 01:37 PM, Steven Schveighoffer wrote: This is a good example of why it's difficult to decide what user input is. One could consider that the 'user' in this case is the developer using the library, but I don't think that's the right choice. I'd say it's a bug, this is clearly a contract, since the data being passed into the ctor can easily not be user input (i.e. it's most likely two literals that will never depend on a user). If it is user input, the caller of the ctor should enforce the user input before passing it to iota. This is indeed a difficult topic. I'm a bit bluffed when reading people confidently asserting apparently clear positions about the use of enforce vs assert vs contracts and such, or whether such checks should or not stay or not in various distribution builds (mainly -release). I can see at least 5 cases, and am far to be sure what the proper tool is in every case, and in which builds it should stay. In each case, there is potential wrong input; but note the variety of cases does seems orthogonal (lol) to what kind of harm it may cause: * colleague: my code is called by code from the same app (same dev team); typically, wrong input logically cannot happen * friend: my code is called by code designed to cooperate with it; there is a kind of moral contract In both cases, wrong input reveals a bug; but in the first case, it's my own (team's) bug. I guess, but am not sure, these cases are good candidates for asserts (or contracts?), excluded from release build. * lib call: my code is a typical lib; thus, I have zero control on caller. I would let the check in release mode, thus use enforce. Or, use assert if it remains when the *caller* is compiled in debug mode. There is something unclear here, I guess. Maybe there are two sub-cases: ~ the caller logically should be able to prove its args correct ~ or not See, this is where I feel we have issues. The clear problem with *always* checking is the iota example. One may use iota like this: foreach(i; iota(0, 5)) Why should checks in iota remain for iota to prove that 0 is less than 5? It always will be less than 5, and the check is not necessary. [snip] This is the kind of job that the compiler could and should do. Whether it's assert and enforce, an inlining pass followed by value range propagation should simply eliminate the unnecessary tests. In this simple case yes, but inlining is not forceable, so you should not rely on it for optimizing out asserts or enforce. Inlining also only goes so deep, it doesn't make sense to inline a whole program, so at some point, you are going to use a function call, even though it can be proven the data is within range. From what I can see, we have 3 cases: 1. those where we can prove beyond a doubt that whether a value is valid is runtime dependent. Those cases should obviously use enforce. 2. Those where we can prove beyond a doubt that whether a value is valid does not depend on runtime data. Those cases should obviously use assert. 3. You can't prove beyond a doubt where those values come from. It's case 3 that is the troublesome one, not because it's hard to prove whether it's case 3 or not, but because the code that knows what the data could be (the caller) is separate from the code which knows whether its valid (the callee). It's also case 3 which is the most common. The most common case is a library function which wants to validate its input. So with the tools we have at hand today, which one should be applied to case 3? My preference is to use assert because then the caller has control over whether the data is checked or not. If you use enforce, the caller has no way of saying no really, I checked that value already!. Note also that phobos functions may be double checking data ALREADY if they make calls to each other. -Steve
Re: internal representation of struct
Am 18.03.2011 17:34, schrieb lenochware: Hello, I have array of type vertex_t vertices[] where vertex_t is: struct vertex_t { float[3] xyz; ubyte[4] color; ... } Now, I would like use instead of array float[3] xyz vec3f xyz, where vec3f is: struct vec3f { float x, y, z; ...some functions... } where I have defined some operators for adding and multipliing vectors etc. Is it possible? xyz must be exactly 3 floats in memory because I am sending vertices array pointer into OpenGL rendering pipeline. Will be struct vec3f represented just like 3 floats - aren't here some additional metadata - because structure contains also some functions? My additional question: What about effectivity? I would like keep struct vertex_t as simple as possible, because I need do calculations fast. Will have replacing float array to structure some impact on speed? Thank you. Why not do something like: struct vec3f { float[3] xyz; @property float x() { return xyz[0]; } // read x @property float x(float val) { return xyz[0] = val; } // write x // and the same for y and z ... // ... and your own functions } This would allow to easily use array optimizations (SSE etc) - just add an overload for e.g. * and let it do xyz[] * othervec[] or similar.. And you'd make sure that it's really an array without any alignment (not sure if alignment on amd64 would be different from x86). And still you could write, because of the properties, vec3f v1; v1.x = 4.2; v1.y = 12.3; v1.z = v1.y-v1.x; and so on. Cheers, - Daniel
Re: Against enforce()
On Friday, March 18, 2011 09:08:38 Kagamin wrote: Steven Schveighoffer Wrote: This is a good example of why it's difficult to decide what user input is. One could consider that the 'user' in this case is the developer using the library, but I don't think that's the right choice. I'd say it's a bug, this is clearly a contract, since the data being passed into the ctor can easily not be user input (i.e. it's most likely two literals that will never depend on a user). If it is user input, the caller of the ctor should enforce the user input before passing it to iota. You can't validate all user input, so external data ends up spead across your entire application. So I don't understand obsession with -release switch, because contracts most of the time do validate user input. If we think about -release switch as a HP-hack for exotic code, there will be no ideological difference between assert and enforce. The idea is that if an assertion fails, there is a bug in your program. You _cannot_ rely on an assertion being run, because it could be compiled out. It is _only_ for verifying that your code is correct. Exceptions, on the other hand, are used for handling errors. If something which results in an error but which is _not_ a logic bug in your program, then it should be handled by an exception. User input would be a classic example of this. If you get bad user input, that's not the program's fault. It can verify that the user input is valid and then assume that it's valid after that (at which point, using assert would make sense, because it's supposed to be guaranteed that the values are valid, since they were validated). But in handling the user input, it would throw on error, not assert. enforce is merely a shorthand way of testing and throw exceptions on failure. It makes exception handling look like assertions. But it is an _entirely_ different thing. As has been point out, the problem is in cases where it's not clear whether you should treat input as user input (and therefore needs to _always_ be checked and have exceptions thrown on error) or whether you should treat input as being from your program and guaranteed to be valid (at which point you use assert to check that that guarantee actually holds). Assertions are _not_ for error handling. They _kill_ your program on failure (since they throw an Assert_Error_, not an exception). Exceptions (and therefore enforce) are for error handling. There is a _clear_ and _distinct_ difference between the two. The confusion is not between assert and enforce. The confusion is when you have a situation where whether assert or enforce is appropriate depends on how the function is being used. - Jonathan M Davis
Re: Pull requests for multiple issues?
On Friday, March 18, 2011 07:26:38 Jesse Phillips wrote: Jonathan M Davis Wrote: I would say that, generally speaking, unrelated changes should be separate pull requests, whereas related changes should be grouped together into a single pull request. Remember that it's all or nothing, so they're going to merge in all of your changes or none of them. So, if it makes sense for them to all go together, then put them together, but if they don't necessarily make sense to go together and it _would_ make sense to accept some of them but not all of them, then separate them. I thought when you were doing a pull request you could do whatever you wanted to bring in the changes you wanted, such as cherry-picking. But I agree it makes review and acceptance easier. The reviewer should be able/expected to accept all/nothing. You have all of git's capabilities when you do a pull request. You could do the pull request into your own branch and then cherry pick just the ones that you want, certainly. However, the pull request itself is for the full branch. It's not done by commits but by branch. And I would generally expect that a pull request would contain a related set of changes such that cherry picking them likely wouldn't make sense. However, as Don points out, if you have a lot of unrelated changes which are small, then it could be desirable to have a single pull request for all of them. Still, I wouldn't expect someone merging them in to normally cherry pick the parts of a pull request that they thought were good. That would create extra work too. So, on the whole, I would expect pull requests to contain related changes which should either be merged in as a whole on not merged in at all. Any further commits to the branch before it's pulled in will be added to the pull request, so reviewers can request that the person doing the pull request make any necessary changes be made before it's pulled in, which should generally avoid any need to cherry pick anything, even in cases where several smaller changes were grouped together. - Jonathan M Davis
Re: internal representation of struct
On Friday, March 18, 2011 10:14:34 spir wrote: Side-note: in the D community a coding style in starting to spread in which type names are capitalised: thus, would be Vertex instead of vertex_t, and Vec3f instead of vec3f. (This is for public code, indeed; I just inform.) LOL. That's the way that _most_ languages do it, I believe. C is one of the odd ones in that it isn't all that common there. Most everywhere else though it's normal to capitalize type names. So, I wouldn't say that it's really the case that the practice is starting to spread so much as anyone who hasn't been capitalizing their type names is likely from a C background and is likely the odd man out as far as what's typical goes. It's typical in most object-oriented languages to capitalize type names. - Jonathan M Davis
Re: Has the ban on returning function nested structs been lifted?
On Friday, March 18, 2011 10:19:10 spir wrote: On 03/18/2011 06:05 PM, Andrej Mitrovic wrote: From TDPL, page 263: Nested struct objects cannot be returned from functions because the caller doesn't have access to their type. However auto seems to work around this limitation: module structInFunction; import std.stdio; void main() { auto local = foo(0); assert(local.sum() == 30); writeln(typeid(local)); // structInFunction.foo.Local } auto foo(int a) { int z = a + 10; struct Local { int x; int y; int sum() { return x + y + z; } } return Local(10, 10); } I don't have a use case for this, personally. But it does seem to work. Well, almost. The following issues a runtime error: module structInFunction; import std.stdio; void main() { auto local = foo(0); writeln(local.sum()); assert(local.sum() == 30); writeln(typeid(local)); // structInFunction.foo.Local } auto foo(int a) { int z = a + 10; struct Local { int x = 10; int y = 10; int sum() { return x + y + z; } } Local local; return local; } object.Error: Access Violation An explicit call to the ctor like this works with no runtime errors: auto local = Local(); return local; Great magic auto is. Auto with you be. Yeah. Actually, Andrei has been making changes to std.range and std.algorithm so that _most_ functions which return new range types work this way. So, if TDPL says that it's illegal, it probably needs to be changed. Either that or we need to stop switching over to doing things that way. On the whole though, it strikes me as a positive change. - Jonathan M Davis
Re: Against enforce()
Steven Schveighoffer wrote: On Fri, 18 Mar 2011 04:34:54 -0400, Don nos...@nospam.com wrote: Steven Schveighoffer Wrote: As long as the delegate does not access shared/global data, it should be able to be pure. Even delegates which modify TLS data should be able to be pure (weak-pure, but still pure). TLS variables are global and must not be accessed from any function marked as pure. With regard to purity, there isn't any difference between shared and TLS variables. However, it's still not shared. This, for example, is a weak pure function: void foo(int *n) pure { *n = 5;} Because TLS variables are not shared, you should be able to do this: int x; void bar() { foo(x); } Yes, that compiles fine. But bar() is not pure. But you are right, there is a huge difference between a local reference to TLS data and directly accessing TLS data -- the latter can be obscured from the compiler, resulting in the compiler thinking the function can be strong pure. So I don't know exactly how to mitigate this, but in my mind, it feels like this should work: int foo(bool cond, lazy int n) pure { if(cond) return n; return 0;} int x; void bar() { foo(x == 4, x = 5); } It seems not too different from the above example where you pass the address of x. But obviously the x = 5 delegate cannot be pure (it modifies TLS data). We may have no recourse to get this to work. It may be a lost cause, and you just can't have lazy variables for pure functions. It's not a lost cause, it's a two-liner! mtype.c line 5045: if (fparam-storageClass STClazy) { -error(0, cannot have lazy parameters to a pure function); +tf-purity = PUREweak; +break; } This is a bit conservative: it would be possible to allow lazy parameters to be marked as pure, which would allow them to be strongly pure. But that would probably not be worth the extra complexity.
Re: a cabal for D ?
On Fri, 2011-03-18 at 10:41 -0400, Jesse Phillips wrote: [ . . . ] Otherwise I would be for using the native packaging system, but it isn't easy for the contributor, the maintainer of the server, or the one building a system that works with all of them. The problem is that the system administrator wants to use just the OS packaging system to make things easy for them to maintain the system. The user wants to be able to install stuff easily and may not have sufficient permissions to actually use the OS packaging system. Sys admins don't want to have to learn N packages to deal with N languages, the use probably only works in a couple of languages and so doesn't care if they have to learn two different packagin systems so as to get stuff done. This is not an easy issue. I just find the knee-jerk reaction of we have this new language therefore we must have a brand new (build system| packaging system|shell|implementation of every comms protocol|new user interface library|operating system) leads to too many distractions from getting stuff done using the good tools that are already available. I still think basing a D packaging system on Git to be the best direction. -- Russel. = Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.win...@ekiga.net 41 Buckmaster Roadm: +44 7770 465 077 xmpp: rus...@russel.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder signature.asc Description: This is a digitally signed message part
Re: Against enforce()
On Fri, 18 Mar 2011 14:35:27 -0400, Don nos...@nospam.com wrote: Steven Schveighoffer wrote: On Fri, 18 Mar 2011 04:34:54 -0400, Don nos...@nospam.com wrote: Steven Schveighoffer Wrote: As long as the delegate does not access shared/global data, it should be able to be pure. Even delegates which modify TLS data should be able to be pure (weak-pure, but still pure). TLS variables are global and must not be accessed from any function marked as pure. With regard to purity, there isn't any difference between shared and TLS variables. However, it's still not shared. This, for example, is a weak pure function: void foo(int *n) pure { *n = 5;} Because TLS variables are not shared, you should be able to do this: int x; void bar() { foo(x); } Yes, that compiles fine. But bar() is not pure. But you are right, there is a huge difference between a local reference to TLS data and directly accessing TLS data -- the latter can be obscured from the compiler, resulting in the compiler thinking the function can be strong pure. So I don't know exactly how to mitigate this, but in my mind, it feels like this should work: int foo(bool cond, lazy int n) pure { if(cond) return n; return 0;} int x; void bar() { foo(x == 4, x = 5); } It seems not too different from the above example where you pass the address of x. But obviously the x = 5 delegate cannot be pure (it modifies TLS data). We may have no recourse to get this to work. It may be a lost cause, and you just can't have lazy variables for pure functions. It's not a lost cause, it's a two-liner! mtype.c line 5045: if (fparam-storageClass STClazy) { -error(0, cannot have lazy parameters to a pure function); +tf-purity = PUREweak; +break; } This is a bit conservative: it would be possible to allow lazy parameters to be marked as pure, which would allow them to be strongly pure. But that would probably not be worth the extra complexity. I'm not sure this works. Aren't you allowed to pass in a delegate to a lazy parameter? For example: shared int x; int foo() { return x; } int bar(lazy int n) pure { return n; } void baz() { bar(foo); } or alternatively: void baz() { bar(x); } The no-shared-data rule prevents you from passing in a shared int reference to a pure function, but how do you stop a delegate from accessing shared data? -Steve
Re: Library Development: What to finish/flesh out?
Hi Lars, I agree on your orderbut would like to see Matrix ops in Phobos over time (my understanding was that it can work without BLAS (just slower), people can always in BLAS when they need to extra performance, no?). David, thanks a lot for your hard work... On 18/03/2011 09:26, Lars T. Kyllingstad wrote: On Thu, 17 Mar 2011 15:33:10 +, dsimcha wrote: I've accumulated a bunch of little libraries via various evening and weekend hacking projects over the past year or so, in various states of completion. Most are things I'm at least half-considering for Phobos, though some belong as third-party libs. I definitely don't have time to finish/flesh out all of them anytime soon, so I've decided to ask the community what to prioritize. Below is a summary of everything I've been working on, with its current level of completion. Please let me know the following: 1. A relative ordering of how useful you think these libraries would be to the community. In order: 1. TempAlloc 2. Matrix ops (I'm biased here, of course...) 3. RandAA 4. CSV parser 5. Rational That said, it does make sense to start with the things which require the least amount of work. If it would take you half an hour to complete the rationals lib, for instance, that may be a good starting point. Regarding std.mixins, I have to agree with Andrei and the others that code should be organised by functionality and not implementation method. Having thought some more about it, I also think std.file is not the right place for GZip support. Phobos needs an std.compression package/module, and a method for bulk reading/writing of gzip files may well be a good start. Finally, I know next to nothing about machine learning, so I won't express any opinion about it. 2. In absolute terms, would you find this useful? Absolutely! 3. For the Phobos candidates, whether they're general enough to belong in the **standard** library. I agree with Don that TempAlloc is a candidate for druntime. Other than that, yes. I note that others have suggested that the matrix stuff go into Phobos. As long as it depends on BLAS, I would say that's out of the question. -Lars
Re: Different types with auto
On 2011-03-17 21:35, Nick Sabalausky wrote: bearophilebearophileh...@lycos.com wrote in message news:iltdqr$1rd7$1...@digitalmars.com... D disallows bug-prone C syntax like this (C style guides strongly suggest to declare only each variable in a distinct statement and line of code): int a = 1, *b = null; D accepts code like: auto a = 1, b = null; This seems against the D rule of not allowing different types to be initialized in the same statement. In my opinion on this design detail D is worse than C++0x. As an example, if you write a line of code like this, meaning it to initialize six double variables, you have a bug: auto x1=1., x2=2., x3=3., x4=4., x5=5, x6=6.; I'm not sure how I feel about D's auto creating multiple types in one statement. But at the very least, I think your code above is yet another good example of why 1. and .1 float-literal syntax needs to die, die, die. It does what? Saves one character just so it can be less readable and cause syntax problems for new potential features? Bah. Yes, it must die. It also conflicts with uniform function call syntax. There are only few (one?) other thing(s) that I think C++0x gets better than D, like a more strict enum, I don't understand why D doesn't follows C++0x design on this other detail: http://d.puremagic.com/issues/show_bug.cgi?id=3999 I agree that would be nice. Weak typing like that is one of the reasons I abandoned C/C++, but D still holds on to it in this particular case. -- /Jacob Carlborg
Re: Has the ban on returning function nested structs been lifted?
On 3/18/11 1:21 PM, Jonathan M Davis wrote: Yeah. Actually, Andrei has been making changes to std.range and std.algorithm so that _most_ functions which return new range types work this way. So, if TDPL says that it's illegal, it probably needs to be changed. Either that or we need to stop switching over to doing things that way. On the whole though, it strikes me as a positive change. - Jonathan M Davis Yah, TDPL needs changing. Auto returns + local types = just awesome. Andrei
Re: Different types with auto
Jacob Carlborg: Yes, it must die. It also conflicts with uniform function call syntax. Currently this is mixed with the octal literals discussion: http://d.puremagic.com/issues/show_bug.cgi?id=2656 http://d.puremagic.com/issues/show_bug.cgi?id=3837 But I think it's better to move it to a specific enhancement request about FP literals only. Bye, bearophile
Re: Has the ban on returning function nested structs been lifted?
On Friday 18 March 2011 12:48:17 Andrei Alexandrescu wrote: On 3/18/11 1:21 PM, Jonathan M Davis wrote: Yeah. Actually, Andrei has been making changes to std.range and std.algorithm so that _most_ functions which return new range types work this way. So, if TDPL says that it's illegal, it probably needs to be changed. Either that or we need to stop switching over to doing things that way. On the whole though, it strikes me as a positive change. - Jonathan M Davis Yah, TDPL needs changing. Auto returns + local types = just awesome. Actually, the coolest part about it IMHO is that it highlights the fact that you should be using auto with std.algorithm and _not_ care about the exact types of the return types. Knowing the exact return type for those functions is generally unnecessary and is often scary anyway (especially with the functions which return lazy ranges like map and until). Making the functions return auto and completely hiding the return type pretty much forces the issue. There's still likely to be some confusion for those new to D, but it makes the proper way to use std.algorithm more obvious. I'd hate to deal with any code which used std.algorithm without auto. That would get ugly _fast_. So, yeah. auto returns + local types are indeed awesome. - Jonathan M Davis
Re: internal representation of struct
On Fri, 18 Mar 2011 18:34:19 +0200, lenochware lenochw...@gmail.com wrote: Hello, I have array of type vertex_t vertices[] where vertex_t is: struct vertex_t { float[3] xyz; ubyte[4] color; ... } Now, I would like use instead of array float[3] xyz vec3f xyz, where vec3f is: struct vec3f { float x, y, z; ...some functions... } where I have defined some operators for adding and multipliing vectors etc. Is it possible? xyz must be exactly 3 floats in memory because I am sending vertices array pointer into OpenGL rendering pipeline. Will be struct vec3f represented just like 3 floats - aren't here some additional metadata - because structure contains also some functions? My additional question: What about effectivity? I would like keep struct vertex_t as simple as possible, because I need do calculations fast. Will have replacing float array to structure some impact on speed? Thank you. D struct is POD. If you replace it with a struct, the speed is up to you since an array implementation might use cpu specific extensions.
Re: Has the ban on returning function nested structs been lifted?
Can auto functions with local types work if you're distributing your library in binary form (.lib) and only .di interface files?
On alias a = b
alias a(T) = b(T, known_type); Would it be an overkill?
Re: On alias a = b
On 3/18/11 3:28 PM, so wrote: alias a(T) = b(T, known_type); Would it be an overkill? It's part of the evil plan. Andrei
Re: On alias a = b
On Mar 19, 11 04:28, so wrote: alias a(T) = b(T, known_type); Would it be an overkill? If B is a template I think it's more consistent to add a '!': alias A(T) = B!(T, int); But I don't think it worth such generalization given the existing syntax already works: template A(T) { alias B!(T, int) A; // alias A = B!(T, known_type); }
Re: On alias a = b
On Fri, 18 Mar 2011 16:37:49 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 3/18/11 3:28 PM, so wrote: alias a(T) = b(T, known_type); Would it be an overkill? It's part of the evil plan. (I think there is a typo above, shouldn't it be alias a(T) = b!(T, known_type) ? ) You mean you would no longer need the surrounding template declaration? i.e. the above (corrected) statement would be short for: template a(T) { alias a = b!(T, known_type); } That would be certainly very un-evil ;) -Steve
Re: Against enforce()
I would say it is a bug in the contract. The signature is not normalized and the user gets a chance to provide conflicting parameters. I think that it would be best to deduce the direction from the order of the start and end parameters. Then the stepsize can be made absolute. Am 18.03.2011 09:14, schrieb Kagamin: So this is a bug? This is a contract, not a validation of user input. struct Iota(N, S) if ((isIntegral!N || isPointer!N) isIntegral!S) { private N current, pastLast; private S step; this(N current, N pastLast, S step) { enforce((current= pastLast step 0) || (current= pastLast step 0)); this.current = current; this.step = step;
Re: On alias a = b
On Mar 19, 11 04:41, Steven Schveighoffer wrote: On Fri, 18 Mar 2011 16:37:49 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 3/18/11 3:28 PM, so wrote: alias a(T) = b(T, known_type); Would it be an overkill? It's part of the evil plan. (I think there is a typo above, shouldn't it be alias a(T) = b!(T, known_type) ? ) You mean you would no longer need the surrounding template declaration? i.e. the above (corrected) statement would be short for: template a(T) { alias a = b!(T, known_type); } That would be certainly very un-evil ;) -Steve Being evil would be: alias staticReduce(alias F, alias Init) = Init; alias staticReduce(alias F, alias Init, T...) if (T.length != 0) = staticReduce!(F, F!(Init, T[0]), T[1..$]); //^ support conditionals? enum addSize(int total, T) = total + T.sizeof; // ^ yeah why not generalize to enum too? static assert(staticReduce!(addSize, 0, byte, short, int, long[2], float, double) == 35); ;)
Re: std.parallelism: Final review
== Quote from Lars T. Kyllingstad (public@kyllingen.NOSPAMnet)'s article On Fri, 04 Mar 2011 21:05:39 +, Lars T. Kyllingstad wrote: David Simcha has made a proposal for an std.parallelism module to be included in Phobos. We now begin the formal review process. The code repository and documentation can be found here: https://github.com/dsimcha/std.parallelism/wiki http://cis.jhu.edu/~dsimcha/d/phobos/std_parallelism.html I would like to remind everyone that there is now only one week left of the std.parallelism review period. If you have any comments, please speak now, so that David has time to make the changes. I realise that the module has been through several review cycles already, and that it is already in active use (by me, among others), so there probably won't be any big issues. However, if it gets voted into Phobos, that's it -- it will be an official part of the D standard library. So start nitpicking, folks! The voting will start next Friday, 25 March, and last for a week, until 1 April. -Lars It's kinda interesting--I don't know at all where this lib stands. The deafening silence for the past week makes me think one of two things is true: 1. std.parallelism solves a problem that's too niche for 90% of D users, or 2. It's already been through so many rounds of discussion in various places (informally with friends, then on the Phobos list, then on this NG) that there really is nothing left to nitpick. I have no idea which of these is true.
Re: clear() not implemented as object method?
Steven Schveighoffer Wrote: On Fri, 18 Mar 2011 13:13:27 -0400, Thomas Mader thomas.ma...@gmail.com wrote: I just wondered why clear() which is there to call the desctructor of an object is implemented as a module function instead of being an object method in object_d. Is there a technical reason for it I don't recognise? unittest { auto b = new Buffer; clear(b); // Wouldn't b.clear() be nicer? } It's a template that handles any type, class object, struct instance, int, float, etc. -Steve also b.clear() is a Container function for emptying the container.
Re: On alias a = b
On Fri, 18 Mar 2011 21:41:56 +0100, Steven Schveighoffer schvei...@yahoo.com wrote: On Fri, 18 Mar 2011 16:37:49 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org wrote: On 3/18/11 3:28 PM, so wrote: alias a(T) = b(T, known_type); Would it be an overkill? It's part of the evil plan. (I think there is a typo above, shouldn't it be alias a(T) = b!(T, known_type) ? ) Could also be used for currying, I guess. void foo(int i, string s){} void foo(float f, string s){} alias bar(value) = foo(value, Move along); -- Simen
Re: Why can't structs be derived from?
On Fri, 18 Mar 2011 15:09:23 +0100, Nick Sabalausky a@a.a wrote: Bekenn leav...@alone.com wrote in message news:ilv2pd$1vkd$1...@digitalmars.com... On 3/17/2011 2:36 PM, Andrei Alexandrescu wrote: I'm with y'all too. Even Walter needs to stop and think for a second. We're considering enabling alias a = b; as an equivalent for alias b a; Along similar lines (hoping this isn't too far off-topic), what's the current plan for typedef? I'm aware that it's deprecated (and for good reason), but some of my reading suggests that there's a successor on the horizon. I was thinking of asking about that, too. Specifically, would it make sence for typedef b a; (or typedef a = b;) to be lowered to something like: struct a { b _tmp; alias _tmp this; } Hmm, then again, IIUC, that would allow 'a' to be implicity converted to 'b' which would defeat half the point, so maybe not. Yeah. Typedef is too blunt an instrument for our purposes. What we want is: alias Subtype!int SubInt; alias Supertype!int SupInt; alias Standalone!int NaturalNumber; Where the following work: int a = SubInt(3); SupInt b = 3; NaturalNumber c = NaturalNumber(3); and the following do not: SubInt d = 3; int e = SupInt(3); NaturalNumber f = 3; int g = NaturalNumber(3); And of course: alias Subtype!int SubInt2; alias Supertype!int SupInt2; alias Standalone!int NaturalNumber2; Where these do not work: SubInt2 h = SubInt(3); SupInt2 i = SupInt(3); NaturalNumber2 j = NaturalNumber(3); -- Simen
Re: std.parallelism: Final review
On 3/18/11 3:55 PM, dsimcha wrote: == Quote from Lars T. Kyllingstad (public@kyllingen.NOSPAMnet)'s article On Fri, 04 Mar 2011 21:05:39 +, Lars T. Kyllingstad wrote: David Simcha has made a proposal for an std.parallelism module to be included in Phobos. We now begin the formal review process. The code repository and documentation can be found here: https://github.com/dsimcha/std.parallelism/wiki http://cis.jhu.edu/~dsimcha/d/phobos/std_parallelism.html I would like to remind everyone that there is now only one week left of the std.parallelism review period. If you have any comments, please speak now, so that David has time to make the changes. I realise that the module has been through several review cycles already, and that it is already in active use (by me, among others), so there probably won't be any big issues. However, if it gets voted into Phobos, that's it -- it will be an official part of the D standard library. So start nitpicking, folks! The voting will start next Friday, 25 March, and last for a week, until 1 April. -Lars It's kinda interesting--I don't know at all where this lib stands. The deafening silence for the past week makes me think one of two things is true: 1. std.parallelism solves a problem that's too niche for 90% of D users, or 2. It's already been through so many rounds of discussion in various places (informally with friends, then on the Phobos list, then on this NG) that there really is nothing left to nitpick. I have no idea which of these is true. Probably a weighted average of the two. If I were to venture a guess I'd ascribe more weight to 1. This is partly because I'm also receiving relatively little feedback on the concurrency chapter in TDPL. Also the general pattern on many such discussion groups is that the amount of traffic on a given topic is inversely correlated with its complexity. FWIW a review is on my todo list. Anyway, I'm glad we have gotten the terminology (concurrency and parallelism) so nicely. See http://www.reddit.com/r/programming/comments/g6k0p/parallelism_is_not_concurrency/ Andrei
Re: a cabal for D ?
On Fri, 18 Mar 2011 18:42:36 +, Russel Winder wrote: I still think basing a D packaging system on Git to be the best direction. Basing package distribution on Git or hg could be a big win, and would help establish a customary case for revision control which is one of the things that make cabal work so well (they use darcs for everything). I find these revision control systems ver fast and very easy to use. The other thing that cabal standardizes is the make/build system. I've updated bud/build to compile under D2, with all the latest patches, but I'm far from convinced that it should be a make system of choice. I have limited experience here, but a D aware build system would seem to be highly preferable. What are people's experiences with the various options for build systems with D? To me, I like the design goals of Andreas Fredriksson's Tundra build system (he wants speed of incremental of builds prioritized over all else, which means utilizing multicores for builds as much as possible to get the quickest build), because fast builds are critical for game development, where D is very attractive. Game projects compile tens of thousands of files. Tundra is GPL and it would be easy to extend to support D. http://voodoo-slide.blogspot.com/2010/08/tundra-my-build-system.html https://github.com/deplinenoise/tundra https://github.com/deplinenoise/tundra/downloads
Re: std.parallelism: Final review
On 18/03/11 10.40, Lars T. Kyllingstad wrote: On Fri, 04 Mar 2011 21:05:39 +, Lars T. Kyllingstad wrote: David Simcha has made a proposal for an std.parallelism module to be included in Phobos. We now begin the formal review process. The code repository and documentation can be found here: https://github.com/dsimcha/std.parallelism/wiki http://cis.jhu.edu/~dsimcha/d/phobos/std_parallelism.html I would like to remind everyone that there is now only one week left of the std.parallelism review period. If you have any comments, please speak now, so that David has time to make the changes. I realise that the module has been through several review cycles already, and that it is already in active use (by me, among others), so there probably won't be any big issues. However, if it gets voted into Phobos, that's it -- it will be an official part of the D standard library. So start nitpicking, folks! The voting will start next Friday, 25 March, and last for a week, until 1 April. -Lars I can't say that I've read the code thoroughly but maybe someone can tell me if it supports work stealing? /Jonas
Re: std.parallelism: Final review
== Quote from Jonas Drewsen (jdrew...@nospam.com)'s article On 18/03/11 10.40, Lars T. Kyllingstad wrote: On Fri, 04 Mar 2011 21:05:39 +, Lars T. Kyllingstad wrote: David Simcha has made a proposal for an std.parallelism module to be included in Phobos. We now begin the formal review process. The code repository and documentation can be found here: https://github.com/dsimcha/std.parallelism/wiki http://cis.jhu.edu/~dsimcha/d/phobos/std_parallelism.html I would like to remind everyone that there is now only one week left of the std.parallelism review period. If you have any comments, please speak now, so that David has time to make the changes. I realise that the module has been through several review cycles already, and that it is already in active use (by me, among others), so there probably won't be any big issues. However, if it gets voted into Phobos, that's it -- it will be an official part of the D standard library. So start nitpicking, folks! The voting will start next Friday, 25 March, and last for a week, until 1 April. -Lars I can't say that I've read the code thoroughly but maybe someone can tell me if it supports work stealing? /Jonas Not in Cilk style. Everything just goes to a shared queue. In theory this could be a bottleneck in the micro parallelism case. However, some experimentation I did early in the design convinced me that in practice there's so much other overhead involved in moving work from one processor to another (cache misses, needing to wake up a thread, etc.) that, in cases where a shared queue might be a bottleneck, the parallelism is probably too fine-grained anyhow. std.parallelism does, however, support semantics somewhat similar to work stealing in that, when a thread needs the results of a job that has not yet been started, said job will be pulled out of the middle of the queue and executed immediately in the thread that needs the result. Using a shared queue simplifies the design massively and arguably makes more sense in that tasks are guaranteed to be started in the order received, except in the case described above.
Argh!! Cyclic dependencies!!!
These module constructor Cyclic dependencies errors are really starting to piss me off. I feel like I'm back in the days when you'd sneeze and DMD would vomit out 100 forward reference errors just because you didn't write your whole damn app in one giant ultra-module. (/me takes a breather to chill out...Ok...) I don't suppose there's any chance we could get a quick little: import foo; pragma(staticCtorsAvoid, foo); // Or pragma(staticCtorsRunBefore, foo); // Or pragma(staticCtorsRunAfter, foo); static this() { // do trivial shit that doesn't touch foo } Could we? I don't care which it is. I don't care if it doesn't enforce any safety at all. I don't care if it gets depricated in favor of an alternate solution in a later version. I just need a way to say this'll work, dmd, just do it and quit yer damn whinin'!! Doesn't need to be perfect, just needs to work. At the very least, if I manage to be able to hack something like that it in, would there be any chance of it getting accepted?
Re: Has the ban on returning function nested structs been lifted?
On Fri, 18 Mar 2011 22:25:49 +0200, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: Can auto functions with local types work if you're distributing your library in binary form (.lib) and only .di interface files? As much as i love to have it (IMO a big issue for library design in general) i am afraid it is not possible because of dynamic libraries. If only we could expose only the parts we want, with zero overhead (I don't know, maybe it is already possible somehow). There is not a single elegant solution in the languages i know. --- di file struct A { // imposter A { method1 method2 } --- d file struct A { method1 method2 method3 ... // data int a, b, c; }
Re: Has the ban on returning function nested structs been lifted?
Andrei Alexandrescu napisał: Auto returns + local types = just awesome. Why is it awesome? -- Tomek
Re: Against enforce()
On Fri, 18 Mar 2011 11:02:13 +0100, Kagamin s...@here.lot wrote: Don Wrote: Pure functions calling weakly pure functions are also weakly pure and so on. This effectively leaves you without purity. I presume you mean Pure functions calling weakly pure functions *would also be* weakly pure and so on. ? What's the difference? Your original statement seems to indicate that strongly pure functions would be reduced to weakly pure if they call weakly pure functions. -- Simen
Re: a cabal for D ?
On 18/03/11 09.52, Russel Winder wrote: On Thu, 2011-03-17 at 20:44 +, Jason E. Aten wrote: Please correct me if I'm wrong, but I observe that there doesn't appear to be a package management system / standard repository for D libraries. Or is there? I'm talking about something as easy to use as R's CRAN, install.packages(rforest) or cpan for perl, ctan for latex, dpgk/apt for debian, cabal for Haskell/ Hackage, etc. Note that every language-specific package manager conflicts directly with every operating system package manager. Thus RubyGems, CPAN, Cabal, Maven, Go, etc. conflicts with the package management of Debian, Fedora, SUSE, FreeBSD, MacPorts, etc. leading to pain. Pain leads to anger. Anger leads to hate. Hate leads to suffering. If there's not a commonly utilized one currently, perhaps we could borrow cabal, with a trivial port. cabal is Haskell's package manager. Not only does having a standard package install system facilitate adoption, it greatly facilitates code sharing and library maturation. At the expense of easy system administration. I guess the only up side of language specific package management is that it enables people whose operating systems are not package structured to do things sensibly. Alternatively Windows users could switch to a sensible operating system ;-) The worst thing is that dependency tracking is lost when the sysadm uses another package system e.g CPAN. If the dependency problem could be solved in an elegant way I think a sysadm would be ok with it. Given that D has chosen to switch to Git for version control, doesn't this imply that package management transported over DVCS is the way forward. Go has certainly taken this route. It prioritizes Mercurial but supports Bazaar and Git as well. I like how Go uses git but there is room for improvements. No reason the limit the protocols as long a it can be resonable supported. It is just a place to download from. Put http, ftp, samba, torrent, dropbox, facebook... in there as well :) DSSS was actually a nice solution. Maybe it could be brought up to date and improved to fit the needs? /Jonas
Re: Has the ban on returning function nested structs been lifted?
On Sat, 19 Mar 2011 00:07:40 +0200, Tomek Sowiński j...@ask.me wrote: Andrei Alexandrescu napisał: Auto returns + local types = just awesome. Why is it awesome? Clean namespace and clean implementation are the first two i can think of.
Re: [TDPL] Russian translation of the book
On Fri, 18 Mar 2011 18:02:03 +0100, Vladimir Panteleev vladi...@thecybershadow.net wrote: On Fri, 18 Mar 2011 13:08:24 +0200, Alexander Malakhov a...@programmer.net wrote: Vladimir Panteleev vladi...@thecybershadow.net писал(а) в своём письме Wed, 16 Mar 2011 23:54:14 +0600: On Wed, 16 Mar 2011 19:10:29 +0200, Alexander Malakhov a...@programmer.net wrote: Russian publisher Символ-Плюс (Symobl-Plus) now is translating TDPL and they are asking for volunteers to * help translating guy with technical details * read final version If you wish to help, add your contacts on forum: http://www.symbol.ru/forum/viewtopic.php?f=4t=363 Note that the last message in that thread is from the last year. Actually it's from 2011.01.20. Go to the 2nd page :) Who puts paging controls at the top of threads? :s In soviet russia...? -- Simen
Re: Has the ban on returning function nested structs been lifted?
Jonathan M Davis: Actually, the coolest part about it IMHO is that it highlights the fact that you should be using auto with std.algorithm and _not_ care about the exact types of the return types. Knowing the exact return type for those functions is generally unnecessary and is often scary anyway (especially with the functions which return lazy ranges like map and until). Making the functions return auto and completely hiding the return type pretty much forces the issue. There's still likely to be some confusion for those new to D, but it makes the proper way to use std.algorithm more obvious. I'd hate to deal with any code which used std.algorithm without auto. That would get ugly _fast_. auto variable inference is indeed almost necessary if you want to use lazy functions as the ones in Phobos. But I have to say that those types are scary because of the current design of those Phobos higher order functions. In Haskell if you have an iterable and you perform a map on it using a function that returns an int, you produce something like a [Int], that's a lazy list of machine integers. This is a very simple type. If you perform another map on that list, and the mapping function returns an int again, the type of the whole result is [Int] still. The type you work with doesn't grow more and more as with Phobos functions. Designers of C# LINQ have found a more complex solution, they build a tree of lazy delegates... Bye, bearophile
Re: Argh!! Cyclic dependencies!!!
Nick Sabalausky Wrote: These module constructor Cyclic dependencies errors are really starting to piss me off. I feel like I'm back in the days when you'd sneeze and DMD would vomit out 100 forward reference errors just because you didn't write your whole damn app in one giant ultra-module. (/me takes a breather to chill out...Ok...) I don't suppose there's any chance we could get a quick little: import foo; pragma(staticCtorsAvoid, foo); // Or pragma(staticCtorsRunBefore, foo); // Or pragma(staticCtorsRunAfter, foo); static this() { // do trivial shit that doesn't touch foo } Could module-level globals be treated like local variables to the static constructor for the purpose of checking purity? AKA static this() pure { // trivial stuff // calls weakly pure functions // writes module-level globals // reads module-level globals // etc... } That's compiler enforceable and effectively means that stati constructor does not count as part of a cyclic dependency...
Re: std.parallelism: Final review
On 18/03/11 22.43, dsimcha wrote: == Quote from Jonas Drewsen (jdrew...@nospam.com)'s article On 18/03/11 10.40, Lars T. Kyllingstad wrote: On Fri, 04 Mar 2011 21:05:39 +, Lars T. Kyllingstad wrote: David Simcha has made a proposal for an std.parallelism module to be included in Phobos. We now begin the formal review process. The code repository and documentation can be found here: https://github.com/dsimcha/std.parallelism/wiki http://cis.jhu.edu/~dsimcha/d/phobos/std_parallelism.html I would like to remind everyone that there is now only one week left of the std.parallelism review period. If you have any comments, please speak now, so that David has time to make the changes. I realise that the module has been through several review cycles already, and that it is already in active use (by me, among others), so there probably won't be any big issues. However, if it gets voted into Phobos, that's it -- it will be an official part of the D standard library. So start nitpicking, folks! The voting will start next Friday, 25 March, and last for a week, until 1 April. -Lars I can't say that I've read the code thoroughly but maybe someone can tell me if it supports work stealing? /Jonas Not in Cilk style. Everything just goes to a shared queue. In theory this could be a bottleneck in the micro parallelism case. However, some experimentation I did early in the design convinced me that in practice there's so much other overhead involved in moving work from one processor to another (cache misses, needing to wake up a thread, etc.) that, in cases where a shared queue might be a bottleneck, the parallelism is probably too fine-grained anyhow. I guess that work stealing could be implemented without changing the current interface if evidence shows up that would favor work stealing? Maybe later an extension to the task scheduler for task cpu affinity would be nice in order to lower cache misses for certain kinds of tasks. std.parallelism does, however, support semantics somewhat similar to work stealing in that, when a thread needs the results of a job that has not yet been started, said job will be pulled out of the middle of the queue and executed immediately in the thread that needs the result. This is indeed a nice feature. Using a shared queue simplifies the design massively and arguably makes more sense in that tasks are guaranteed to be started in the order received, except in the case described above. Yes it works very well in general I believe. Nice work! /Jonas
Re: Argh!! Cyclic dependencies!!!
On 2011-03-18 19:24:41 -0400, Jason House jason.james.ho...@gmail.com said: Nick Sabalausky Wrote: These module constructor Cyclic dependencies errors are really starting to piss me off. I feel like I'm back in the days when you'd sneeze and DMD would vomit out 100 forward reference errors just because you didn't write your whole damn app in one giant ultra-module. (/me takes a breather to chill out...Ok...) I don't suppose there's any chance we could get a quick little: import foo; pragma(staticCtorsAvoid, foo); // Or pragma(staticCtorsRunBefore, foo); // Or pragma(staticCtorsRunAfter, foo); static this() { // do trivial shit that doesn't touch foo } Could module-level globals be treated like local variables to the static constructor for the purpose of checking purity? AKA static this() pure { // trivial stuff // calls weakly pure functions // writes module-level globals // reads module-level globals // etc... } That's compiler enforceable and effectively means that stati constructor does not count as part of a cyclic dependency... That would work nicely, except for one thing: static constructors can be used to build immutable global variables. And pure functions have access to immutable global variables. This means two things: 1. purity isn't really guarantied for pure functions inside a module constructor 2. pure functions could access immutable global variables of other modules before their initialization I think the pragma is a more viable solution, athough not very elegant. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: SpanMode.breadth -- misnomer?
On 12/03/2011 09:31, spir wrote: snip You are right about depth / breadth. (But I also have always found preorder/postorder misleading, or rather inversed. For me, the second one should be called postorder, since it postpones app on A after app on A's subnodes. I agree. Basically: - Preorder means the processing of each node on entry to its subtree (before visiting the children) - Postorder means the processing of each node on exit from its subtree (after visiting the children) A better, non-misleading, naming may be branch-first (case 1 above) vs children-first (case 2).) Branch-first to me is equally misleading. How about trunk-first and leaves-first? Stewart.
Re: Against enforce()
Steven Schveighoffer wrote: On Fri, 18 Mar 2011 14:35:27 -0400, Don nos...@nospam.com wrote: Steven Schveighoffer wrote: On Fri, 18 Mar 2011 04:34:54 -0400, Don nos...@nospam.com wrote: Steven Schveighoffer Wrote: As long as the delegate does not access shared/global data, it should be able to be pure. Even delegates which modify TLS data should be able to be pure (weak-pure, but still pure). TLS variables are global and must not be accessed from any function marked as pure. With regard to purity, there isn't any difference between shared and TLS variables. However, it's still not shared. This, for example, is a weak pure function: void foo(int *n) pure { *n = 5;} Because TLS variables are not shared, you should be able to do this: int x; void bar() { foo(x); } Yes, that compiles fine. But bar() is not pure. But you are right, there is a huge difference between a local reference to TLS data and directly accessing TLS data -- the latter can be obscured from the compiler, resulting in the compiler thinking the function can be strong pure. So I don't know exactly how to mitigate this, but in my mind, it feels like this should work: int foo(bool cond, lazy int n) pure { if(cond) return n; return 0;} int x; void bar() { foo(x == 4, x = 5); } It seems not too different from the above example where you pass the address of x. But obviously the x = 5 delegate cannot be pure (it modifies TLS data). We may have no recourse to get this to work. It may be a lost cause, and you just can't have lazy variables for pure functions. It's not a lost cause, it's a two-liner! mtype.c line 5045: if (fparam-storageClass STClazy) { -error(0, cannot have lazy parameters to a pure function); +tf-purity = PUREweak; +break; } This is a bit conservative: it would be possible to allow lazy parameters to be marked as pure, which would allow them to be strongly pure. But that would probably not be worth the extra complexity. I'm not sure this works. Aren't you allowed to pass in a delegate to a lazy parameter? Yes. For example: shared int x; int foo() { return x; } int bar(lazy int n) pure { return n; } void baz() { bar(foo); } or alternatively: void baz() { bar(x); } This compiles just fine. (Well, you need to use bar(foo) not bar(foo)). But if you try to mark baz() as pure, here's what you get: test0.d(135): Error: pure function 'baz' cannot call impure function 'foo' or for the second case: test0.d(136): Error: pure function 'baz' cannot access mutable static data 'x' bar is just weakly pure. The no-shared-data rule prevents you from passing in a shared int reference to a pure function, but how do you stop a delegate from accessing shared data? Delegates are either marked as pure, or not. In the case above, foo() is not pure.
Re: Pull requests for multiple issues?
Jonathan M Davis wrote: On Friday, March 18, 2011 07:26:38 Jesse Phillips wrote: Jonathan M Davis Wrote: I would say that, generally speaking, unrelated changes should be separate pull requests, whereas related changes should be grouped together into a single pull request. Remember that it's all or nothing, so they're going to merge in all of your changes or none of them. So, if it makes sense for them to all go together, then put them together, but if they don't necessarily make sense to go together and it _would_ make sense to accept some of them but not all of them, then separate them. I thought when you were doing a pull request you could do whatever you wanted to bring in the changes you wanted, such as cherry-picking. But I agree it makes review and acceptance easier. The reviewer should be able/expected to accept all/nothing. You have all of git's capabilities when you do a pull request. You could do the pull request into your own branch and then cherry pick just the ones that you want, certainly. However, the pull request itself is for the full branch. It's not done by commits but by branch. And I would generally expect that a pull request would contain a related set of changes such that cherry picking them likely wouldn't make sense. However, as Don points out, if you have a lot of unrelated changes which are small, then it could be desirable to have a single pull request for all of them. Still, I wouldn't expect someone merging them in to normally cherry pick the parts of a pull request that they thought were good. That would create extra work too. So, on the whole, I would expect pull requests to contain related changes which should either be merged in as a whole on not merged in at all. Any further commits to the branch before it's pulled in will be added to the pull request, so reviewers can request that the person doing the pull request make any necessary changes be made before it's pulled in, which should generally avoid any need to cherry pick anything, even in cases where several smaller changes were grouped together. - Jonathan M Davis There's a bit of a confidence thing: if you're confident that ALL of the patches are good, they're OK in one branch. But anything which you're less certain about should go in its own branch. (You'll get the most straightforward ones assessed and integrated more quickly that way).
Re: std.parallelism: Final review
On 3/18/2011 7:33 PM, Jonas Drewsen wrote: Not in Cilk style. Everything just goes to a shared queue. In theory this could be a bottleneck in the micro parallelism case. However, some experimentation I did early in the design convinced me that in practice there's so much other overhead involved in moving work from one processor to another (cache misses, needing to wake up a thread, etc.) that, in cases where a shared queue might be a bottleneck, the parallelism is probably too fine-grained anyhow. I guess that work stealing could be implemented without changing the current interface if evidence shows up that would favor work stealing? Yes, this would be possible. However, in my experience super fine-grained parallelism is almost never needed to take full advantage of whatever hardware you're running on. Therefore, I'm hesitant to add complexity to std.parallelism to support super fine-grained parallelism, at least without strong justification in terms of real-world use cases. The one thing work stealing (and improvements to the queue in general) has going for it is that it would only make the implementation more complex, not the interface.
Re: Has the ban on returning function nested structs been lifted?
On Friday, March 18, 2011 15:48:53 bearophile wrote: Jonathan M Davis: Actually, the coolest part about it IMHO is that it highlights the fact that you should be using auto with std.algorithm and _not_ care about the exact types of the return types. Knowing the exact return type for those functions is generally unnecessary and is often scary anyway (especially with the functions which return lazy ranges like map and until). Making the functions return auto and completely hiding the return type pretty much forces the issue. There's still likely to be some confusion for those new to D, but it makes the proper way to use std.algorithm more obvious. I'd hate to deal with any code which used std.algorithm without auto. That would get ugly _fast_. auto variable inference is indeed almost necessary if you want to use lazy functions as the ones in Phobos. But I have to say that those types are scary because of the current design of those Phobos higher order functions. In Haskell if you have an iterable and you perform a map on it using a function that returns an int, you produce something like a [Int], that's a lazy list of machine integers. This is a very simple type. If you perform another map on that list, and the mapping function returns an int again, the type of the whole result is [Int] still. The type you work with doesn't grow more and more as with Phobos functions. Designers of C# LINQ have found a more complex solution, they build a tree of lazy delegates... You get the simple types in Haskell, because _everything_ in Haskell is lazy. _Nothing_ is actually computed until it has to be. So, the fact that a list is lazily executed doesn't really affect the type system. Not everything is lazy in D, so that doesn't work. And honestly, while the return type of functions like map and until may look fairly ugly, auto makes their ugliness pretty much irrelevant. I think that D has a solid solution. Haskell looks cleaner only because it forces laziness on everything. - Jonathan M Davis
Re: std.parallelism: Final review
On 2011-03-18 17:12:07 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org said: On 3/18/11 3:55 PM, dsimcha wrote: It's kinda interesting--I don't know at all where this lib stands. The deafening silence for the past week makes me think one of two things is true: 1. std.parallelism solves a problem that's too niche for 90% of D users, or 2. It's already been through so many rounds of discussion in various places (informally with friends, then on the Phobos list, then on this NG) that there really is nothing left to nitpick. I have no idea which of these is true. Probably a weighted average of the two. If I were to venture a guess I'd ascribe more weight to 1. This is partly because I'm also receiving relatively little feedback on the concurrency chapter in TDPL. Also the general pattern on many such discussion groups is that the amount of traffic on a given topic is inversely correlated with its complexity. One reason might also be that not many people are invested in D for such things right now. It's hard to review such code and make useful comments without actually testing it on a problem that would benefit from its use. If I was writing in D the application I am currently writing, I'd certainly give it a try. But the thing I have that would benefit from something like this is in Objective-C (it's a Cocoa program I'm writing). I'll eventually get D to interact well with Apple's Objective-C APIs, but in the meantime all I'm writing in D is some simple web stuff which doesn't require multithreading at all. In my application, what I'm doing is starting hundreds of tasks from the main thread, and once those tasks are done they generally send back a message to the main thread through Cocoa's event dispatching mechanism. From a quick glance at the documentation, std.parallelism offers what I'd need if I were to implement a similar application in D. The only thing I don't see is a way to priorize tasks: some of my tasks need a more immediate execution than others in order to keep the application responsive. One interesting bit: what I'm doing in those tasks is mostly I/O on the hard drive combined with some parsing. I find a task queue is useful to manage all the work, in my case it's not really about maximizing the utilization of a multicore processor but more about keeping it out of the main thread so the application is still responsive. Maximizing speed is still a secondary objective, but given most of the work is I/O-bound, having multiple cores available doesn't help much. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: std.parallelism: Final review
I think your use case is both beyond the scope of std.parallelism and better handled by std.concurrency. std.parallelism is mostly meant to handle the pure multicore parallelism use case. It's not that it **can't** handle other use cases, but that's not what it's tuned for. As far as prioritization, it wouldn't be hard to implement prioritization of when a task starts (i.e. have a high- and low-priority queue). However, the whole point of TaskPool is to avoid starting a new thread for each task. Threads are recycled for efficiency. This prevents changing the priority of things in the OS scheduler. I also don't see how to generalize prioritization to map, reduce, parallel foreach, etc. w/o making the API much more complex. In addition, std.parallelism guarantees that tasks will be started in the order that they're submitted, except that if the results are needed immediately and the task hasn't been started yet, it will be pulled out of the middle of the queue and executed immediately. One way to get the prioritization you need is to just submit the tasks in order of priority, assuming you're submitting them all from the same place. One last thing: As far as I/O goes, AsyncBuf may be useful. This allows you to pipeline reading of a file and higher level processing. Example: // Read the lines of a file into memory in parallel with processing // them. import std.stdio, std.parallelism, std.algorithm; void main() { auto lines = map!a.idup(File(foo.txt).byLine()); auto pipelined = taskPool.asyncBuf(lines); foreach(line; pipelined) { auto ls = line.split(\t); auto nums = to!(double[])(ls); } } On 3/18/2011 9:27 PM, Michel Fortin wrote: On 2011-03-18 17:12:07 -0400, Andrei Alexandrescu seewebsiteforem...@erdani.org said: On 3/18/11 3:55 PM, dsimcha wrote: It's kinda interesting--I don't know at all where this lib stands. The deafening silence for the past week makes me think one of two things is true: 1. std.parallelism solves a problem that's too niche for 90% of D users, or 2. It's already been through so many rounds of discussion in various places (informally with friends, then on the Phobos list, then on this NG) that there really is nothing left to nitpick. I have no idea which of these is true. Probably a weighted average of the two. If I were to venture a guess I'd ascribe more weight to 1. This is partly because I'm also receiving relatively little feedback on the concurrency chapter in TDPL. Also the general pattern on many such discussion groups is that the amount of traffic on a given topic is inversely correlated with its complexity. One reason might also be that not many people are invested in D for such things right now. It's hard to review such code and make useful comments without actually testing it on a problem that would benefit from its use. If I was writing in D the application I am currently writing, I'd certainly give it a try. But the thing I have that would benefit from something like this is in Objective-C (it's a Cocoa program I'm writing). I'll eventually get D to interact well with Apple's Objective-C APIs, but in the meantime all I'm writing in D is some simple web stuff which doesn't require multithreading at all. In my application, what I'm doing is starting hundreds of tasks from the main thread, and once those tasks are done they generally send back a message to the main thread through Cocoa's event dispatching mechanism. From a quick glance at the documentation, std.parallelism offers what I'd need if I were to implement a similar application in D. The only thing I don't see is a way to priorize tasks: some of my tasks need a more immediate execution than others in order to keep the application responsive. One interesting bit: what I'm doing in those tasks is mostly I/O on the hard drive combined with some parsing. I find a task queue is useful to manage all the work, in my case it's not really about maximizing the utilization of a multicore processor but more about keeping it out of the main thread so the application is still responsive. Maximizing speed is still a secondary objective, but given most of the work is I/O-bound, having multiple cores available doesn't help much.
review of std.parallelism
0. Overview and vote I think the library delivers the high-level goods (parallel foreach, map, reduce) but is a bit fuzzy in the lower level details. Documentation hurts understanding of the capabilities of the library and essentially is of inadequate quality. Entity documentation and examples do little more than give the impression of dispensing with an unpleasant chore. My vote in favor of acceptance is contingent upon a radical improvement in the quality of documentation and examples. Most if not all artifacts should be motivated by simple, compelling examples. The introductory section must contain a brief and attractive synopsis of the flagship capabilities. All terms must be defined before being used and introduced in a carefully-chosen order. The relationship between various entities should be clarified. I've seen the argument that simple and strong examples are difficult to find. Though I agree such examples are not easy to come up with, I also believe the author of library is in the best position to produce them. 1. Library proper: * In the case of non-random access ranges, parallel foreach is still usable but buffers lazily to an array... Wouldn't strided processing help? If e.g. 4 threads the first works on 0, 4, 8, ... second works on 1, 5, 9, ... and so on. * Example with squares would be better if double replaced uint, and if a more complicated operation (sqrt, log...) were involved. * I'm unclear on the tactics used by lazyMap. I'm thinking the obvious method should be better: just use one circular buffer. The presence of two dependent parameters makes this abstraction difficult to operate with. * Same question about asyncBuf. What is wrong with a circular buffer filled on one side by threads and on the consumed from the other by the client? I can think of a couple of answers but it would be great if they were part of the documentation. * Why not make workerIndex a ulong and be done with it? * Is stop() really trusted or just unsafe? If it's forcibly killing threads then its unsafe. * uint size() should be size_t for conformity. * defaultPoolThreads - should it be a @property? * I don't understand what Task is supposed to do. It is circularly defined: A struct that encapsulates the information about a task, including its current status, what pool it was submitted to, and its arguments. OK, but what's a task? Could a task be used outside a task pool, and if so to what effect(s)? * If LazyMap is only necessary as the result of lazyMap, could that become a local type inside lazyMap? 2. Documentation: * Documentation unacceptable. It lacks precision and uses terms before defining them. For example: This class encapsulates a task queue and a set of worker threads comes before the notions of task queue and worker thread are defined. Clearly there is an intuition of what those are supposed to mean, but in practice each library lays down some fairly detailed definition of such. * Note: Initializing a pool with zero threads (as would happen in the case of a single-core CPU) is well-tested and does work. The absence of a bug should not be advertised in so many words. Simpler: Note: Single-CPU machines will operate transparently with zero-sized pools. * Allows for custom pool size. I have no idea what pool size means. * // Do something interesting. Worst example ever. You are the creator of the library. If _you_ can't find a brief compelling example, who could? * Immediately after the range argument, an optional block size argument may be provided. If none is provided, the default block size is used. An optional buffer for returining the results may be provided as the last argument. If one is not provided, one will be automatically allocated. If one is provided, it must be the same length as the range. An example should be inserted after each of these sentences. * // Do something expensive with line. Better you do something expensive with line. * This is not the same thing as commutativity. I think this is obvious enough to be left out. The example of matrices (associative but not commutative) is nice though. * immutable n = 10; - use underscores * Would be great if the documentation examples included some rough experimental results, e.g. 3.8 times faster on a 4-core machine than the equivalent serial loop. * No example for workerIndex and why it's useful. * Is LocalWorker better than WorkerLocal? No, because it's not the worker that's local, it's the storage - which is missing from the name! WorkerLocalStorage? Also replace create with make or drop it entirely. The example doesn't tell me how I can use bufs. I suspect workerIndex has something to do with it but the example fails to divulge that relationship. * No example for join(), which is quite a central primitive. * No example for put(), which would be interesting to see. * No example for task(). * No example for run().
Re: [TDPL] Russian translation of the book
2011/3/16 Alexander Malakhov a...@programmer.net Russian publisher Символ-Плюс (Symobl-Plus) now is translating TDPL and they are asking for volunteers to * help translating guy with technical details * read final version If you wish to help, add your contacts on forum: http://www.symbol.ru/forum/viewtopic.php?f=4t=363 -- Alexander I always thought Andrei was Russian, but someone told me he's Romanian. He sure does sound Russian, though. Great to see TDPL and D become more widespread.
Re: Library Development: What to finish/flesh out?
On Fri, Mar 18, 2011 at 2:19 PM, filgood filg...@somewhere.net wrote: Hi Lars, I agree on your orderbut would like to see Matrix ops in Phobos over time (my understanding was that it can work without BLAS (just slower), people can always in BLAS when they need to extra performance, no?). David, thanks a lot for your hard work... How about Eigen? http://eigen.tuxfamily.org/index.php?title=Benchmark Those benchmarks are old, but still. Eigen v3 performs even better and they've added multi-threading and tons of other features and enhancements.