Re: Goto into catch blocks
== Quote from dsimcha (dsim...@yahoo.com)'s article > == Quote from Iain Buclaw (ibuc...@ubuntu.com)'s article > > I have been merging Phobos that got released with the latest DMD release > > into > > GDC. > Great. I was wondering what happened here since you usually merge Phobos and > DMD > at the same time, and I'm very excited that the last few showstopper bugs got > fixed and GDC may actually be usable now. A very particular change to arraytypes in the frontend was the reason for that. :o) > > And I have raised a pull request (though I seem to recall I had commit > > access > > granted a while back - though this was before the move to github): > > https://github.com/D-Programming-Language/phobos/pull/253 > Generally you should use pull requests even if you have commit access, so > that the > code gets reviewed by at least one other person. This has led to major > improvements in the code quality in Phobos. The exception is for "trivial" > things. > There's a little disagreement about where the line should be drawn. I draw > it at > simple one- or a few-liner bug fixes in code I understand well, and reverting > recent changes that cause build problems. These and anything simpler, I push > directly. Anything more complicated, I think review is worthwhile. Others > seem > to think that basically any change to actual code is non-trivial, though I > think > this is excessively bureaucratic and would only follow it if there was a very > strong consensus and a written rule in our dev guidelines. OK, thanks.
Re: Line lengths discussed in eclipse forum and on reddit
"Andrei Alexandrescu" wrote: Anyhow, let's move on to date formats. I'm archiving some receipt right now, and I find the mm/dd/yy notation notation quite unpleasant... Touché! :-) -- Jouko
Re: Line lengths discussed in eclipse forum and on reddit
On 09/12/2011 08:29 PM, Adam Ruppe wrote: Andrei Alexandrescu wrote: Well I agree to that, but allow me to note that it's only one post away you mentioned "0" as a memorable number. I might have been unclear - it's not so much that it's memorable, but it has a different gut reaction. "Below zero" in my gut is akin to saying "it's off the scale"; it implies a big extreme in subjective perception rather than a specific physical quantity. If you say "it's below zero" on the Celsius scale, it's literally freezing cold, but it's not an uncommon or exceptional thing. It is in the spring, and it means that year's crop is in danger. That _is_ something one would note, and quite literally at the gut level :o). Anyhow, let's move on to date formats. I'm archiving some receipt right now, and I find the mm/dd/yy notation notation quite unpleasant... Andrei
Re: Line lengths discussed in eclipse forum and on reddit
Andrei Alexandrescu wrote: > Well I agree to that, but allow me to note that it's only one post > away you mentioned "0" as a memorable number. I might have been unclear - it's not so much that it's memorable, but it has a different gut reaction. "Below zero" in my gut is akin to saying "it's off the scale"; it implies a big extreme in subjective perception rather than a specific physical quantity. If you say "it's below zero" on the Celsius scale, it's literally freezing cold, but it's not an uncommon or exceptional thing. It's below zero through almost the entire winter (and half the spring and fall, at least up here). But, if you say the same thing with the Fahrenheit scale, that is actually fairly special, even in winter - below zero Fahrenheit is pretty cold.
Re: cleaning up dsource
On 09/13/2011 03:18 AM, Marco Leise wrote: Am 12.09.2011, 21:17 Uhr, schrieb Nick Sabalausky : I agree. Unfortunately, the site's maintainer, Brad Anderson, doesn't appear to be active with D anymore :( "There are lot's of discontinued projects listed on that site. Something must be done!" - "Sure, but the web site is discontinued." No offense, it is satire. :) =D
Re: cleaning up dsource
Am 12.09.2011, 21:17 Uhr, schrieb Nick Sabalausky : I agree. Unfortunately, the site's maintainer, Brad Anderson, doesn't appear to be active with D anymore :( "There are lot's of discontinued projects listed on that site. Something must be done!" - "Sure, but the web site is discontinued." No offense, it is satire. :)
Re: Line lengths discussed in eclipse forum and on reddit
On 09/12/2011 07:52 PM, Adam Ruppe wrote: Andrei Alexandrescu wrote: Surely you're jesting. Partially. For the most part, the metric system is better for science, but for day to day stuff? Poo. Lots of silly things to remember and the numbers don't line up well to regular stuff. Could be due to the fact that I'm more used to it, but it's more likely that my preferences are objectively superior to anyone who disagrees :) I bow to that! Zero degrees Celsius is the water freezing temperature, which is a very practical influencer (snow vs. rain, plants, crops, etc). Zero degrees is just as arbitrary for that value as thirty-two degrees. Well I agree to that, but allow me to note that it's only one post away you mentioned "0" as a memorable number. I mean you can't make an argument to then refute it. It's not easier to remember, nor does it simplify calculations, especially since other constants are so random looking. (what's 1g for force of gravity? The specific heat of water? Standard temperature and pressure? All ugly numbers...) But hey, whatever levitates your nautical vessel. Pro-metric arguments just tend to annoy me because they like to focus on irrelevant trivia, but the truth is they are both arbitrary and ugly. My preference is just less ugly :-P No prob. I'm just pointing out when objective is not apart from the subjective. Andrei
Re: Clean-up of std.socket
On Tue, 13 Sep 2011 04:13:47 +0900, Sean Kelly wrote: Looks much nicer than the current std.socket. A few random comments from a quick scan of the code: [snip] As an aside… From your comments, I gather that you're not terribly happy with certain design requirements imposed by the existing std.socket. Why not create an entirely new API in std.socket2 and not worry about it? Would your design change enough to warrant doing this? I think we should create new Socket API(My old post at Phobos ML was the first step). I will restart more rewrite with new project. Of course, this patch is useful to improvement current std.socket.
Re: Line lengths discussed in eclipse forum and on reddit
Andrei Alexandrescu wrote: > Surely you're jesting. Partially. For the most part, the metric system is better for science, but for day to day stuff? Poo. Lots of silly things to remember and the numbers don't line up well to regular stuff. Could be due to the fact that I'm more used to it, but it's more likely that my preferences are objectively superior to anyone who disagrees :) > Zero degrees Celsius is the water freezing temperature, which is a > very practical influencer (snow vs. rain, plants, crops, etc). Zero degrees is just as arbitrary for that value as thirty-two degrees. It's not easier to remember, nor does it simplify calculations, especially since other constants are so random looking. (what's 1g for force of gravity? The specific heat of water? Standard temperature and pressure? All ugly numbers...) But hey, whatever levitates your nautical vessel. Pro-metric arguments just tend to annoy me because they like to focus on irrelevant trivia, but the truth is they are both arbitrary and ugly. My preference is just less ugly :-P
Re: Goto into catch blocks
On 09/13/2011 12:27 AM, Iain Buclaw wrote: I have been merging Phobos that got released with the latest DMD release into GDC. And couldn't help but notice this nostalgic error I implemented a while back: std/format.d:1520: Error: cannot goto into catch block Line of concern in phobos: https://github.com/D-Programming-Language/phobos/blob/master/std/format.d#L1539 Part of spec which error implements: http://www.digitalmars.com/d/2.0/statement.html#GotoStatement Where does it say that a goto into a catch block is categorically banned? It only says that a goto cannot skip a variable initialization. catch(Type){} and catch{} are valid forms too. Neither one contains a declaration. Sure, usually a goto into a catch block means that someone is abusing exceptions for regular control flow, but if you just want a quick and dirty hack, or if a third-party API forces you to, I don't think the language should stand in your way.
Re: D in the TIOBE top
On 09/12/2011 07:11 PM, Jeff Nowakowski wrote: On 09/12/2011 07:06 PM, Andrei Alexandrescu wrote: If you were in my position, wouldn't you have posted that article? I hope I wouldn't have published it, since I don't like misleading marketing. BTW, apparently others comment on the news, too. http://www.infoworld.com/d/application-development/objective-c-c-d-language-winners-in-programming-popularity-172587. Then he doesn't know better about the problems with Tiobe. You do, or at least you should. D originally fell out of the top 20 because it plummeted after Tiobe actually started applying a tiny bit of care to their stats. You also acknowledged in the reddit thread that you thought Tiobe was meaningless -- that is, until D hit the front page. Smiley or not, I'll take that at face value given the context. Too bad, you missed out on a good joke. Feigning lack of a sense of humor for the sake of appearing self-righteous is a losing gambit as a sense of humor indicates intelligence. Andrei
Re: D in the TIOBE top
On 09/12/2011 07:06 PM, Andrei Alexandrescu wrote: If you were in my position, wouldn't you have posted that article? I hope I wouldn't have published it, since I don't like misleading marketing. BTW, apparently others comment on the news, too. http://www.infoworld.com/d/application-development/objective-c-c-d-language-winners-in-programming-popularity-172587. Then he doesn't know better about the problems with Tiobe. You do, or at least you should. D originally fell out of the top 20 because it plummeted after Tiobe actually started applying a tiny bit of care to their stats. You also acknowledged in the reddit thread that you thought Tiobe was meaningless -- that is, until D hit the front page. Smiley or not, I'll take that at face value given the context. I find it odd that you hang out on this newsgroup although every indication of D's success infuriates you. Wrong. I follow D because I find it an interesting language. Rather than being upset at a successful D, I've been hoping it would turn out great after all these years. Why else would I make a comment supporting bearophile about error-prone behavior like array initialization? I criticize when I find things to critique, usually when they hit my pet peeve issues. Bullshit marketing happens to be one of them, and Tiobe is right up there.
Re: Support for feeding data to engine threads?
== Quote from Jerry Quinn (jlqu...@optonline.net)'s article > > Hmm, currently there isn't an easy/obvious way, though I'm thinking maybe > > one > > should be added. I've kind of needed it, too, and I don't anticipate it > > being > > very hard to implement. If you can suggest a good API for this, I'll work > > on it > > for next release. > I'd probably naturally want to do something like: > auto engines = taskPool.init(new Engine(params)); > auto lines = File("foo.txt").byLine(); > auto results = taskPool.map!(engines.process)(lines) > foreach (auto r; results) > writeln(r); > This would create a set of new Engine objects per object, but initialized > within each thread as thread-local data. Each Engine object has a process() call taking a line as input and returning a string in this case. Any free engine can process more work as long as there is still work available. > For the large-scale use case, it could take an extra argument and allow only N simultaneous init's under the covers. >From reading your later posts, it seems like what you really want is >worker-local storage that's initialized from the thread that owns it rather than the thread that workerLocalStorage() was called from. This may be do-able but I'll have to think about the consequences and the implementation. In the mean time, see my other posts for a workaround.
Re: D in the TIOBE top
On 09/12/2011 05:48 PM, Jeff Nowakowski wrote: On 09/12/2011 04:25 PM, Andrei Alexandrescu wrote: I have no connection with Tiobe and the name "D" wasn't chosen to manipulate its ranking method. Are you disagreeing with my posting of a piece of information on a community-voted forum? I wouldn't quite understand what the matter is here, if it weren't for your posting history. Nice strawman. I never said you chose the D name. I made it clear why I think using Tiobe to crow about D is just lame marketing. It's not all that clear to me. I see that post as an attempt at inflaming. What's silly is framing marketing as "posting of a piece of information on a community-voted forum". That's taking generics to a whole new level! That's pretty much what I did. It's very simple, really - the people who maintain the Tiobe index wrote a few good words about D in their monthly installment for September. I found fit to share that on reddit. I fail to see where I've done something lame or of questionable intent or whatnot. If you were in my position, wouldn't you have posted that article? I don't understand what you're trying to prove. BTW, apparently others comment on the news, too. http://www.infoworld.com/d/application-development/objective-c-c-d-language-winners-in-programming-popularity-172587. I find it odd that you hang out on this newsgroup although every indication of D's success infuriates you. Andrei
Re: Goto into catch blocks
On Monday, September 12, 2011 15:27 Iain Buclaw wrote: > I have been merging Phobos that got released with the latest DMD release > into GDC. And couldn't help but notice this nostalgic error I implemented > a while back: > > std/format.d:1520: Error: cannot goto into catch block > > > Line of concern in phobos: > https://github.com/D-Programming-Language/phobos/blob/master/std/format.d#L > 1539 > > Part of spec which error implements: > http://www.digitalmars.com/d/2.0/statement.html#GotoStatement > > I have discussed such code before and why it should be disallowed: > http://www.digitalmars.com/d/archives/digitalmars/D/Behaviour_of_goto_into_ > catch_blocks._116908.html > > > And I have raised a pull request (though I seem to recall I had commit > access granted a while back - though this was before the move to github): > https://github.com/D-Programming-Language/phobos/pull/253 Regardless of whether you have commit access, anything other than really trivial changes (such as updates to the changelog) should still go through pull requests. At this point having commit access is more about being able to merge in other people's pull requests that have been adequately reviewed than being able to commit your own changes. However, if you want commit access again, then ping Walter about it, and he should be able to give you commit access. - Jonathan M Davis
Re: Support for feeding data to engine threads?
dsimcha Wrote: > == Quote from Jerry Quinn (jlqu...@optonline.net)'s article > > dsimcha Wrote: > > > == Quote from Jerry Quinn (jlqu...@optonline.net)'s article > > > > I'm looking at porting an app that maintains a work queue to be > > > > processed by one > > > of N engines and written out in order. At first glance, std.parallelism > > > already > > > provides the queue, but the Task concept appears to assume that there's > > > no startup > > > cost per thread. > > > > Am I missing something or do I need to roll a shared queue object? > > > > > > Not sure if I'm misunderstanding what you're asking, but I'll answer the > > > question > > > I think you're asking. std.parallelism's Task can be executed in two > > > ways. > > > executeInNewThread() does start a new thread for every Task. However, > > > you can > > > also submit a Task to a TaskPool and have it executed by an existing > > > worker > > > thread. The whole point of using TaskPool to execute a Task is to avoid > > > paying > > > the thread start-up cost for every Task. > > The question I was asking was how to execute a huge amount of per-thread > initialization once per thread in the TaskPool framework. > > Hmm, currently there isn't an easy/obvious way, though I'm thinking maybe one > should be added. I've kind of needed it, too, and I don't anticipate it being > very hard to implement. If you can suggest a good API for this, I'll work on > it > for next release. I'd probably naturally want to do something like: auto engines = taskPool.init(new Engine(params)); auto lines = File("foo.txt").byLine(); auto results = taskPool.map!(engines.process)(lines) foreach (auto r; results) writeln(r); This would create a set of new Engine objects per object, but initialized within each thread as thread-local data. Each Engine object has a process() call taking a line as input and returning a string in this case. Any free engine can process more work as long as there is still work available. For the large-scale use case, it could take an extra argument and allow only N simultaneous init's under the covers.
Re: D in the TIOBE top
On 09/12/2011 04:25 PM, Andrei Alexandrescu wrote: I have no connection with Tiobe and the name "D" wasn't chosen to manipulate its ranking method. Are you disagreeing with my posting of a piece of information on a community-voted forum? I wouldn't quite understand what the matter is here, if it weren't for your posting history. Nice strawman. I never said you chose the D name. I made it clear why I think using Tiobe to crow about D is just lame marketing. What's silly is framing marketing as "posting of a piece of information on a community-voted forum". That's taking generics to a whole new level!
Re: Goto into catch blocks
== Quote from Iain Buclaw (ibuc...@ubuntu.com)'s article > I have been merging Phobos that got released with the latest DMD release into > GDC. Great. I was wondering what happened here since you usually merge Phobos and DMD at the same time, and I'm very excited that the last few showstopper bugs got fixed and GDC may actually be usable now. > And I have raised a pull request (though I seem to recall I had commit access > granted a while back - though this was before the move to github): > https://github.com/D-Programming-Language/phobos/pull/253 Generally you should use pull requests even if you have commit access, so that the code gets reviewed by at least one other person. This has led to major improvements in the code quality in Phobos. The exception is for "trivial" things. There's a little disagreement about where the line should be drawn. I draw it at simple one- or a few-liner bug fixes in code I understand well, and reverting recent changes that cause build problems. These and anything simpler, I push directly. Anything more complicated, I think review is worthwhile. Others seem to think that basically any change to actual code is non-trivial, though I think this is excessively bureaucratic and would only follow it if there was a very strong consensus and a written rule in our dev guidelines.
Re: Clean-up of std.socket
Adam Burton wrote: > Jonathan M Davis wrote: > >> On Monday, September 12, 2011 14:53 Adam Burton wrote: >>> Simen Kjaeraas wrote: >>> > On Mon, 12 Sep 2011 23:13:29 +0200, Adam Burton >>> > wrote: >>> >> I quite like the idea of >>> >> void[] representing a chunk of memory that could contain anything, >>> >> serialized data; an array of ubytes or strings, and allow ubyte[] to >>> >> just represent an array of ubytes (after all is serialized data an >>> >> array of bytes >>> >> or a block of data containing various data types cramed into it in >>> >> some organised manner?). In the end it is just a convention I like, >>> >> not attached >>> >> to it or anything, and D tends to discourage working based on >>> >> conventions anyway, I guess I am somewhat playing devil's advocate in >>> >> this paragraph >>> >> >>> >> :-). >>> > >>> > I believe the reasons for not using void[] is exactly that it could >>> > contain anything, including pointers, which likely would not be valid >>> > in the other end. >>> >>> How does a ubyte[] prevent that? If you've serialized an int (or even a >>> pointer) then ubyte[] is just as bad, ubyte[0] would seem to indicate a >>> meaningful unit of data itself when it's actually just the first byte of >>> an int (or pointer). void[] at least says "I don't know, I just know the >>> start and how long, you figure it out, I presume I have somewhere to go >>> to be given context". >> >> With void[], you can pass something like int*[] to it without having to >> worry about converting it, because the conversion is implicity. ubyte[], >> on the other hand, forces you to do the conversion explicitly. So yes, >> you could still make it so that the ubyte[] passed in contains pointers, >> but you have to do it explicitly, whereas with void[], it'll take any >> array without complaining. >> >> - Jonathan M Davis > Fair enough that's more clear, I hadn't actually thought of an array of > pointers as I was thinking of a pointer forced into ubyte[] with other > data types. I suppose that'll help remind people to double check what they > are sending but if you are going to send int*[] down a socket then you're > probably gonna put cast(ubyte[]) without looking anyway. Just a thought then, rather than using ubyte[] and casting to force someone to check (and possibly encourage a bad habit of automatically putting in a cast without checking, through fustration or over confidence) make send and receive templates methods that don't accept types we are unable to determine how to handle (like pointers and classes)? Maybe even give a static assert with an error message explaining pointers etc are not allowed?
Goto into catch blocks
I have been merging Phobos that got released with the latest DMD release into GDC. And couldn't help but notice this nostalgic error I implemented a while back: std/format.d:1520: Error: cannot goto into catch block Line of concern in phobos: https://github.com/D-Programming-Language/phobos/blob/master/std/format.d#L1539 Part of spec which error implements: http://www.digitalmars.com/d/2.0/statement.html#GotoStatement I have discussed such code before and why it should be disallowed: http://www.digitalmars.com/d/archives/digitalmars/D/Behaviour_of_goto_into_catch_blocks._116908.html And I have raised a pull request (though I seem to recall I had commit access granted a while back - though this was before the move to github): https://github.com/D-Programming-Language/phobos/pull/253 Regards Iain
Re: clear()
On 09/12/2011 04:36 PM, Michel Fortin wrote: On 2011-09-12 20:04:05 +, "Steven Schveighoffer" said: How does an author of a struct "not expect" the destructor to be called on an .init version of itself? Isn't that an error? Do you have a counter-case? struct S { @disable this(); } Nope, the way Walter designed the feature, when such a struct is a member, it will have opAssign called against an object initialized with .init. Generally I find this discussion difficult to get into. So you don't like the name clear() and you don't like the behavior of clear(). (Also, you seem to consider calling the destructor several times an impossibility. Why?) Anyhow, any chance to post a condensed list of issues as you see them along with proposed fixes? Thanks, Andrei
Re: Line lengths discussed in eclipse forum and on reddit
On 09/12/2011 03:50 PM, Adam D. Ruppe wrote: Imperial units are superior. Surely you're jesting. "It's zero degrees out." 0 F is actually pretty cold. 0 C is slightly chilly, but nothing to get worked up about. Zero degrees Celsius is the water freezing temperature, which is a very practical influencer (snow vs. rain, plants, crops, etc). Just like with kilometers, centimeters are useless. (ever gone on a kilometer run? Weak. Mile runs are where it's at.) Well an amount of subjectivism in comparing measuring units is inevitable, but reifying it goes a bit far. Andrei
Re: Clean-up of std.socket
Jonathan M Davis wrote: > On Monday, September 12, 2011 14:53 Adam Burton wrote: >> Simen Kjaeraas wrote: >> > On Mon, 12 Sep 2011 23:13:29 +0200, Adam Burton >> > wrote: >> >> I quite like the idea of >> >> void[] representing a chunk of memory that could contain anything, >> >> serialized data; an array of ubytes or strings, and allow ubyte[] to >> >> just represent an array of ubytes (after all is serialized data an >> >> array of bytes >> >> or a block of data containing various data types cramed into it in >> >> some organised manner?). In the end it is just a convention I like, >> >> not attached >> >> to it or anything, and D tends to discourage working based on >> >> conventions anyway, I guess I am somewhat playing devil's advocate in >> >> this paragraph >> >> >> >> :-). >> > >> > I believe the reasons for not using void[] is exactly that it could >> > contain anything, including pointers, which likely would not be valid >> > in the other end. >> >> How does a ubyte[] prevent that? If you've serialized an int (or even a >> pointer) then ubyte[] is just as bad, ubyte[0] would seem to indicate a >> meaningful unit of data itself when it's actually just the first byte of >> an int (or pointer). void[] at least says "I don't know, I just know the >> start and how long, you figure it out, I presume I have somewhere to go >> to be given context". > > With void[], you can pass something like int*[] to it without having to > worry about converting it, because the conversion is implicity. ubyte[], > on the other hand, forces you to do the conversion explicitly. So yes, you > could still make it so that the ubyte[] passed in contains pointers, but > you have to do it explicitly, whereas with void[], it'll take any array > without complaining. > > - Jonathan M Davis Fair enough that's more clear, I hadn't actually thought of an array of pointers as I was thinking of a pointer forced into ubyte[] with other data types. I suppose that'll help remind people to double check what they are sending but if you are going to send int*[] down a socket then you're probably gonna put cast(ubyte[]) without looking anyway.
Re: Clean-up of std.socket
On Mon, 12 Sep 2011 20:55:42 +0300, David Nadlinger wrote: As discussed on IRC, throwing on reverse lookup failure seems very wrong to me, as it is certainly expected. In my opinion, the best solution would be to return null (empty string), but I am not certain if it should still throw if something went wrong during lookup (besides the IP address not being found). I'm thinking of making all of Address.to(Addr|HostName|Port|Service)String return null on failure for consistency. Sounds good? I'll probably change the current std.socket.toHostAddrString() to behave like this, as the current behavior is inconsistent (when the getHostByAddr fallback is used), and I accidentally left it undocumented anyway. I'd prefer if we minimized changes on the master branch. I hope we can finalize and merge in the cleaned-up version before the next release anyway. -- Best regards, Vladimirmailto:vladi...@thecybershadow.net
Re: Clean-up of std.socket
On Monday, September 12, 2011 14:53 Adam Burton wrote: > Simen Kjaeraas wrote: > > On Mon, 12 Sep 2011 23:13:29 +0200, Adam Burton wrote: > >> I quite like the idea of > >> void[] representing a chunk of memory that could contain anything, > >> serialized data; an array of ubytes or strings, and allow ubyte[] to > >> just represent an array of ubytes (after all is serialized data an > >> array of bytes > >> or a block of data containing various data types cramed into it in some > >> organised manner?). In the end it is just a convention I like, not > >> attached > >> to it or anything, and D tends to discourage working based on > >> conventions anyway, I guess I am somewhat playing devil's advocate in > >> this paragraph > >> > >> :-). > > > > I believe the reasons for not using void[] is exactly that it could > > contain anything, including pointers, which likely would not be valid in > > the other end. > > How does a ubyte[] prevent that? If you've serialized an int (or even a > pointer) then ubyte[] is just as bad, ubyte[0] would seem to indicate a > meaningful unit of data itself when it's actually just the first byte of an > int (or pointer). void[] at least says "I don't know, I just know the start > and how long, you figure it out, I presume I have somewhere to go to be > given context". With void[], you can pass something like int*[] to it without having to worry about converting it, because the conversion is implicity. ubyte[], on the other hand, forces you to do the conversion explicitly. So yes, you could still make it so that the ubyte[] passed in contains pointers, but you have to do it explicitly, whereas with void[], it'll take any array without complaining. - Jonathan M Davis
Re: Clean-up of std.socket
Simen Kjaeraas wrote: > On Mon, 12 Sep 2011 23:13:29 +0200, Adam Burton wrote: >> I quite like the idea of >> void[] representing a chunk of memory that could contain anything, >> serialized data; an array of ubytes or strings, and allow ubyte[] to just >> represent an array of ubytes (after all is serialized data an array of >> bytes >> or a block of data containing various data types cramed into it in some >> organised manner?). In the end it is just a convention I like, not >> attached >> to it or anything, and D tends to discourage working based on conventions >> anyway, I guess I am somewhat playing devil's advocate in this paragraph >> :-). > > I believe the reasons for not using void[] is exactly that it could > contain anything, including pointers, which likely would not be valid in > the other end. > How does a ubyte[] prevent that? If you've serialized an int (or even a pointer) then ubyte[] is just as bad, ubyte[0] would seem to indicate a meaningful unit of data itself when it's actually just the first byte of an int (or pointer). void[] at least says "I don't know, I just know the start and how long, you figure it out, I presume I have somewhere to go to be given context".
Re: clear()
On 2011-09-12 20:04:05 +, "Steven Schveighoffer" said: How does an author of a struct "not expect" the destructor to be called on an .init version of itself? Isn't that an error? Do you have a counter-case? struct S { @disable this(); } I hated having clear call the default constructor. … because you use 'clear' to release resources. Which makes sense, but goes contrary to expectations for something called 'clear'. What I am saying is that 'clear' shouldn't be used to release resources, something else should be used for that. I think that's entirely the wrong thing to do. clear + deallocate replaces delete, wit h clear being the finalization of the data. Well, if you really wanted clear + deallocate to replace delete (regardless of the suitability of the name), don't make it so it looks like you can reuse the object/struct afterward. Saying it is assigning the 'init' state makes people believe the object will still be in a usable state although actually there is no guaranty of that, and that's true for a struct too (as shown above). Also, if 'clear' is meant to replace 'delete', it should give an error when called on non-GC memory because there's no way you can prevent the destructor from being called a second time otherwise. -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Clean-up of std.socket
On Mon, 12 Sep 2011 23:13:29 +0200, Adam Burton wrote: I quite like the idea of void[] representing a chunk of memory that could contain anything, serialized data; an array of ubytes or strings, and allow ubyte[] to just represent an array of ubytes (after all is serialized data an array of bytes or a block of data containing various data types cramed into it in some organised manner?). In the end it is just a convention I like, not attached to it or anything, and D tends to discourage working based on conventions anyway, I guess I am somewhat playing devil's advocate in this paragraph :-). I believe the reasons for not using void[] is exactly that it could contain anything, including pointers, which likely would not be valid in the other end. -- Simen
Re: cleaning up dsource
"Nick Sabalausky" wrote in message news:j4llsb$hvq$1...@digitalmars.com... > "maarten van damme" wrote in message > news:mailman.2825.1315840171.14074.digitalmar...@puremagic.com... >> well that's too bad >> an improved dsource would be a great step forward. D is already >> little-known >> (relative) having a site advertising a lot of dead projects and with a >> dead >> forum isn't going to help a lot :) >> > > I agree. Unfortunately, the site's maintainer, Brad Anderson, doesn't > appear to be active with D anymore :( Maybe the active projects need moving to another site... -=mike=-
Re: Clean-up of std.socket
Sean Kelly wrote: > On Sep 12, 2011, at 1:12 PM, Adam Burton wrote: > >> Sean Kelly wrote: >> >>> Looks much nicer than the current std.socket. A few random comments >>> from a quick scan of the code: >>> >>> Socket.send/receive should use ubyte[], not void[] for the data. >> Regardless if it is correct or wrong I think there is a reason it is >> void[] (I am sure you are aware of this but just in case you are not ;)). >> All arrays implicitly convert to void[] >> (http://www.digitalmars.com/d/2.0/arrays.html - Implicit conversions) and >> the array length is automatically modified such that it is a byte count >> (for example assigning a dstring "hello" to void[] sets void[]'s length >> to 20 while dstring is 5), this lets you send data to send/receive >> without having to cast it. I've inferred that to mean void[] is expected >> for buffers of bytes and ubyte[]/byte[] as arrays of bytes. > > Sure… but is this a feature that's actually desirable here? I suppose it > would be good for sending char strings, but other than that I'd probably > want to serialize the data somehow before sending it. Like I said, regardless if it is correct or wrong. I'm not arguing for it either way I was just making sure it was known why it would use void[]. If the data is serialized or not it makes no difference if send/receive uses ubyte[] or void[] since void[] can handle both. I quite like the idea of void[] representing a chunk of memory that could contain anything, serialized data; an array of ubytes or strings, and allow ubyte[] to just represent an array of ubytes (after all is serialized data an array of bytes or a block of data containing various data types cramed into it in some organised manner?). In the end it is just a convention I like, not attached to it or anything, and D tends to discourage working based on conventions anyway, I guess I am somewhat playing devil's advocate in this paragraph :-). The only reason I can see not to change it to ubyte[] is it seems to me a change that would be breaking, due to some code maybe needing casts, (or atleast require a fairly simple deprecation) with no real benefit (as far as I can see). That's assuming it is not turned into std.socket2 :-).
Re: Support for feeding data to engine threads?
On 9/12/2011 3:32 PM, Jerry Quinn wrote: The other thing I think I have to do is sequence the initializations. Otherwise the disk/network will thrash trying to load N copies simultaneously. I imagine this can be done with a shared variable inside the engine. This can easily be done by creating null engines in the WorkerLocalStorage and then initializing them inside a synchronized block: auto wlEngines = taskPool.workerLocalStorage(Engine.init); auto wlIsInitialized = taskPool.workerLocalStorage(false); // This gets executed on the pool in a Task: void taskFunction() { if(!wlIsInitialized.get) { // Do initialization of thread-local engine in worker thread. synchronized wlEngines.get = new Engine(ctorArgs); wlIsInitialized.get = true; } // Do main processing. } I prefer to do all the initializations before work starts so that timing can be more accurate. These things take a lot to get fully loaded and ready to run. Unfortunately I don't have a good answer for this constraint. If you can offer a concrete enhancement request for std.parallelism, I'll certainly consider it, but I can't think of a good design for this kind of per-thread initialization routine off the top of my head, either in terms of API or implementation.
Re: Line lengths discussed in eclipse forum and on reddit
"Adam D. Ruppe" wrote in message news:j4lrbg$s98$1...@digitalmars.com... > Nick Sabalausky wrote: >> What font/size do you use? > > Might be more informative to use a screenshot: > > http://arsdnet.net/desktop.png > > the white windows are the kind of thing I use for code most often. > > The email window shows the other linux font. > Yea, those are definitely more vertical than mine. So a space is narrower for you than for me. > > Anyway on indent size again, I think the biggest problem with me > is more outdents rather than indents. > > if using_ugly_language: >"i see this change despite being 4 chars" >if spanish_inquisition: >"nobody expects" >"amongst our weaponry are such diverse elements as" > "i can totally miss this" > > > That last line will mess up my brain. Maybe I'm just so used to > eight character indents, but when I see that change, it almost > always registers as a single change in level. > True. That's actually one of the reasons I don't like indentation-scoping. It's not so bad with braces.
Re: Support for feeding data to engine threads?
On 9/12/2011 3:32 PM, Jerry Quinn wrote: Thanks for all the help! It might be useful to indicate in the workerLocalData call that the lazy processing happens in the worker's thread. Sorry for the misunderstanding. When workerLocalStorage() is called, the lazy variable is evaluated once per worker thread, but it's evaluated **in the thread that workerLocalStorage() is called from**, **before workerLocalStorage() returns**.
Re: Clean-up of std.socket
On Mon, 12 Sep 2011 22:13:47 +0300, Sean Kelly wrote: Looks much nicer than the current std.socket. A few random comments from a quick scan of the code: Socket.send/receive should use ubyte[], not void[] for the data. I'd say this is debatable (e.g. File.rawWrite is templated to the same effect). It can't be changed without breaking compatibility, but it could be possible to add overloads and deprecate the void[] versions. I'd like some way to avoid new objects being created during any low-level socket operation I expect to do regularly. For example, socket.receiveFrom creates a new Address instance every time it's called. Perhaps I could have the option to supply an Address object to be overwritten instead? Good point. Luckily, this particular case has a simple and backwards-compatible fix: https://github.com/CyberShadow/phobos/commit/2fbb7d6287ccd760f4e1a6c91acb60f05bf52ed8 That Address.name() returns a sockaddr* is kind of weird. I'd expect it to return a string? I know that the sockaddr is generally called a "name" in API parlance, but it seems a bit weird in this context. Another oddity of the original design. Generally, we're free to rename methods and schedule aliases for old names for deprecation - and this method shouldn't have much use outside std.socket anyway. What would be a better name? Why is InternetHost an instantiable object? It has data fields that aren't initialized by any ctor, but only by calls where a hostent* is passed? And all for access to API calls which no one is supposed to use anyway? Please just make this go away :-) I'm not sure what to do about it. It's in use by current code. The Service and Protocol classes work in a similar manner (fields initialized by various methods). There are a number of bool parameters that should really be EnumName.yes/no. The only candidate I can spot is the Socket.blocking property. What did I miss? (Address.toHostString and toAddressString are private) The current approach that appears to be required for connecting to a remote host kind of stinks: Socket sock = null; foreach(info, getAddressInfo("www.digitalmars.com")) { try { sock = new Socket(info); // will throw if can't create a socket based on info sock.connect(info.address); break; } catch (Exception e) { sock = null; } } if (sock is null) // unable to connect via any available method! It's a question of how much gruntwork should the network module abstract away. FWIW, the situation is similar with Python: http://docs.python.org/library/socket.html (scroll down to second "Echo client program" example) I've heard opinions on IRC that std.socket should definitely not conflate connections with DNS lookups, thus a Socket.connect(string hostname) method wouldn't belong. As an aside… From your comments, I gather that you're not terribly happy with certain design requirements imposed by the existing std.socket. Why not create an entirely new API in std.socket2 and not worry about it? Would your design change enough to warrant doing this? I'm not sure if I can find the time and commitment to design an entirely new socket API at the moment. Simply put, I tried to improve the existing module without breaking too much. -- Best regards, Vladimirmailto:vladi...@thecybershadow.net
Re: Line lengths discussed in eclipse forum and on reddit
Nick Sabalausky wrote: > What font/size do you use? Depends what program I have open. But it's one of these three: fixed size 14 (pixels probably) on linux. (it's a bitmap font that is rxvt's default for me) bitstream vera monospace size 16.. I think.. if I spring for the fanciness of an xterm. and the putty default, which I believe is Courier New, 10 point, if I'm on Windows. Might be more informative to use a screenshot: http://arsdnet.net/desktop.png the white windows are the kind of thing I use for code most often. The email window shows the other linux font. > Fuck these stupid imperial units. Imperial units are superior. "It's zero degrees out." 0 F is actually pretty cold. 0 C is slightly chilly, but nothing to get worked up about. Inches beat centimeters any day of the week. Just like with kilometers, centimeters are useless. (ever gone on a kilometer run? Weak. Mile runs are where it's at.) You're always going to be doing some multiple or fraction. English units go naturally to fractions - following very useful powers of two! A half inch is... well, half an inch. You can eyeball the middle of a full inch and be on target. What if you want half a centimeter? Now it's some vile 5 mm... still workable though. Turns out that didn't fit either. Let's cut in half again. English: 1/4 inch. Sane. Metric: 2.5 mm gross! So then you have 2mm sometimes, and 3mm sometimes, and it's just a pain to eyeball the difference. > Maybe I've lost my mind, but I could swear american > rulers and tape measures always used to have imperial along one > side and metric along the other. My ruler and square have both, but my yard stick and tape measure are only imperial... > (I might do things differently if I were on a widescreen, though. I suspect it's more of a focus model matter. at least for me. (I just refuse to use widescreens, so no big experience there) If clicking a window raises it, it's a pain to stack, since they keep covering each other in underdesired ways. Might as well just maximize it. But, when I can turn that dreadful behavior off, I avoid maximization whenever possible, since I actually can use the whole thing. Anyway on indent size again, I think the biggest problem with me is more outdents rather than indents. if using_ugly_language: "i see this change despite being 4 chars" if spanish_inquisition: "nobody expects" "amongst our weaponry are such diverse elements as" "i can totally miss this" That last line will mess up my brain. Maybe I'm just so used to eight character indents, but when I see that change, it almost always registers as a single change in level. The indents aren't too bad, since at least there's a block of stuff surrounding it. It's still easy for me to skip past, but not a huge deal. But, outdents are harder to see. I think part of it is I'm so used to seeing changes of 8 that 4*2 = 8*1, so I register one change instead of two. Closing braces help a lot though, since seeing two braces going out very clearly marks the end of /something/. writeln("eating is fun"); } } Not ideal, but it at least works for me.
Re: Clean-up of std.socket
On Sep 12, 2011, at 1:12 PM, Adam Burton wrote: > Sean Kelly wrote: > >> Looks much nicer than the current std.socket. A few random comments from >> a quick scan of the code: >> >> Socket.send/receive should use ubyte[], not void[] for the data. > Regardless if it is correct or wrong I think there is a reason it is void[] > (I am sure you are aware of this but just in case you are not ;)). All > arrays implicitly convert to void[] > (http://www.digitalmars.com/d/2.0/arrays.html - Implicit conversions) and > the array length is automatically modified such that it is a byte count (for > example assigning a dstring "hello" to void[] sets void[]'s length to 20 > while dstring is 5), this lets you send data to send/receive without having > to cast it. I've inferred that to mean void[] is expected for buffers of > bytes and ubyte[]/byte[] as arrays of bytes. Sure… but is this a feature that's actually desirable here? I suppose it would be good for sending char strings, but other than that I'd probably want to serialize the data somehow before sending it.
Re: D in the TIOBE top
On 09/12/2011 01:38 PM, Jeff Nowakowski wrote: On 09/12/2011 11:43 AM, Andrei Alexandrescu wrote: Accuracy (i.e. figuring the "right" ranking) is probably indeed low, but Tiobe's methods are a reasonable proxy for a language's presence. I see the increase of D's Tiobe rank not as a surprise or some random artifact, but a reflection of the strong progress in the past months. D is prone to overcounting because it's common name matches lots of unrelated stuff, including things like 3-D programming. The Tiobe folks can't be counted on to come up with an accurate measure to filter it out. The latest spike could be for any number of reasons. You might as well be reading tea leaves. People were scoffing at Scala at number #50, but in my experience it's just as mainstream than D is, and very likely much more. Want some stats? Martin's book on Amazon is #17,254. Andrei's book is #159,672. There are over a dozen Scala books on the market. Stack overflow shows 5,606 tagged with "scala", and 430 questions tagged with "d". Lame marketing, Andrei. But hey, it works, right? I have no connection with Tiobe and the name "D" wasn't chosen to manipulate its ranking method. Are you disagreeing with my posting of a piece of information on a community-voted forum? I wouldn't quite understand what the matter is here, if it weren't for your posting history. Thanks, Andrei
Re: Pull 375 and related enhancements
Nick Sabalausky: > I think you mean: > > auto a = padArrayLiteral!ubyte(10, [1, 2]); > void main() {} I think Don knows what I meant :-) I meant something like: ubyte[256] a = padArrayLiteral!ubyte(256, [1, 2]); Bye and sorry, bearophile
Re: Clean-up of std.socket
Sean Kelly wrote: > Looks much nicer than the current std.socket. A few random comments from > a quick scan of the code: > > Socket.send/receive should use ubyte[], not void[] for the data. Regardless if it is correct or wrong I think there is a reason it is void[] (I am sure you are aware of this but just in case you are not ;)). All arrays implicitly convert to void[] (http://www.digitalmars.com/d/2.0/arrays.html - Implicit conversions) and the array length is automatically modified such that it is a byte count (for example assigning a dstring "hello" to void[] sets void[]'s length to 20 while dstring is 5), this lets you send data to send/receive without having to cast it. I've inferred that to mean void[] is expected for buffers of bytes and ubyte[]/byte[] as arrays of bytes. > > I'd like some way to avoid new objects being created during any low-level > socket operation I expect to do regularly. For example, > socket.receiveFrom creates a new Address instance every time it's called. > Perhaps I could have the option to supply an Address object to be > overwritten instead? > > That Address.name() returns a sockaddr* is kind of weird. I'd expect it > to return a string? I know that the sockaddr is generally called a "name" > in API parlance, but it seems a bit weird in this context. > > Why is InternetHost an instantiable object? It has data fields that > aren't initialized by any ctor, but only by calls where a hostent* is > passed? And all for access to API calls which no one is supposed to use > anyway? Please just make this go away :-) > > There are a number of bool parameters that should really be > EnumName.yes/no. > > The current approach that appears to be required for connecting to a > remote host kind of stinks: > > Socket sock = null; > foreach(info, getAddressInfo("www.digitalmars.com")) { > try { > sock = new Socket(info); // will throw if can't create a > socket based on info sock.connect(info.address); > break; > } catch (Exception e) { > sock = null; > } > } > if (sock is null) > // unable to connect via any available method! > > As an aside… From your comments, I gather that you're not terribly happy > with certain design requirements imposed by the existing std.socket. Why > not create an entirely new API in std.socket2 and not worry about it? > Would your design change enough to warrant doing this?
Re: clear()
On Mon, 12 Sep 2011 15:43:13 -0400, Michel Fortin wrote: On 2011-09-12 11:37:20 +, "Steven Schveighoffer" said: On Mon, 12 Sep 2011 07:12:19 -0400, Michel Fortin wrote: On 2011-09-11 10:23:21 +, "Marco Leise" said: Enough sarcasm. If I recall, Andrei liked the name 'clear' and was unsympathetic to the arguments that it'd be confusing. 'clear' is explained in TDPL and Andrei doesn't like to break his book, so we might be stuck with that mess for while. But I think it's clear by now that that 'clear' is confusing and dangerous: it will work with certain types and completely blow up with others depending on implementation details of the type (calling the destructor twice, it's insane!). And the name just make it sounds like it's something pretty normal to do, which is probably the worse part of it. Actually no, the worse part is probably that it's inside module 'object', the only module imported by default everywhere, so you can't even escape the confusion by not importing its module. :-( While I share your sentiment that clear is too useful a term to be relegated to only be "call the destructor" (in fact, I use clear as a member function in my dcollections library, which probably adds to the confusion), I still think that the function should work. What types does it "blow up" on? What types does it call the destructor twice? I'd like to fix these. It can "blow up" when the destructor is called twice and the destructor doesn't expect this. The destructor will be called twice when you use it on a struct variable on the stack. You'll probably say it shouldn't be used on stack variables, but if something work, especially if it looks pretty and appropriate like 'clear' does, people will use it anyway and write programs that'll break later when the implementation behind an API changes. Remember that this problem couldn't happen with 'delete'… I'm not sure that's valid. If you can declare a struct, you can declare an uninitialized struct, whose destructor *will* be called when the scope exits. How does an author of a struct "not expect" the destructor to be called on an .init version of itself? Isn't that an error? Do you have a counter-case? 'clear' conflates two things: restoring the object to its pristine state, and releasing resources. It does succeed at releasing resources, but only because it reaches half of the former goal. I think it'd be much wiser to have two different functions for these two concepts. I think 'delete' is the one that should be tasked with releasing resources. Just change 'delete' so it calls the destructor, wipes all the bits, but keep the memory block alive so it gets collected later by the GC, keeping things memory-safe. There's absolutely no point in reinstating the original 'init' bits if what you want is to destroy the object. 'delete' only works with memory allocated on the heap, not stack variables, not memory allocated elsewhere, so it's easy to make sure destructors don't get called twice because that's a bit in the GC's block flags. Then you can make 'clear' a function that actually does what people expects it to do: restore the object to its pristine state: calling the destructor, reinstating the 'init' bits, then calling constructor again if necessary. It could be safe to call on stack variables, and it could fail if the default constructor is disabled (like in NotNull!T). I hated having clear call the default constructor. I think that's entirely the wrong thing to do. clear + deallocate replaces delete, with clear being the finalization of the data. If you want to reallocate, you can always reassign the reference to a default-constructed object. -Steve
Re: clear()
On 2011-09-12 11:37:20 +, "Steven Schveighoffer" said: On Mon, 12 Sep 2011 07:12:19 -0400, Michel Fortin wrote: On 2011-09-11 10:23:21 +, "Marco Leise" said: Enough sarcasm. If I recall, Andrei liked the name 'clear' and was unsympathetic to the arguments that it'd be confusing. 'clear' is explained in TDPL and Andrei doesn't like to break his book, so we might be stuck with that mess for while. But I think it's clear by now that that 'clear' is confusing and dangerous: it will work with certain types and completely blow up with others depending on implementation details of the type (calling the destructor twice, it's insane!). And the name just make it sounds like it's something pretty normal to do, which is probably the worse part of it. Actually no, the worse part is probably that it's inside module 'object', the only module imported by default everywhere, so you can't even escape the confusion by not importing its module. :-( While I share your sentiment that clear is too useful a term to be relegated to only be "call the destructor" (in fact, I use clear as a member function in my dcollections library, which probably adds to the confusion), I still think that the function should work. What types does it "blow up" on? What types does it call the destructor twice? I'd like to fix these. It can "blow up" when the destructor is called twice and the destructor doesn't expect this. The destructor will be called twice when you use it on a struct variable on the stack. You'll probably say it shouldn't be used on stack variables, but if something work, especially if it looks pretty and appropriate like 'clear' does, people will use it anyway and write programs that'll break later when the implementation behind an API changes. Remember that this problem couldn't happen with 'delete'… 'clear' conflates two things: restoring the object to its pristine state, and releasing resources. It does succeed at releasing resources, but only because it reaches half of the former goal. I think it'd be much wiser to have two different functions for these two concepts. I think 'delete' is the one that should be tasked with releasing resources. Just change 'delete' so it calls the destructor, wipes all the bits, but keep the memory block alive so it gets collected later by the GC, keeping things memory-safe. There's absolutely no point in reinstating the original 'init' bits if what you want is to destroy the object. 'delete' only works with memory allocated on the heap, not stack variables, not memory allocated elsewhere, so it's easy to make sure destructors don't get called twice because that's a bit in the GC's block flags. Then you can make 'clear' a function that actually does what people expects it to do: restore the object to its pristine state: calling the destructor, reinstating the 'init' bits, then calling constructor again if necessary. It could be safe to call on stack variables, and it could fail if the default constructor is disabled (like in NotNull!T). -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Pull 375 and related enhancements
"bearophile" wrote in message news:j4krf0$2070$1...@digitalmars.com... > Don: > >> As I said in my other post, we could deal with this using a CTFE library >> solution. > > Currently this works: > > ubyte[10] a = [1, 2]; > void main() {} > > But if you write this, I think padArrayLiteral returns an int[], so D > refuses the implicit cast: > > ubyte[10] a = padArrayLiteral(256, [1, 2]); > void main() {} > > So I think you have to write something like: > > ubyte[10] a = padArrayLiteral!ubyte(256, [1, 2]); > void main() {} > I think you mean: auto a = padArrayLiteral!ubyte(10, [1, 2]); void main() {} ? --- Not sent from an iPhone.
Re: Support for feeding data to engine threads?
dsimcha Wrote: > == Quote from Jerry Quinn (jlqu...@optonline.net)'s article > > Timon Gehr Wrote: > > > On 09/12/2011 07:23 PM, Jerry Quinn wrote: > > > > I'm looking at porting an app that maintains a work queue to be > > > > processed by > one of N engines and written out in order. At first glance, std.parallelism > already provides the queue, but the Task concept appears to assume that > there's no > startup cost per thread. > > > > > > > > Am I missing something or do I need to roll a shared queue object? > > > > > > I don't know if I get you right, but std.parallelism uses a task pool. > > > Usually no threads are started or stopped during processing. > > OK I guess what I'm looking for is WorkerLocalStorage. I can create an > > engine > per thread. However, I probably need to have each thread do the > initialization > work. If I create the engine on the main thread, it won't be properly > accessed by > the worker thread, right? I.e. I need each thread to run engine.init() which > will > do a whole pile of loading and setup first before I can start feeding data to > the > pool. > > The impression I get is that > > for (int i=0; i < nthreads; i++) > > taskPool.workerLocalStorage(new engine(datafile)) > > will not get me what I want. > > The parameter for taskPool.workerLocalStorage is lazy, so it's even easier: > > taskPool.workerLocalStorage(new engine(datafile)); > > will create one new engine **per thread** because the lazy parameter is > passed to > it and evaluated **once per thread**. I'm not sure what an engine is in this > context, though. An engine is simply a complex class that takes a lot of memory and setup work to prepare. I'm working on language processing, so we use large multiGB models. Great, I'm getting closer. So the evaluation happens in the worker thread, not the main thread, right? The other thing I think I have to do is sequence the initializations. Otherwise the disk/network will thrash trying to load N copies simultaneously. I imagine this can be done with a shared variable inside the engine. > As far as initialization, you could do something like: > > auto isInitialized = taskPool.workerLocalStorage(false); > > void doStuff() { > if(!isInitialized.get) { > engines.get.initialize(); > isInitialized.get = true; > } > > // Do some real processing. > } I prefer to do all the initializations before work starts so that timing can be more accurate. These things take a lot to get fully loaded and ready to run. Thanks for all the help! It might be useful to indicate in the workerLocalData call that the lazy processing happens in the worker's thread. Jerry
Re: Support for feeding data to engine threads?
== Quote from Jerry Quinn (jlqu...@optonline.net)'s article > dsimcha Wrote: > > == Quote from Jerry Quinn (jlqu...@optonline.net)'s article > > > I'm looking at porting an app that maintains a work queue to be processed > > > by one > > of N engines and written out in order. At first glance, std.parallelism > > already > > provides the queue, but the Task concept appears to assume that there's no > > startup > > cost per thread. > > > Am I missing something or do I need to roll a shared queue object? > > > > Not sure if I'm misunderstanding what you're asking, but I'll answer the > > question > > I think you're asking. std.parallelism's Task can be executed in two ways. > > executeInNewThread() does start a new thread for every Task. However, you > > can > > also submit a Task to a TaskPool and have it executed by an existing worker > > thread. The whole point of using TaskPool to execute a Task is to avoid > > paying > > the thread start-up cost for every Task. > The question I was asking was how to execute a huge amount of per-thread initialization once per thread in the TaskPool framework. Hmm, currently there isn't an easy/obvious way, though I'm thinking maybe one should be added. I've kind of needed it, too, and I don't anticipate it being very hard to implement. If you can suggest a good API for this, I'll work on it for next release.
Re: Support for feeding data to engine threads?
dsimcha Wrote: > == Quote from Jerry Quinn (jlqu...@optonline.net)'s article > > I'm looking at porting an app that maintains a work queue to be processed > > by one > of N engines and written out in order. At first glance, std.parallelism > already > provides the queue, but the Task concept appears to assume that there's no > startup > cost per thread. > > Am I missing something or do I need to roll a shared queue object? > > Not sure if I'm misunderstanding what you're asking, but I'll answer the > question > I think you're asking. std.parallelism's Task can be executed in two ways. > executeInNewThread() does start a new thread for every Task. However, you can > also submit a Task to a TaskPool and have it executed by an existing worker > thread. The whole point of using TaskPool to execute a Task is to avoid > paying > the thread start-up cost for every Task. The question I was asking was how to execute a huge amount of per-thread initialization once per thread in the TaskPool framework.
Re: Support for feeding data to engine threads?
Timon Gehr Wrote: > On 09/12/2011 08:01 PM, Jerry Quinn wrote: > > Timon Gehr Wrote: > > > >> On 09/12/2011 07:23 PM, Jerry Quinn wrote: > >>> I'm looking at porting an app that maintains a work queue to be processed > >>> by one of N engines and written out in order. At first glance, > >>> std.parallelism already provides the queue, but the Task concept appears > >>> to assume that there's no startup cost per thread. > >>> > >>> Am I missing something or do I need to roll a shared queue object? > >> > >> I don't know if I get you right, but std.parallelism uses a task pool. > >> Usually no threads are started or stopped during processing. > > > > OK I guess what I'm looking for is WorkerLocalStorage. I can create an > > engine per thread. However, I probably need to have each thread do the > > initialization work. If I create the engine on the main thread, it won't > > be properly accessed by the worker thread, right? I.e. I need each thread > > to run engine.init() which will do a whole pile of loading and setup first > > before I can start feeding data to the pool. > > > > The impression I get is that > > > > for (int i=0; i< nthreads; i++) > >taskPool.workerLocalStorage(new engine(datafile)) > > > > will not get me what I want. > > > > > > Calling workerLocalStorage once suffices. > > auto engine=taskPool.workerLocalStorage(new Engine(datafile)); > > This will create one engine per working thread and and the same datafile. > > You can access the engine from each thread with engine.get. What is the > exact role of datafile? Does it have to be distinct for each engine? datafile is just a set of parameters for configuring the engine, i.e location of data, parameter values, etc. In this setting it would be the same for each engine.
Re: Pull 375 and related enhancements
bearophile wrote: > Don: > >> As I said in my other post, we could deal with this using a CTFE library >> solution. > > Currently this works: > > ubyte[10] a = [1, 2]; > void main() {} > > But if you write this, I think padArrayLiteral returns an int[], so D > refuses the implicit cast: > > ubyte[10] a = padArrayLiteral(256, [1, 2]); > void main() {} > Why you're padding to 256 entries when a ubyte[10] is needed? ;) > So I think you have to write something like: > > ubyte[10] a = padArrayLiteral!ubyte(256, [1, 2]); > void main() {} > > Bye, > bearophile Or: auto a = staticArray!(ubyte[10])([1, 2]); (staticArray() is like array() which can take arbitrary ranges, but it returns a static array formed by take-ing the range and padding with ElementType.init.)
Re: cleaning up dsource
"maarten van damme" wrote in message news:mailman.2825.1315840171.14074.digitalmar...@puremagic.com... > well that's too bad > an improved dsource would be a great step forward. D is already > little-known > (relative) having a site advertising a lot of dead projects and with a > dead > forum isn't going to help a lot :) > I agree. Unfortunately, the site's maintainer, Brad Anderson, doesn't appear to be active with D anymore :( --- Not sent from an iPhone.
Re: Clean-up of std.socket
Looks much nicer than the current std.socket. A few random comments from a quick scan of the code: Socket.send/receive should use ubyte[], not void[] for the data. I'd like some way to avoid new objects being created during any low-level socket operation I expect to do regularly. For example, socket.receiveFrom creates a new Address instance every time it's called. Perhaps I could have the option to supply an Address object to be overwritten instead? That Address.name() returns a sockaddr* is kind of weird. I'd expect it to return a string? I know that the sockaddr is generally called a "name" in API parlance, but it seems a bit weird in this context. Why is InternetHost an instantiable object? It has data fields that aren't initialized by any ctor, but only by calls where a hostent* is passed? And all for access to API calls which no one is supposed to use anyway? Please just make this go away :-) There are a number of bool parameters that should really be EnumName.yes/no. The current approach that appears to be required for connecting to a remote host kind of stinks: Socket sock = null; foreach(info, getAddressInfo("www.digitalmars.com")) { try { sock = new Socket(info); // will throw if can't create a socket based on info sock.connect(info.address); break; } catch (Exception e) { sock = null; } } if (sock is null) // unable to connect via any available method! As an aside… From your comments, I gather that you're not terribly happy with certain design requirements imposed by the existing std.socket. Why not create an entirely new API in std.socket2 and not worry about it? Would your design change enough to warrant doing this?
Re: D in the TIOBE top
On Mon, Sep 12, 2011 at 1:38 PM, Jeff Nowakowski wrote: > On 09/12/2011 11:43 AM, Andrei Alexandrescu wrote: > >> >> Accuracy (i.e. figuring the "right" ranking) is probably indeed low, but >> Tiobe's methods are a reasonable proxy for a language's presence. I see >> the increase of D's Tiobe rank not as a surprise or some random >> artifact, but a reflection of the strong progress in the past months. >> > > D is prone to overcounting because it's common name matches lots of > unrelated stuff, including things like 3-D programming. The Tiobe folks > can't be counted on to come up with an accurate measure to filter it out. > The latest spike could be for any number of reasons. You might as well be > reading tea leaves. > > People were scoffing at Scala at number #50, but in my experience it's just > as mainstream than D is, and very likely much more. Want some stats? > Martin's book on Amazon is #17,254. Andrei's book is #159,672. There are > over a dozen Scala books on the market. Stack overflow shows 5,606 tagged > with "scala", and 430 questions tagged with "d". > > Lame marketing, Andrei. But hey, it works, right? > The lame marketing is when programming languages need big corporate money and power to get them to any level of popularity. Did you forget what happened with Google Go? Not a language that's any better than D, but because of Google now everyone knows about it. No different with Scala, Java, etc. When was the last time we had something like Scalathon for D with corporate sponsors such as Google?
Re: Support for feeding data to engine threads?
== Quote from Jerry Quinn (jlqu...@optonline.net)'s article > Timon Gehr Wrote: > > On 09/12/2011 07:23 PM, Jerry Quinn wrote: > > > I'm looking at porting an app that maintains a work queue to be processed > > > by one of N engines and written out in order. At first glance, std.parallelism already provides the queue, but the Task concept appears to assume that there's no startup cost per thread. > > > > > > Am I missing something or do I need to roll a shared queue object? > > > > I don't know if I get you right, but std.parallelism uses a task pool. > > Usually no threads are started or stopped during processing. > OK I guess what I'm looking for is WorkerLocalStorage. I can create an engine per thread. However, I probably need to have each thread do the initialization work. If I create the engine on the main thread, it won't be properly accessed by the worker thread, right? I.e. I need each thread to run engine.init() which will do a whole pile of loading and setup first before I can start feeding data to the pool. > The impression I get is that > for (int i=0; i < nthreads; i++) > taskPool.workerLocalStorage(new engine(datafile)) > will not get me what I want. The parameter for taskPool.workerLocalStorage is lazy, so it's even easier: taskPool.workerLocalStorage(new engine(datafile)); will create one new engine **per thread** because the lazy parameter is passed to it and evaluated **once per thread**. I'm not sure what an engine is in this context, though. As far as initialization, you could do something like: auto isInitialized = taskPool.workerLocalStorage(false); void doStuff() { if(!isInitialized.get) { engines.get.initialize(); isInitialized.get = true; } // Do some real processing. }
Re: Support for feeding data to engine threads?
== Quote from Jerry Quinn (jlqu...@optonline.net)'s article > I'm looking at porting an app that maintains a work queue to be processed by > one of N engines and written out in order. At first glance, std.parallelism already provides the queue, but the Task concept appears to assume that there's no startup cost per thread. > Am I missing something or do I need to roll a shared queue object? Not sure if I'm misunderstanding what you're asking, but I'll answer the question I think you're asking. std.parallelism's Task can be executed in two ways. executeInNewThread() does start a new thread for every Task. However, you can also submit a Task to a TaskPool and have it executed by an existing worker thread. The whole point of using TaskPool to execute a Task is to avoid paying the thread start-up cost for every Task.
Re: Support for feeding data to engine threads?
On 09/12/2011 08:01 PM, Jerry Quinn wrote: Timon Gehr Wrote: On 09/12/2011 07:23 PM, Jerry Quinn wrote: I'm looking at porting an app that maintains a work queue to be processed by one of N engines and written out in order. At first glance, std.parallelism already provides the queue, but the Task concept appears to assume that there's no startup cost per thread. Am I missing something or do I need to roll a shared queue object? I don't know if I get you right, but std.parallelism uses a task pool. Usually no threads are started or stopped during processing. OK I guess what I'm looking for is WorkerLocalStorage. I can create an engine per thread. However, I probably need to have each thread do the initialization work. If I create the engine on the main thread, it won't be properly accessed by the worker thread, right? I.e. I need each thread to run engine.init() which will do a whole pile of loading and setup first before I can start feeding data to the pool. The impression I get is that for (int i=0; i< nthreads; i++) taskPool.workerLocalStorage(new engine(datafile)) will not get me what I want. Calling workerLocalStorage once suffices. auto engine=taskPool.workerLocalStorage(new Engine(datafile)); This will create one engine per working thread and and the same datafile. You can access the engine from each thread with engine.get. What is the exact role of datafile? Does it have to be distinct for each engine?
Re: D in the TIOBE top
On 09/12/2011 11:43 AM, Andrei Alexandrescu wrote: Accuracy (i.e. figuring the "right" ranking) is probably indeed low, but Tiobe's methods are a reasonable proxy for a language's presence. I see the increase of D's Tiobe rank not as a surprise or some random artifact, but a reflection of the strong progress in the past months. D is prone to overcounting because it's common name matches lots of unrelated stuff, including things like 3-D programming. The Tiobe folks can't be counted on to come up with an accurate measure to filter it out. The latest spike could be for any number of reasons. You might as well be reading tea leaves. People were scoffing at Scala at number #50, but in my experience it's just as mainstream than D is, and very likely much more. Want some stats? Martin's book on Amazon is #17,254. Andrei's book is #159,672. There are over a dozen Scala books on the market. Stack overflow shows 5,606 tagged with "scala", and 430 questions tagged with "d". Lame marketing, Andrei. But hey, it works, right?
Re: D in the TIOBE top
On Mon, 12 Sep 2011 18:57:16 +0200, bearophile wrote: Timon Gehr: You lose vs haskell because haskell does not recompute the same PowerSet multiple times. Are you sure? I have tried with memoization, but now it's slower (about 5.8 seconds). Note: to use memoize I have had to add the opCall. Is this really necessary for memoization of a struct? import std.stdio, std.array, std.range, std.functional; struct PowerSet(T) { T[] items; static PowerSet opCall(T[] it) { PowerSet p; p.items = it; return p; } int opApply(int delegate(ref T[]) dg) { int result; T[] res; T[30] buf; if (!items.length) { result = dg(res); } else { outer: foreach (opt; [items[0..1], []]) { buf[0 .. opt.length] = opt[]; alias memoize!PowerSet mPowerSet; foreach (r; mPowerSet(items[1..$])) { buf[opt.length .. opt.length + r.length] = r[]; You are copying recursively here. You should pass a slice to the recursive instance. res = buf[0 .. (opt.length + r.length)]; result = dg(res); if (result) break outer; } } } return result; } } void main() { size_t count; foreach (x; PowerSet!int(array(iota(22 count++; writeln(count); } Bye, bearophile Besides this can be wrapped in a random access range, which takes predictable 65ms * 2 ^ (setSize - 22) for me. https://gist.github.com/1211961
Re: Support for feeding data to engine threads?
Timon Gehr Wrote: > On 09/12/2011 07:23 PM, Jerry Quinn wrote: > > I'm looking at porting an app that maintains a work queue to be processed > > by one of N engines and written out in order. At first glance, > > std.parallelism already provides the queue, but the Task concept appears to > > assume that there's no startup cost per thread. > > > > Am I missing something or do I need to roll a shared queue object? > > I don't know if I get you right, but std.parallelism uses a task pool. > Usually no threads are started or stopped during processing. OK I guess what I'm looking for is WorkerLocalStorage. I can create an engine per thread. However, I probably need to have each thread do the initialization work. If I create the engine on the main thread, it won't be properly accessed by the worker thread, right? I.e. I need each thread to run engine.init() which will do a whole pile of loading and setup first before I can start feeding data to the pool. The impression I get is that for (int i=0; i < nthreads; i++) taskPool.workerLocalStorage(new engine(datafile)) will not get me what I want.
Re: Clean-up of std.socket
On 9/12/11 4:11 PM, Vladimir Panteleev wrote: * Currently, reverse hostname lookup functions throw on failure. Such lookups are not reliable and are expected to sometimes fail, so perhaps a more appropriate behavior would be to return the requested IP address unchanged, or a value indicating failure (null or false). As discussed on IRC, throwing on reverse lookup failure seems very wrong to me, as it is certainly expected. In my opinion, the best solution would be to return null (empty string), but I am not certain if it should still throw if something went wrong during lookup (besides the IP address not being found). I'll probably change the current std.socket.toHostAddrString() to behave like this, as the current behavior is inconsistent (when the getHostByAddr fallback is used), and I accidentally left it undocumented anyway. David
Re: Support for feeding data to engine threads?
On 09/12/2011 07:23 PM, Jerry Quinn wrote: I'm looking at porting an app that maintains a work queue to be processed by one of N engines and written out in order. At first glance, std.parallelism already provides the queue, but the Task concept appears to assume that there's no startup cost per thread. Am I missing something or do I need to roll a shared queue object? I don't know if I get you right, but std.parallelism uses a task pool. Usually no threads are started or stopped during processing.
Re: D in the TIOBE top
On 09/12/2011 06:57 PM, bearophile wrote: Timon Gehr: You lose vs haskell because haskell does not recompute the same PowerSet multiple times. Are you sure? I have tried with memoization, but now it's slower (about 5.8 seconds). Note: to use memoize I have had to add the opCall. Is this really necessary for memoization of a struct? import std.stdio, std.array, std.range, std.functional; struct PowerSet(T) { T[] items; static PowerSet opCall(T[] it) { PowerSet p; p.items = it; return p; } int opApply(int delegate(ref T[]) dg) { int result; T[] res; T[30] buf; if (!items.length) { result = dg(res); } else { outer: foreach (opt; [items[0..1], []]) { buf[0 .. opt.length] = opt[]; alias memoize!PowerSet mPowerSet; foreach (r; mPowerSet(items[1..$])) { buf[opt.length .. opt.length + r.length] = r[]; res = buf[0 .. (opt.length + r.length)]; result = dg(res); if (result) break outer; } } } return result; } } void main() { size_t count; foreach (x; PowerSet!int(array(iota(22 count++; writeln(count); } Bye, bearophile std.functional.memoize uses AAs internally, so that is very slow. Haskell builds a linked data structure, if you have result: [...,[2,3],[1,2,3]] then the [2,3] part is exactly the same for both. Also, if you only look at the length, the haskell code probably does not fully evaluate the power set.
Support for feeding data to engine threads?
I'm looking at porting an app that maintains a work queue to be processed by one of N engines and written out in order. At first glance, std.parallelism already provides the queue, but the Task concept appears to assume that there's no startup cost per thread. Am I missing something or do I need to roll a shared queue object?
Re: D in the TIOBE top
Timon Gehr: > You lose vs haskell because haskell does not recompute the same PowerSet > multiple times. Are you sure? I have tried with memoization, but now it's slower (about 5.8 seconds). Note: to use memoize I have had to add the opCall. Is this really necessary for memoization of a struct? import std.stdio, std.array, std.range, std.functional; struct PowerSet(T) { T[] items; static PowerSet opCall(T[] it) { PowerSet p; p.items = it; return p; } int opApply(int delegate(ref T[]) dg) { int result; T[] res; T[30] buf; if (!items.length) { result = dg(res); } else { outer: foreach (opt; [items[0..1], []]) { buf[0 .. opt.length] = opt[]; alias memoize!PowerSet mPowerSet; foreach (r; mPowerSet(items[1..$])) { buf[opt.length .. opt.length + r.length] = r[]; res = buf[0 .. (opt.length + r.length)]; result = dg(res); if (result) break outer; } } } return result; } } void main() { size_t count; foreach (x; PowerSet!int(array(iota(22 count++; writeln(count); } Bye, bearophile
Re: D in the TIOBE top
Agreed Andrei, As you may have noticed, I've been visiting D at maybe 6 month intervals for some time. Suddenly it seems real. There are alternative implementations, the library looks like something quite comprehensive, and we're more or less back to there being one version. Like I said - "I just wanted to say..." Walter, Thanks for the retrospective compliment. Coming from you, that means a lot ;=) Steve
Re: D in the TIOBE top
On 12.09.2011 17:43, Andrei Alexandrescu wrote: On 9/12/11 10:19 AM, Jeff Nowakowski wrote: On 09/11/2011 10:28 PM, Caligo wrote: I don't understand why some would down vote such a news. a lot of haters out there I suppose. Probably because Tiobe is a piece of shit when it comes to accuracy, so crowing about your "top 20" Tiobe number brings out the hate for lame marketing. Accuracy (i.e. figuring the "right" ranking) is probably indeed low, but Tiobe's methods are a reasonable proxy for a language's presence. I see the increase of D's Tiobe rank not as a surprise or some random artifact, but a reflection of the strong progress in the past months. Andrei If you look at the graph, it's clear that about half of the increase relative to last month is just a noise spike. D will drop out of the top 20 next month. Nonetheless there does seem to be a small yet continuous upwards trend; it should be reliably in the top 20 within six months time.
Re: D in the TIOBE top
== Quote from Andrei Alexandrescu (seewebsiteforem...@erdani.org)'s article > On 9/12/11 7:28 AM, Timon Gehr wrote: > > This eager D version uncovered a DMD bug: > > > > import std.stdio, std.algorithm, std.range; > > T[][] powerset(T)(T[] xs){ > > T[][] r=new T[][](1< > foreach(i,ref x;r) x=array(indexed(xs,filter!((a){return > > 1< > return r; > > } > > > > void main(){ > > writeln(powerset([1,2,3])); > > } > > > > This does not compile iff the -inline flag is passed to DMD 2.055. > goto bugzilla; > Andrei Looks like this old bug report: http://d.puremagic.com/issues/show_bug.cgi?id=4724 I'd love to see fixing all the lambda function issues be the next big push for improving DMD. Right now, they're so buggy it's not even funny. Besides 4724, the other one that really irks me and severely limits the usability of std.parallelism is http://d.puremagic.com/issues/show_bug.cgi?id=5710 .
Re: D in the TIOBE top
On 9/12/11 10:19 AM, Jeff Nowakowski wrote: On 09/11/2011 10:28 PM, Caligo wrote: I don't understand why some would down vote such a news. a lot of haters out there I suppose. Probably because Tiobe is a piece of shit when it comes to accuracy, so crowing about your "top 20" Tiobe number brings out the hate for lame marketing. Accuracy (i.e. figuring the "right" ranking) is probably indeed low, but Tiobe's methods are a reasonable proxy for a language's presence. I see the increase of D's Tiobe rank not as a surprise or some random artifact, but a reflection of the strong progress in the past months. Andrei
Re: D in the TIOBE top
On 9/12/11 7:28 AM, Timon Gehr wrote: This eager D version uncovered a DMD bug: import std.stdio, std.algorithm, std.range; T[][] powerset(T)(T[] xs){ T[][] r=new T[][](1< goto bugzilla; Andrei
Re: D in the TIOBE top
On 09/11/2011 10:28 PM, Caligo wrote: I don't understand why some would down vote such a news. a lot of haters out there I suppose. Probably because Tiobe is a piece of shit when it comes to accuracy, so crowing about your "top 20" Tiobe number brings out the hate for lame marketing.
Re: cleaning up dsource
well that's too bad an improved dsource would be a great step forward. D is already little-known (relative) having a site advertising a lot of dead projects and with a dead forum isn't going to help a lot :)
Re: D in the TIOBE top
On 09/12/2011 01:36 PM, bearophile wrote: It seems people (Andrei too) are slowly adding more comments in that Reddit thread. A sub-thread: http://www.reddit.com/r/programming/comments/kaxjq/the_d_programming_language_is_back_in_tiobes_top/c2iycwb It starts with this question: How would you write this kind of Python in D? from struct import Struct def decode(buf): while buf: s = Struct(buf[0]) val, = s.unpack(buf[1 : 1 + s.size]) yield val buf = buf[1 + s.size:] Or this: def powerset(items): if not items: yield [] return item, rest = items[0], items[1:] for opt in [[item], []]: for r in powerset(rest): yield opt + r btw, I like Haskell even more, and in it, the latter example is: powerset [] = return [] powerset (x:xs) = do o<- [[x], []] r<- powerset xs return $ o ++ r Or, you can re-use the filterM function, and get: powerset = filterM (\x -> [True,False]) Equivalent D version. Runs in ca 22 min on my machine (for computing the size of P(Z_21)) LList!(List!T) powerset(T)(Lazy!(List!T) xs){ return lz({ if(xs().empty) return list(Empty!T)(); auto r=lz({return powerset(xs().tail)();}); return chain(r,map((LList!T a){return cons(xs().head,a);},r))(); }); } writeln(powerset(take(21,naturals(0))).length); 2097152 real21m58.438s user21m32.320s sys 0m4.710s
Clean-up of std.socket
Hi, I've spent some time polishing up std.socket a bit. I've tried to preserve compatibility as much as possible. The branch is here: https://github.com/CyberShadow/phobos/tree/new-std-socket A list of commits is here: https://github.com/CyberShadow/phobos/compare/master...new-std-socket Docs are here: http://thecybershadow.net/d/new-std-socket/std_socket.html The most important changes are: * Incorporate Chris Miller's std.socket updates and license change, which were posted on Bugzilla as issue 5401 in January. * Add bounds checking to SocketSet. Previously, adding sockets outside the SocketSet's capacity was an unsafe operation which could corrupt memory. * SocketSet now supports variable fd_set sizes on Windows. * Re-entrant IPv4 name resolution for supported POSIX platforms. This will potentially speed up existing multi-threaded network code. * IPv6 address support, with wrapper functions which use IPv4-only functions when the IPv6 functions are unavailable (Windows versions before XP). * Fixes for issues 5177 and 3484. * Improved documentation, added examples. * Some minor added functionality, such as retrieval of more detailed error information, Unix Domain sockets, setting TCP keep-alive options. I'd appreciate if someone with an existing body of D2 code using std.socket could try my version, and let me know of any code breakage. I've heard a lot of criticism about std.socket before. If I haven't fixed your gripe, feel free to let me know. Some concerns: * std.socket enumerations do not conform to D's naming conventions. Fixing this is complicated, due to (IIUC) enum aliases breaking code which enumerate enum members, and the inability to deprecate individual enum members. * Exceptions retrieve a text description of numerical error codes when they are created. If it's possible, it would be best to make that happen when a text description is requested (msg field or .toString), though I don't think msg being a field allows this. * InternetAddress (and by convention, Internet6Address) has a constructor which accepts a hostname. The constructor resolves the hostname and picks the first address entry. I understand that conflating DNS resolution with other functionality may be undesirable, so perhaps such functionality should be deprecated. * Currently, reverse hostname lookup functions throw on failure. Such lookups are not reliable and are expected to sometimes fail, so perhaps a more appropriate behavior would be to return the requested IP address unchanged, or a value indicating failure (null or false). * As far as I can tell, the UnknownAddress class is useless. The generic sockaddr structure it encapsulates is not large enough to abstract and hold newer socket address structures. * David Nadlinger added functionality to work around an apparent oddity of the Windows socket implementation (see WINSOCK_TIMEOUT_SKEW). Although the hack is documented, I'm a bit uncomfortable with that there are no provided details or instructions on how to reproduce the experiments and measurements which led to the inclusion of this hack. (There's also the question whether a language library's purpose includes working around apparent bugs in platforms' implementations.) * Some new functions (notably getAddress) could have probably been named better. "getAddress", which returns an array of Address class instances, is the logical extension of getAddressInfo (which returns the addresses with accompanying information), which in turn is named after the POSIX getaddrinfo function. * InternetAddress has constructors and getters which use uint32_t as the native type for an IPv4 address. Should Internet6Address use ubyte[16]? Currently it uses the in6_addr structure, which is also used in POSIX network structures. -- Best regards, Vladimirmailto:vladi...@thecybershadow.net
Re: D in the TIOBE top
On 09/12/2011 01:36 PM, bearophile wrote: A more complex version that does't yield distinct sub-arrays to allocate less memory: import std.stdio, std.array, std.range; struct PowerSet(T) { T[] items; int opApply(int delegate(ref T[]) dg) { int result; T[] res; T[30] buf; if (!items.length) { result = dg(res); } else { outer: foreach (opt; [items[0..1], []]) { buf[0 .. opt.length] = opt[]; foreach (r; PowerSet(items[1..$])) { buf[opt.length .. opt.length + r.length] = r[]; res = buf[0 .. (opt.length + r.length)]; result = dg(res); if (result) break outer; } } } return result; } } void main() { size_t count; foreach (x; PowerSet!int(array(iota(22 count++; writeln(count); } This runs in about 4.5 seconds, and uses less than 10 MB RAM. You lose vs haskell because haskell does not recompute the same PowerSet multiple times.
Re: D in the TIOBE top
On 09/12/2011 01:36 PM, bearophile wrote: It seems people (Andrei too) are slowly adding more comments in that Reddit thread. A sub-thread: http://www.reddit.com/r/programming/comments/kaxjq/the_d_programming_language_is_back_in_tiobes_top/c2iycwb It starts with this question: How would you write this kind of Python in D? from struct import Struct def decode(buf): while buf: s = Struct(buf[0]) val, = s.unpack(buf[1 : 1 + s.size]) yield val buf = buf[1 + s.size:] Or this: def powerset(items): if not items: yield [] return item, rest = items[0], items[1:] for opt in [[item], []]: for r in powerset(rest): yield opt + r btw, I like Haskell even more, and in it, the latter example is: powerset [] = return [] powerset (x:xs) = do o<- [[x], []] r<- powerset xs return $ o ++ r Or, you can re-use the filterM function, and get: powerset = filterM (\x -> [True,False]) This is the lazy Haskell program, it's not so basic as it looks: powerset [] = return [] powerset (x:xs) = do o<- [[x], []] r<- powerset xs return $ o ++ r main = print $ powerset [1, 2, 3] It outputs: [[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],[]] The second Haskell version of the same program: import Control.Monad (filterM) powerset = filterM (\x -> [True,False]) main = print $ powerset [1, 2, 3] An eager D version, with arrays: import std.stdio: writeln; auto powerSet(T)(T[] items) { auto r = new T[][](1, 0); foreach (e; items) { T[][] rs; foreach (x; r) rs ~= x ~ [e]; r ~= rs; } return r; } void main() { writeln(powerSet([1, 2, 3])); } That outputs: [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]] The lazyness has some advantages. If I call the D version with: writeln(powerSet(array(iota(22))).length); And the Haskell version with: main = print $ length $ powerset [0..21] The D code (GHC -O3) takes 9.7 seconds and 430 MB RAM The Haskell code takes about 1.8 seconds and less than 200 MB of RAM. The second Haskell version (with filterM) takes about 2.4 seconds and about 240 MB RAM. A lazy D version: import std.stdio, std.array, std.range; struct PowerSet(T) { T[] items; int opApply(int delegate(ref T[]) dg) { int result; T[] res; if (!items.length) { result = dg(res); } else { outer: foreach (opt; [items[0..1], []]) foreach (r; PowerSet(items[1..$])) { res = opt ~ r; result = dg(res); if (result) break outer; } } return result; } } void main() { // can't use this because the silly walkLength() // doesn't recognize opApply yet: // http://d.puremagic.com/issues/show_bug.cgi?id=5691 //writeln(walkLength(PowerSet!int(array(iota(22); size_t count; foreach (x; PowerSet!int(array(iota(22 count++; writeln(count); } The lazy D version runs in about 22 seconds, using less than 10 MB. DMD performs no advanced lazy optimizations here. A more complex version that does't yield distinct sub-arrays to allocate less memory: import std.stdio, std.array, std.range; struct PowerSet(T) { T[] items; int opApply(int delegate(ref T[]) dg) { int result; T[] res; T[30] buf; if (!items.length) { result = dg(res); } else { outer: foreach (opt; [items[0..1], []]) { buf[0 .. opt.length] = opt[]; foreach (r; PowerSet(items[1..$])) { buf[opt.length .. opt.length + r.length] = r[]; res = buf[0 .. (opt.length + r.length)]; result = dg(res); if (result) break outer; } } } return result; } } void main() { size_t count; foreach (x; PowerSet!int(array(iota(22 count++; writeln(count); } This runs in about 4.5 seconds, and uses less than 10 MB RAM. With the syntax sugar I have suggested here: http://d.puremagic.com/issues/show_bug.cgi?id=5660 the recursive lazy D version becomes something like this, that is not too much bad looking (untested): yield(T[]) powerSet(T)(T[] items) { if (!items.length) yield []; else foreach (opt; [items[0..1], []]) foreach (r; powerSet(items[1..$])) yield opt ~ r; } Bye, bearophile This eager D version uncovered a DMD bug: import std.stdio, std.algorithm, std.range; T[][] powerset(T)(T[] xs){ T[][] r=new T[][](1
Re: Pull 375 and related enhancements
Don: > As I said in my other post, we could deal with this using a CTFE library > solution. Currently this works: ubyte[10] a = [1, 2]; void main() {} But if you write this, I think padArrayLiteral returns an int[], so D refuses the implicit cast: ubyte[10] a = padArrayLiteral(256, [1, 2]); void main() {} So I think you have to write something like: ubyte[10] a = padArrayLiteral!ubyte(256, [1, 2]); void main() {} Bye, bearophile
Re: Allocators/region allocator proposal overhaul
V Sun, 11 Sep 2011 19:25:41 +, dsimcha wrote: > Is there any easy way to getDDoc to document that a mixin template has > been mixed into a class/struct? I.e.: > > struct Foo { > /// Document that this is mixed in. > mixin SomeMixin; > } Currently none. http://d.puremagic.com/issues/show_bug.cgi?id=648
C++ interoperability
Am 12.09.2011, 09:07 Uhr, schrieb Don : On 11.09.2011 17:07, Daniel Murphy wrote: Adding the C++ interfacing capability was well before my time, so I'm not sure how it ended up with the current limitations. Maybe someone else does? I think the issue with static member functions is getting the name mangling/linking to work, this is obviously never a problem for virtual functions, and is simpler for free functions. I'll have a go at this eventually if nobody beats me to it. There's a patch in bugzilla which implements it. Walter used a couple of things from the patch, but left out the rest. Don't know what the reasoning was. Do you mean this one? http://d.puremagic.com/issues/show_bug.cgi?id=4620 I really don't understand why we have to deal with crappy C++ -> C -> D layers if it's that easy to add more C++ interoperability.
Re: D in the TIOBE top
It seems people (Andrei too) are slowly adding more comments in that Reddit thread. A sub-thread: http://www.reddit.com/r/programming/comments/kaxjq/the_d_programming_language_is_back_in_tiobes_top/c2iycwb It starts with this question: > How would you write this kind of Python in D? > > from struct import Struct > def decode(buf): > while buf: > s = Struct(buf[0]) > val, = s.unpack(buf[1 : 1 + s.size]) > yield val > buf = buf[1 + s.size:] > > Or this: > > def powerset(items): > if not items: > yield [] > return > item, rest = items[0], items[1:] > for opt in [[item], []]: > for r in powerset(rest): > yield opt + r > > btw, I like Haskell even more, and in it, the latter example is: > > powerset [] = return [] > powerset (x:xs) = do > o <- [[x], []] > r <- powerset xs > return $ o ++ r > > Or, you can re-use the filterM function, and get: > > powerset = filterM (\x -> [True,False]) This is the lazy Haskell program, it's not so basic as it looks: powerset [] = return [] powerset (x:xs) = do o <- [[x], []] r <- powerset xs return $ o ++ r main = print $ powerset [1, 2, 3] It outputs: [[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],[]] The second Haskell version of the same program: import Control.Monad (filterM) powerset = filterM (\x -> [True,False]) main = print $ powerset [1, 2, 3] An eager D version, with arrays: import std.stdio: writeln; auto powerSet(T)(T[] items) { auto r = new T[][](1, 0); foreach (e; items) { T[][] rs; foreach (x; r) rs ~= x ~ [e]; r ~= rs; } return r; } void main() { writeln(powerSet([1, 2, 3])); } That outputs: [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]] The lazyness has some advantages. If I call the D version with: writeln(powerSet(array(iota(22))).length); And the Haskell version with: main = print $ length $ powerset [0..21] The D code (GHC -O3) takes 9.7 seconds and 430 MB RAM The Haskell code takes about 1.8 seconds and less than 200 MB of RAM. The second Haskell version (with filterM) takes about 2.4 seconds and about 240 MB RAM. A lazy D version: import std.stdio, std.array, std.range; struct PowerSet(T) { T[] items; int opApply(int delegate(ref T[]) dg) { int result; T[] res; if (!items.length) { result = dg(res); } else { outer: foreach (opt; [items[0..1], []]) foreach (r; PowerSet(items[1..$])) { res = opt ~ r; result = dg(res); if (result) break outer; } } return result; } } void main() { // can't use this because the silly walkLength() // doesn't recognize opApply yet: // http://d.puremagic.com/issues/show_bug.cgi?id=5691 //writeln(walkLength(PowerSet!int(array(iota(22); size_t count; foreach (x; PowerSet!int(array(iota(22 count++; writeln(count); } The lazy D version runs in about 22 seconds, using less than 10 MB. DMD performs no advanced lazy optimizations here. A more complex version that does't yield distinct sub-arrays to allocate less memory: import std.stdio, std.array, std.range; struct PowerSet(T) { T[] items; int opApply(int delegate(ref T[]) dg) { int result; T[] res; T[30] buf; if (!items.length) { result = dg(res); } else { outer: foreach (opt; [items[0..1], []]) { buf[0 .. opt.length] = opt[]; foreach (r; PowerSet(items[1..$])) { buf[opt.length .. opt.length + r.length] = r[]; res = buf[0 .. (opt.length + r.length)]; result = dg(res); if (result) break outer; } } } return result; } } void main() { size_t count; foreach (x; PowerSet!int(array(iota(22 count++; writeln(count); } This runs in about 4.5 seconds, and uses less than 10 MB RAM. With the syntax sugar I have suggested here: http://d.puremagic.com/issues/show_bug.cgi?id=5660 the recursive lazy D version becomes something like this, that is not too much bad looking (untested): yield(T[]) powerSet(T)(T[] items) { if (!items.length) yield []; else foreach (opt; [items[0..1], []]) foreach (r; powerSet(items[1..$])) yield opt ~ r; } Bye, bearophile
Re: clear()
On Mon, 12 Sep 2011 07:12:19 -0400, Michel Fortin wrote: On 2011-09-11 10:23:21 +, "Marco Leise" said: Enough sarcasm. If I recall, Andrei liked the name 'clear' and was unsympathetic to the arguments that it'd be confusing. 'clear' is explained in TDPL and Andrei doesn't like to break his book, so we might be stuck with that mess for while. But I think it's clear by now that that 'clear' is confusing and dangerous: it will work with certain types and completely blow up with others depending on implementation details of the type (calling the destructor twice, it's insane!). And the name just make it sounds like it's something pretty normal to do, which is probably the worse part of it. Actually no, the worse part is probably that it's inside module 'object', the only module imported by default everywhere, so you can't even escape the confusion by not importing its module. :-( While I share your sentiment that clear is too useful a term to be relegated to only be "call the destructor" (in fact, I use clear as a member function in my dcollections library, which probably adds to the confusion), I still think that the function should work. What types does it "blow up" on? What types does it call the destructor twice? I'd like to fix these. -Steve
Re: Auto tools and D
Steve, On Sun, 2011-09-11 at 18:28 +, Steve Teale wrote: > I was able to get some distance down the road with: > > env = Environment() > > def CheckPKGConfig(context, version): > context.Message( 'Checking for pkg-config... ' ) > ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % > version)[0] > context.Result( ret ) > return ret > > def CheckPKG(context, name): > context.Message( 'Checking for %s... ' % name ) > ret = context.TryAction('pkg-config --exists \'%s\'' % name)[0] > context.Result( ret ) > return ret The support for pkg-config in SCons needs improving, you shouldn't have to define these sorts of function yourself. I have variants on the above, but the itch to actually create something in SCons never got bad enough to have to scratch. If there were others definitely using pkg-config with SCons, we should club together and create something that people could use and which could be lined up for inclusion in SCons. > # Configuration: > > conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig, >'CheckPKG' : CheckPKG }) > > if not conf.CheckPKGConfig('0.15.0'): > print 'pkg-config >= 0.15.0 not found.' > Exit(1) > > if not conf.CheckPKG('gtk+-2.0 >= 2.24.4'): > print 'gtk+-2.0 >= 2.24.4 not found.' > Exit(1) > > if not conf.CheckPKG('glib-2.0 >= 2.28.6'): > print 'glib-2.0 >= 2.28.6 not found.' > Exit(1) > > if not conf.CheckPKG('cairo >= 1.10.2'): > print 'cairo >= 1.10.2 not found.' > Exit(1) > > if not conf.CheckPKG('pango >= 1.28.4'): > print 'pango >= 1.28.4 not found.' > Exit(1) I tend to avoid these repetitious tests by doing: for dependency in ( 'gtk+-2.0 >= 2.24.4', 'glib-2.0 >= 2.28.6', 'cairo >= 1.10.2', 'pango >= 1.28.4', ): if not conf.CheckPKG(dependency): print dependency + ' not found.' Exit(1) > # Your extra checks here > > env = conf.Finish() > > > Program('compo', Glob('*.d'), LIBS = [ 'gtkd', 'phobos2', 'dl', 'rt' ], > LIBPATH = [ '/usr/lib32' ], DPATH = > ['/usr/local/include/d']) > > This at least allows me to check for the versions of GTK+ components that I > built > against. > > But I don't know how to check for the versions of DMD and gtkD. > > Does your stuff get me anywhere in that direction Russel? The DMD tool handles all the Phobos and known transitive dependencies so by including it you can get rid of the LIBPATH and DPATH stuff and also the LIBS, except the gtkd. I wonder if it might be worth having a gtkd tool? -- 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: clear()
On 2011-09-11 10:23:21 +, "Marco Leise" said: Is there a reason why the method that calls the destructor hasn't been called 'deinit', 'destruct', 'invalidate' or 'destroy' instead? Probably to confuse people. And are these bug reports in fact invalid as per specification of clear() ? http://www.digitalmars.com/d/archives/digitalmars/D/bugs/Issue_5816_New_clear_breaks_associative_array_29122.html http://www.digitalmars.com/d/archives/digitalmars/D/bugs/Issue_5683_New_Calling_.clear_on_a_fresh_associative_array_causes_subsequent_segfault_28632.html Seems like they are indeed invalid. Clear is working as intended, and is confusing people. I'm confused :p See, it works! Enough sarcasm. If I recall, Andrei liked the name 'clear' and was unsympathetic to the arguments that it'd be confusing. 'clear' is explained in TDPL and Andrei doesn't like to break his book, so we might be stuck with that mess for while. But I think it's clear by now that that 'clear' is confusing and dangerous: it will work with certain types and completely blow up with others depending on implementation details of the type (calling the destructor twice, it's insane!). And the name just make it sounds like it's something pretty normal to do, which is probably the worse part of it. Actually no, the worse part is probably that it's inside module 'object', the only module imported by default everywhere, so you can't even escape the confusion by not importing its module. :-( -- Michel Fortin michel.for...@michelf.com http://michelf.com/
Re: Pull 375 and related enhancements
On 12.09.2011 12:47, Walter Bright wrote: On 9/11/2011 2:31 AM, Don wrote: Do you have an example? One is initializing the ctype array - the first 128 are initialized, followed by 128 zeros. As I said in my other post, we could deal with this using a CTFE library solution. It hardly seems common enough to justify the special-case syntax sugar in the language, especially when it masks a common bug.
Re: Pull 375 and related enhancements
On 9/11/2011 2:31 AM, Don wrote: Do you have an example? One is initializing the ctype array - the first 128 are initialized, followed by 128 zeros.
Re: Allocators/region allocator proposal overhaul
dsimcha , dans le message (digitalmars.D:144293), a écrit : > If you mean just making functions like T newArray(Allocator)(Allocator > allocator, > size_t size), etc., I've mentioned before that having the type available to > the > allocator is often useful and therefore these defaults need to be > overrideable. > Otherwise, please clarify. Maybe something like: auto newArray(T, Allocator)(Allocator allocator, size_t size) if (is(typeof(allocator.newArray!T(size))==T[]) { return allocator.newArray!T(size); }
Re: Pull 375 and related enhancements
Don: > Thanks! We could do this with CTFE, for example: > > immutable ubyte _ctype[256] = padArrayLiteral(256, > [ >_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL, > ... >_LC,_LC,_LC,_PNC,_PNC,_PNC,_PNC,_CTL > ], 0); > > and this would also work with Stewart's example. > I don't think we really need language support, the language already has > enough power to do this kind of thing in a library. The ... syntax seems even less needed, if you add that to Phobos. But the $ syntax is useful still. Bye, bearophile
Re: Looking forward to the resurrection ddmd
On 2011-09-12 03:35, Daniel Murphy wrote: "Jacob Carlborg" wrote in message news:j4j4al$il3$1...@digitalmars.com... Virtual functions needs to be mangled as well. The only thing that, at least I know about, differs from a free function and a static member function is the mangling. -- /Jacob Carlborg Virtual functions never need to get linked. The compiler just needs to match up the argument types, calling convention and vtable slot, and because only C++ interfaces are supported in D, the rest just works. There's no need to have virtual functions mangled the same way as in C++ because they're always abstract in D. Ok, I see. -- /Jacob Carlborg
Re: D in the TIOBE top
bearophile Wrote: > I think most managers only see the top 11 of that list I am seeing now (some > managers probably see some language below too, like Delphi, Ada, Scala, etc, > but they are uncommon). DevExpress enterprise-quality visual controls library started as a Delphi project and they still support the delphi version.
Re: Looking forward to the resurrection ddmd
On 11.09.2011 17:07, Daniel Murphy wrote: "Jacob Carlborg" wrote in message news:j4i33b$1bc2$1...@digitalmars.com... I find this strange: D can call C++ free functions and virtual member functions but it cannot call non-virtual or static member functions. Especially not be able to call static member functions are strange. I thought that free functions and static member functions where implemented in the same way. As far as I know they are implemented in the same way in D. -- /Jacob Carlborg Adding the C++ interfacing capability was well before my time, so I'm not sure how it ended up with the current limitations. Maybe someone else does? I think the issue with static member functions is getting the name mangling/linking to work, this is obviously never a problem for virtual functions, and is simpler for free functions. I'll have a go at this eventually if nobody beats me to it. There's a patch in bugzilla which implements it. Walter used a couple of things from the patch, but left out the rest. Don't know what the reasoning was.
Re: Pull 375 and related enhancements
On 11.09.2011 11:43, bearophile wrote: Don: Do you have an example? In bug 3849 there the only example I've found (it's not my code): immutable ubyte _ctype[256] = [ _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL, _CTL,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL|_SPC,_CTL,_CTL, _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL, _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL, _SPC|_BLK,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC, _PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC,_PNC, _DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX, _DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX,_DIG|_HEX, _PNC,_PNC,_PNC,_PNC,_PNC,_PNC, _PNC,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC|_HEX,_UC, _UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC, _UC,_UC,_UC,_UC,_UC,_UC,_UC,_UC, _UC,_UC,_UC,_PNC,_PNC,_PNC,_PNC,_PNC, _PNC,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC|_HEX,_LC, _LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC, _LC,_LC,_LC,_LC,_LC,_LC,_LC,_LC, _LC,_LC,_LC,_PNC,_PNC,_PNC,_PNC,_CTL, ... ]; (ellipses added by me). But I have never had to do something like that in my code, so far. Thanks! We could do this with CTFE, for example: immutable ubyte _ctype[256] = padArrayLiteral(256, [ _CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL,_CTL, ... _LC,_LC,_LC,_PNC,_PNC,_PNC,_PNC,_CTL ], 0); and this would also work with Stewart's example. I don't think we really need language support, the language already has enough power to do this kind of thing in a library. Stewart Gordon has recently written more comments about this topic (is Bugzilla down?): http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D.bugs&article_id=32924 Bye, bearophile