digitalmars.D - Various D language matters
- Dan Williams (269/279) Jun 29 2004 Hi people!
- Norbert Nemec (22/24) Jun 29 2004 Sorry for not going into all the different points of your mail. It reall...
- Walter (54/124) Jun 29 2004 D
- Sean Kelly (7/14) Jun 29 2004 I haven't looked at the code, but it sounds like you were running a word
- Walter (15/32) Jun 29 2004 [3].
- Dan Williams (9/42) Jun 29 2004 Heheh, yes I noticed you didn't write the C++ version ;)
- Dan Williams (13/31) Jun 29 2004 Yes, that's correct, I used the word count programs given on the D site,
- Martin M. Pedersen (6/7) Jun 29 2004 It reminds me - I think it should be documented if the sort is guarantee...
- Walter (4/9) Jun 29 2004 to
- Derek Parnell (22/33) Jun 29 2004 If two items with the same sort key are adjacent in the unsorted array,
- Walter (4/33) Jun 29 2004 guaranteed
- Oskar Linde (3/4) Jun 30 2004 No, quicksort is not stable.
-
Walter
(3/6)
Jun 30 2004
Then .sort is not stable.
- Ben Hinkle (4/16) Jun 29 2004 that is doesn't swap things that compare equal - though personally I thi...
- Jesus (6/13) Jun 30 2004 to
- Dan Williams (5/23) Jun 30 2004 Indeed, this is why I was hoping for a built-in swap method, so that we
- Norbert Nemec (4/6) Jun 30 2004 Where is the problem of using a temporary and doing the three assignment...
- Dan Williams (8/14) Jun 30 2004 Yes, it's mainly due to convenience, but not just syntactical convenienc...
- Walter (13/16) Jun 30 2004 a
- Dan Williams (8/24) Jun 30 2004 so
- Ivan Senji (8/41) Jun 30 2004 pointers
- Dan Williams (52/95) Jun 30 2004 and
- Regan Heath (17/126) Jun 30 2004 No, it is you who are mistaken (I think) :)
- Dan Williams (10/155) Jun 30 2004 Seems like the same thing is now being debated in multiple branches of t...
- Sam McCall (7/47) Jul 01 2004 If they're value types, sure. (The only value types that could be that
- Dan Williams (10/56) Jul 01 2004 pointers
- ardita (1/64) May 12 2009
- Dan Williams (51/136) Jun 29 2004 Thanks for the reply :) Comments below...
- Chr. Grade (3/266) Jun 30 2004 There's someone in this newsgroup who gets paid by the amount of smileys...
- Dan Williams (3/5) Jun 30 2004 I wish :) :D :P ;)
- J C Calvarese (11/31) Jun 29 2004 DTL hasn't been released yet. Matthew Wilson is working on it, but he's
- Derek Parnell (17/48) Jun 29 2004 Hear! Hear! Long live the VARIANT type.
- Derek Parnell (14/29) Jun 29 2004 Content-type: text/plain; charset="us-ascii"
- Dan Williams (4/13) Jun 30 2004 Glad to see that I'm not the only one who would find a variant data type
- Regan Heath (6/22) Jun 30 2004 What exactly is a variant type?
- Derek (13/39) Jun 30 2004 Let's pretend a bit...
-
Dan Williams
(6/42)
Jun 30 2004
- Regan Heath (18/56) Jun 30 2004 Cool.. If everything (even primitives) were derived from Object you coul...
- Walter (25/68) Jun 29 2004 I forgot to add that gc code can also be incrementally smaller, because ...
- Dan Williams (33/69) Jun 30 2004 instead
- Jesus (40/62) Jun 30 2004 then
- Dan Williams (53/120) Jun 30 2004 where
- Norbert Nemec (11/16) Jun 30 2004 What you call "arrays with variable-length elements" should rather be ca...
- Dan Williams (17/33) Jun 30 2004 Hmmmm...
- Regan Heath (6/54) Jun 30 2004 I think I have understood you in my last post.. haven't I?
- Dan Williams (5/68) Jun 30 2004 If
- Derek (39/44) Jun 30 2004 [snip]
- Dan Williams (41/93) Jun 30 2004 it
- Regan Heath (79/134) Jun 30 2004 B) is the method that *does* actually take place, try my example code...
- Dan Williams (44/181) Jun 30 2004 be
- Stephen Waits (4/6) Jun 30 2004 Pay attention.. the data in the case of a string IS A POINTER (and a
- Regan Heath (43/268) Jun 30 2004 I took your code, compiled and verified, got the same results :)
- Dan Williams (91/375) Jul 01 2004 have
-
Carlos Santander B.
(13/13)
Jul 01 2004
"Dan Williams"
escribió en el mensaje - James McComb (8/12) Jul 01 2004 You might have been confused by the fact that in D, we write:
- Dan Williams (7/18) Jul 01 2004 new
- Derek Parnell (61/189) Jun 30 2004 You didn't actually try this code out, did you? You are just guessing, I
- Dan Williams (26/214) Jul 01 2004 reason
- Derek (44/60) Jul 01 2004 G'day, mate. Great news! I too was a bit confused by D's assignment
- Dan Williams (28/84) Jul 01 2004 and
- Regan Heath (57/97) Jun 30 2004 char[][100] list;
- Sam McCall (7/10) Jun 30 2004 Really?
- Regan Heath (15/27) Jun 30 2004 I believe so. My test program uses it.
- Sam McCall (15/32) Jun 30 2004 No they're not.
- Regan Heath (20/60) Jun 30 2004 Yep.
- Sam McCall (4/69) Jul 01 2004 Yes, yes, I get all that, but the _indices_ are _backwards_.
- Dan Williams (5/74) Jul 01 2004 I'm with Sam on this one... it appears confusing to reverse the order. I
- Regan Heath (5/73) Jul 01 2004 See "Norbert Nemec"'s post. he explains it well.
- Norbert Nemec (28/39) Jul 01 2004 Careful: in nested arrays, the type declaration looks the other way arou...
- Dan Williams (35/128) Jun 30 2004 you
- Regan Heath (57/241) Jun 30 2004 I get that feeling sometimes too.. sometimes I wonder if they do it on
- Dan Williams (16/49) Jul 01 2004 :D so it's not just me then!
- Regan Heath (15/85) Jul 01 2004 If there were a way to query a thing for all its members and if every
- Roberto Mariottini (11/15) Jun 30 2004 I think now it's time for a few commercial questions:
- Walter (5/21) Jun 30 2004 You can download it now! That's what dmd.zip is.
- Roberto Mariottini (12/25) Jun 30 2004 I think you missed the point, that is in the next question:
- Walter (7/10) Jun 30 2004 project if
- Lynn Allan (8/11) Jul 01 2004 Shared libraries could be very advantageous to minimize download size fo...
- Dan Williams (17/21) Jun 30 2004 with
- Walter (11/26) Jun 30 2004 No, not unless the programs are running simultaneously. And even so, how
- Dan Williams (11/24) Jun 30 2004 an
- Lynn Allan (4/8) Jun 30 2004 pda development (Palm and Pocket-PC) still have important resource
- Stephen Waits (18/28) Jun 30 2004 D is a great language, I'm a huge fan, and have been since its earliest
- Walter (10/24) Jul 01 2004 I think you can get much closer in D than you can in C++, because in D y...
- Norbert Nemec (12/21) Jul 01 2004 Careful: the multiple index opIndex may help you in writing *comfortable...
- me (20/21) Jun 30 2004 If you're truely after cross platform, the D is probably not at a stage ...
Hi people! I have just started using D after finding it two weeks ago, and I emailed Walter today. He has encouraged me to post my email here, and so I will do (slightly altered) - plus I will add to it some things that have come up after my spending the day reading the D newsgroups (I went back as far as January - whew! a lot of stuff there!) Let me briefly introduce myself. I'm a programmer, I have roughly a decade of programming experience, and I've used about a dozen languages and have working knowledge of maybe another dozen (I really can't be bothered to try and count!). Most of that experience is in 'C-like' languages - I have, from time to time, played with things like Forth and Smalltalk, but I don't really like them too much. Anyway, I'm also a web developer and designer (I guess I'm one of those apparently few people who have a gift for both coding and design) and in the past couple of years I have been mainly writing in web languages such as PHP. Because of this, my skills in C/C++ have gotten slightly rusty, but that's partly because I've always hated some aspects of C, and so having the opportunity to write primarily in other languages such as PHP, Perl, Python, Ruby etc. has been quite welcome, because I can concentrate more on doing the task and less on making sure that every single little thing is handled correctly (not to mention the other benefits of such languages!). So, why did I bother to introduce myself? Well, I want you to realise I am not a newbie at programming. From some of the things I have read about D, it appears that the 'anti-D' camp often try to use the argument that 'they know more about C and so what's the point of D' - that kind of thing. I notice that a lot of D supporters are actually very highly skilled and experienced, in many different languages, and undoubtably far above my own level. But I just wanted to point out that I enter this as someone who already knows enough about C to make a proper decision about D. Ok, I hope you got what I was on about there :) I have a couple of projects on at the moment that are going to require the use of a more 'C-style' language. One specific, critical requirement is performance. Indeed, that aspect alone is enough to force me to use C (or C++ - I tend to write 'C' to cover both) if I have to, but I am loath to do so if there is a more suitable alternative. Another requirement is that the language must be compilable, and another is that it must be pretty much cross-platform. Finally, the language features. Because I have already ruled out so many nice languages with the requirements I have already stated, I'm left begging for whatever features I can, really. Things like dynamic typing are nice, but to be honest I generally prefer static typing. String and array handling is very important - the nearer the language is to PHP, Ruby etc. in this respect, the better. So:cross-platform, and the language itself is near perfect for what I need - except it isn't strict enough.PHP: nowhere near fast enough; not compilable. However, it iscompilable, there are some wrappers. The language is again near-perfect, I love the way everything is OO, but the speed and fiddly wrapping means it doesn't qualify.Ruby: getting better - a lot faster than PHP, and although not strictlyit's very slow. There are wrappers, but all things compared, Ruby would be a better choice.Python: not even worth considering. I don't really like the language, andnot compilable.Perl: faster than PHP, but worse language-wise; for me, at least. Again,I *don't* want to have to spend ages creating custom data types and classes for things that I could use natively in other languages. I dislike the STL; quite often I personally find the implementation of certain features still has to be tweaked a lot to fit what I want to do, and so I often end up writing from scratch something that I could arguably use the STL for, but I end up with something smaller and not as hacked together as it would be if I altered an existing module. I hate the way strings and arrays are dealt with in C/C++, I hate the way C++ deals with objects... gah! so many things about C that I hate, no wonder I haven't used it much in the last couple of years :)C/C++: very fast, obviously compilable, and cross-platform. Perfect? NO!I want. However, it just isn't used enough it seems, because I have had trouble finding what I need on it, plus I really don't like the language.Smalltalk: quite fast, compilable, and the language supports much of whatwhat I need to do, and many are quite fast, but the lack of widespread mainstream use, and hence the lack of enough material, plus my dislike of the languages, rules them out.Forth, Ada, similar friends: similar to my comments on Smalltalk. Some doBasic and Pascal derivatives? ...nothing I know of fits the bill, really.small, fast, does pretty much what I would want. Compilable? Hmmm. Wrappable, more like. There is still the problem of having to write the Lua, interface the Lua with some C, and so on. I would end up with what would essentially be a small C program loading an embedded Lua interpreter, and bootstrapping a Lua program stored as a C string. That pretty much rules out Lua, which is a shame, because if it was properly compilable, it might even win. So much so, that I spent quite a while playing around with it to see if it would in fact be suitable. Ah well.Lua: a very interesting option, this one. Lua is a beautiful language,Java as being the ideal solution for me. C-like, so surely I will like the language. Fast - or so they will say. Compilable - again, so they will say. And it does everything I want to do, doesn't it? Not really. I have a strong dislike of Java. I actually taught it for a while, but no more recently than three years ago, because I decided not to continue using it. I think I would rather use C++ than Java. Sure, Java has got better OO, lots more features... but it is pretty slow (or at least I think so) and isn't really compilable. Not in the way that I want. So Java is also ruled out. There are plenty more languages, but I picked those out for a reason, plus I can't be bothered to waste my time and yours by listing every single language out there. You will probably notice the focus on PHP - that is partly because one of my projects is writing some PHP extensions, and partly because I use it every day, and like it immensely. So that brings me to D. I'm glad I found your site - I had never heard of D before, and to be honest, although I was impressed by the features etc. I was also wondering if this language would live up to the hype you give it. After all, everyone does that with their own stuff - myself included. (I've actually written a language; PTPScript, used in my template engine, PTP. I personally think it's the best thing since sliced bread, but not everyone will agree. So I'm used to own-trumpet-blowing!) After reading things like the discussion at comp.lang.c++ [1], I realised that many of the people who dislike D are simply being picky. I read through the first hundred messages of that discussion, and failed to see anything of use (such as real-world performance tests or in-depth language feature analysis) - instead, far too much time was spent simply arguing about whether you should have used '+' instead of '~' and similar rubbish. I personally don't care - you designed and wrote the language, that's more than they did, surely it's up to you to write it how you want. So long as it's semantically coherent, I can simply learn the syntax, as I have to do with any other language in any case. So I decided to try out D for myself. I figured I'd use the word count program that you have on your site, and do some tests. First, I downloaded D and installed it on both my Windows XP system (worked fine) and my RedHat Linux server (again, worked fine). I was unable to get it to work under Cygwin - shame really. I then altered the C++ and D code slightly so that both produced exactly the same output (you may not have noticed, but the formatting is different, and as I was doing a difference comparison on the produced output in order to check for success, I needed them to match). I also found a small bug in your D code - line 1 and line 18: 'file' should be 'std.file'. I compiled the programs on my Linux system, using the standard method (no extra flags or anything), and then stripped them. I was a bit disappointed that the D executable was 110Kb (75kb after stripping) whereas the C++ program was only 36Kb (21Kb after stripping). I'm not sure why the compiled D program is so much larger than the C one [2], but never mind. That alone is not really a bad thing, as file size is generally not a critical requirement these days. I then grabbed a copy of the alice text, and created 4 test files. The first was simply alice, the second had the same text 10 times, the third, 100, and the fourth, 1000. That gave me file sizes of 163Kb, 1.63Mb, 16.3Mb, and 163Mb. Next, I simply ran the C program and then the D program with each file, outputting to a log file. Times for the C++ program: ~0.5s, 2s, 15s, 155s. Note that these are by no means pin-point accuracy, as I was simply counting the seconds on my watch ;) Times for the D program: ~0.1s, ~0.5s, ~1s, 15s. Wow! Pretty impressive! :) The results clearly show to me that the compiled D program was approximately 10x faster than the compiled C++ program [3]. Now, in fairness, I have not actually gone through all the code in each program to compare the methods, so I guess it's possible that you used a more efficient method. However it mentioned on the site that it was supposed to be a direct translation, plus plenty of people have read that page and discussed it, so I figured that if the method itself was giving an advantage then someone would have kicked up a fuss by now :D The conclusion I have come to, as what I would call an informed outsider, is that D seems to be a lot 'better' than C or C++. I like your features; I don't think all your comparisons between C/C++ and D as quite as fair as maybe they could be, but I can see that you are saying is true. I very much like the fact that D seems to be faster than C, and therefore those things to me constitute an acceptable definition of 'better' :) In case you haven't guessed... the purpose of this email (and post) is primarily to encourage you. I thought it might be useful in some way to hear how D has been selected as the development language of choice for some real-world projects, based on criteria that actually matter, when put side-by-side with pretty much every other language out there. In particular I was wondering if you would like me to take the speed testing thing further, and maybe do some detailed analysis (when I have the time) on different aspects and their realisations. It would certainly be interesting, and may help attract some more attention. I am about to start using D quite extensively, and also I will include it as a supported language on my forums (I provide coding help for people). If you need any assistance with anything then please drop me a line, as I have resources, skills, and contacts, and can probably lend a hand with many things, if need be. Thankyou for developing this language, and for the time you have poured into it. Dan ------------------------------------------------------------ To the newsgroup readers: that's pretty much the email that I sent to Walter. Here are some footnotes: [1] http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&threadm=ww3_a.9531%24BC2.1823%40newsread2.news.atl.earthlink.net&prev=/groups%3Fq%3Dg:thl953709878d%26dq%3D%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3DUTF-8%26selm%3Dbjacrl%25244un%252401%25241%2540news.t-online.com&as_drrb=b&as_maxd=12&as_maxm=8&as_maxy=2003&as_mind=29&as_minm=3&as_miny=1995 [2] From reading the newsgroups, I realise that the extra file size is because the Phobos code has to be compiled into the executable, whereas for the C program, the common code is already installed as libraries. More about that in a minute. [3] Just in case anyone asks - no, the difference in results is nothing to do with file caching or anything similar. I repeated the tests to make sure that this was not affecting it in any way. ------------------------------------------------------------ Ok, and now for some things that I haven't had answered by searching and reading, plus some general comments. First, if any of you can point me to anything relating to the possibility of coding PHP extensions in D, that would be very much appreciated! ;) Now, I notice that there has been a lot of discussion about arrays, mostly about the definition of what I would call multi-dimensional fixed arrays, or something like that, but people seem to like calling them rectangular despite the fact that when you go above two dimensions you get a cuboid and then some strange n-dimensional shape ;) All I can say about that type of array is that I agree with the proposal put forward by Norbert Nemec - has any of that been implemented yet? Is it going to be? I was unable to find that out. Responding to some of the suggestions I have read, I personally would prefer the int[a, b, c] method over the int[a][b][c] method, but I'm really not that fussed, and I would be happy with either one so long as the methodology and syntax was clearly defined with no room for ambiguity. While on the subject on arrays, I have a question. Is it possible to create D arrays with mixed types? i.e. like PHP arrays ;) I notice that I can use non-mumeric keys, which is great, but I have not been able to ascertain whether there is the ability to mix data types in the array elements and also in the keys (maybe in the DTL?). My suspicion is "no", because of the definition method - therefore, my next question is, what would people recommend as the best method to do such a thing? I have such a structure created in some C++ code that I was writing some way back, but I would obviously prefer a solution that is native to the language. Maybe I could suggest a Visual Basic-style data type of variant, or similar? That's just speculating, and I guess someone is gonna shoot that down as 'bad' for so many reasons, but although I like strong typing, I can see advantages to bringing in a variant data type too, so long as the memory management was done properly (shouldn't be too hard?). My final question on arrays is the methodology behind them. I figure the D implementation is probably what I think is the best solution; i.e. that arrays are actually arrays of pointers to variable-length data. Is this correct? In which case, I would like to see things like a built-in swap method, e.g. myArray.swap(index_a, index_b) or whatever syntax you like. I haven't noticed that feature available, but hopefully the benefits will be apparent. When sorting etc. you don't want to be moving the actual array element data around in memory, just the pointers. I haven't seen if there are any built-in sort functions, but it doesn't matter - a swap method is all you need for a lot of things, not just sort. If one is available, please point me to it! Plus, if this is not included and not going to be, I assume that it is still possible to swap the pointers in some way, seeing as we can manipulate pointers directly with D, like in C/C++? Please correct me if any of that is misunderstood. The next thing on my list is the Big Cast Discussion. So many methods were brought up! And the subject kept resurfacing. I'm not gonna say a lot about it, because I don't really care that much, but out of the methods; I like "cast(type) expression" - i.e. the one that has been implemented. I didn't much like "x.cast(type)" because that doesn't adequately deal with x being an expression. The only advantage is when x is simply a variable, and the current method handles both just fine. I don't like "cast(type, expression)" at all, because I don't feel that's as comfortable. It has some semantic advantages, however the cast method is a pretty familiar one, and "cast(int) expression" is just fine. "cast type expression" was a bit shaky I thought. I liked the possibility of specific casting methods such as "int(expression)", however I'm not sure they are really necessary, as I am never convinced of the value of providing too many ways of doing the same thing. Likewise with something like "x.int()" although that might be useful. So my basic summary of cast is that I am fine with the way it is :) The only other thing about casting is I think maybe it should be possible to do something like "int a = b" - is this possible? But then, that could lead to "a = int b" as another method, which I guess is getting close to the "a = int(b)" or "a = cast int b" kind of thing, which I don't like too much. I noticed some talk about the way D programs have Phobos code compiled into them, and the situation seems to be that the equivalent doesn't happen in C, because the libraries are usually already available. Talk was made of turning off the incluusion of the Phobos code, however surely the better option is to simply build some static Phobos libraries, and put these in somewhere like /usr/lib, or even /lib (or wherever appropriate on Windows for dlls) so that they are globally available? Isn't that what GCC and friends do? That would then mean that the common code would not have to be recompiled every time, and neither would it have to be included in every D program. My apologies if this suggestion, which seems so obvious to me, has already been covered! Finally, I was concerned about what I read regarding garbage collection and things like Object.toHash(). I'm simply going to voice my opinion and say that I do not think the GC method should be changed until other areas like Object.toHash() are stable and ready enough to cope with the change. Oh yeah and that whole argument about bits and bools... lol... the way it has been done, is the correct way I feel, even if it admittedly doesn't have everything down pat yet. A bool should indeed be the same as a bit, but you should be able to use the bits/bools exactly the same way that you can use anything else, like passing in and out of functions, for example (I read that apparently you can't use a bit in an inout in the same way as you can an int? Hence this comment). Also, because bits are bits, it seems only natural that an array of 5 bits should return length or size of 5, because the unit of measurement being used is that of a bit. Pretty much everything else uses bytes as the unit of measurement, but that does not, IMHO, mean that bits should use bytes to measure. That's just crazy talk ;) ------------------------------------------------------------ Right, so, sorry about the long post, but it's the result of hanging back and reading quite a bit first. Most of my questions were answered already by reading the online material, and the newsgroup posts. If someone could answer my questions about arrays and stuff, I would be very happy :) Cheers, and happy D-ing DanJava: Many people (probably Java lovers!) would have immediately touted
Jun 29 2004
Sorry for not going into all the different points of your mail. It really was interesting to read. Just the one detail that affects me directly:All I can say about that type of array is that I agree with the proposal put forward by Norbert Nemec - has any of that been implemented yet?The proposal is still high up in the air. The ultimate implementation that the proposal in its current form is aimed for is directly in the language, and it will take some time until it is fit for that. Until then, one might try to do a demonstration as a library, but as of yet, it would probably not be possible to really "implement" the proposal as a library. First, of course, the syntax could not be the same I proposed for the language feature. Then - for the partial indexing/partial slicing: I have a very clear idea how the compiler should handle this, but I still have no idea, how opSlice should be generalized to first handle multiple dimensions, and then handle a mixture of slicing and indexing in one expression. So, in general, there is a long way to go, and I have very little time to spend on this right now. I once hoped that multidimensional arrays could get into D 1.0 already, since they might actually collide with some details of the current specs for onedimensional arrays, but by now, I strongly doubt that this is realistic at all. Ciao, Nobbi
Jun 29 2004
"Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbskjv$2u3i$1 digitaldaemon.com...So that brings me to D. I'm glad I found your site - I had never heard ofDbefore, and to be honest, although I was impressed by the features etc. I was also wondering if this language would live up to the hype you give it.Hype? What hype? <g>After reading things like the discussion at comp.lang.c++ [1], I realised that many of the peoplewhodislike D are simply being picky. I read through the first hundredmessagesof that discussion, and failed to see anything of use (such as real-world performance tests or in-depth language feature analysis) - instead, fartoomuch time was spent simply arguing about whether you should have used '+' instead of '~' and similar rubbish.I suspect people who latch on to something like that are ones who haven't read the spec. There's lots of legitimate things to criticise D on, but ~ isn't one of them.I was a bit disappointed that the D executable was 110Kb (75kb after stripping) whereas the C++ program was only 36Kb (21Kb after stripping).I'mnot sure why the compiled D program is so much larger than the C one [2], but never mind. That alone is not really a bad thing, as file size is generally not a critical requirement these days.The D runtime library includes the garbage collector, which adds a chunk of code not present in a C++ executable. This chunk is a fixed overhead, though, and does not suggest that D compiled code is any larger.Wow! Pretty impressive! :) The results clearly show to me that thecompiledD program was approximately 10x faster than the compiled C++ program [3].The reason for the speedup is D doesn't need to do memory allocation for its strings, whereas C++ does.Now, in fairness, I have not actually gone through all the code in each program to compare the methods, so I guess it's possible that you used a more efficient method. However it mentioned on the site that it wassupposedto be a direct translation, plus plenty of people have read that page and discussed it, so I figured that if the method itself was giving anadvantagethen someone would have kicked up a fuss by now :DThe inefficiency in the C++ comes from, when you boil it down, not supporting garbage collection, so C++'s std.string constantly is allocating and copying strings around. wc is a stellar example of why gc'd programs can run far faster than explicitly managed programs, despite the myth that gc programs are slower.The conclusion I have come to, as what I would call an informed outsider,isthat D seems to be a lot 'better' than C or C++. I like your features; I don't think all your comparisons between C/C++ and D as quite as fair as maybe they could be, but I can see that you are saying is true. I verymuchlike the fact that D seems to be faster than C, and therefore those things to me constitute an acceptable definition of 'better' :)I think that once you get used to D, the comparisons to C++ are actually rather biased towards C++ <g>.In case you haven't guessed... the purpose of this email (and post) is primarily to encourage you.Thanks!I thought it might be useful in some way to hear how D has been selected as the development language of choice for some real-world projects, based on criteria that actually matter, when put side-by-side with pretty much every other language out there. InparticularI was wondering if you would like me to take the speed testing thing further, and maybe do some detailed analysis (when I have the time) on different aspects and their realisations. It would certainly beinteresting,and may help attract some more attention.D does need some testimonials from using it in significant projects.All I can say about that type of array is that I agree with the proposalputforward by Norbert Nemec - has any of that been implemented yet? Is itgoingto be?It's a good candidate for 2.0. But right now, one can emulate such arrays using structs and operator overloading.While on the subject on arrays, I have a question. Is it possible tocreateD arrays with mixed types?No, D is statically typed. But you can use templates to do the equivalent, or you can define a 'variant' type and create an array of those instead (which is what most dynamically typed scripting languages do under the hood anyway).My final question on arrays is the methodology behind them. I figure the D implementation is probably what I think is the best solution; i.e. that arrays are actually arrays of pointers to variable-length data. Is this correct?No. A D array is a pair of two items, the number of elements in the array and a pointer to the array data.In which case, I would like to see things like a built-in swap method, e.g. myArray.swap(index_a, index_b) or whatever syntax you like. I haven't noticed that feature available, but hopefully the benefits will be apparent. When sorting etc. you don't want to be moving the actual array element data around in memory, just the pointers. I haven't seen if there are any built-in sort functions, but it doesn't matter - a swap method is all you need for a lot of things, not just sort. If one is available,pleasepoint me to it! Plus, if this is not included and not going to be, Iassumethat it is still possible to swap the pointers in some way, seeing as wecanmanipulate pointers directly with D, like in C/C++? Please correct me ifanyof that is misunderstood.There is a built-in sort property for arrays, but not swap.I noticed some talk about the way D programs have Phobos code compiledintothem, and the situation seems to be that the equivalent doesn't happen inC,because the libraries are usually already available. Talk was made of turning off the incluusion of the Phobos code, however surely the better option is to simply build some static Phobos libraries, and put these in somewhere like /usr/lib, or even /lib (or wherever appropriate on Windows for dlls) so that they are globally available? Isn't that what GCC and friends do? That would then mean that the common code would not have to be recompiled every time, and neither would it have to be included in every D program. My apologies if this suggestion, which seems so obvious to me,hasalready been covered!What you're talking about are DLLs in Windows and shared libraries under linux. Right now, I prefer things to be statically linked in because that avoids "DLL hell" where versions get mismatched.
Jun 29 2004
In article <cbsq23$46i$1 digitaldaemon.com>, Walter says..."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbskjv$2u3i$1 digitaldaemon.com...I haven't looked at the code, but it sounds like you were running a word counter? If so, pick a sample set containing words no longer than 16 characters. The Small String Optimization present in C++ should keep any memory allocations from occurring and thus run much faster. It may be a more useful benchmark vs. D. SeanWow! Pretty impressive! :) The results clearly show to me that thecompiledD program was approximately 10x faster than the compiled C++ program [3].The reason for the speedup is D doesn't need to do memory allocation for its strings, whereas C++ does.
Jun 29 2004
"Sean Kelly" <sean f4.ca> wrote in message news:cbsquv$5ca$1 digitaldaemon.com...In article <cbsq23$46i$1 digitaldaemon.com>, Walter says...[3]."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbskjv$2u3i$1 digitaldaemon.com...Wow! Pretty impressive! :) The results clearly show to me that thecompiledD program was approximately 10x faster than the compiled C++ programitsThe reason for the speedup is D doesn't need to do memory allocation formemorystrings, whereas C++ does.I haven't looked at the code, but it sounds like you were running a word counter? If so, pick a sample set containing words no longer than 16 characters. The Small String Optimization present in C++ should keep anyallocations from occurring and thus run much faster. It may be a moreusefulbenchmark vs. D.The sample set is the full text of "Alice in Wonderland", in which most words are far less than 16 characters. But even with SSO, C++ std::string *still* needs to copy the strings. I didn't tune the input data, nor did I tune the C++ code to look bad. In fact, I didn't even write the C++ version because I'm sure I'd have been accused of sabotaging C++ if I had <g>. The C++ version was written by some C++ folks who were (I believe) trying to show that std::string was better than D strings. The C++ version has some bugs in it (lack of error handling) that I didn't bother to point out to its author(s).
Jun 29 2004
Heheh, yes I noticed you didn't write the C++ version ;) In fact, that was one of the motivating factors for my using it in the test :D "Walter" <newshound digitalmars.com> wrote in message news:cbss5n$70s$1 digitaldaemon.com..."Sean Kelly" <sean f4.ca> wrote in message news:cbsquv$5ca$1 digitaldaemon.com...forIn article <cbsq23$46i$1 digitaldaemon.com>, Walter says...[3]."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbskjv$2u3i$1 digitaldaemon.com...Wow! Pretty impressive! :) The results clearly show to me that thecompiledD program was approximately 10x faster than the compiled C++ programThe reason for the speedup is D doesn't need to do memory allocationitsanystrings, whereas C++ does.I haven't looked at the code, but it sounds like you were running a word counter? If so, pick a sample set containing words no longer than 16 characters. The Small String Optimization present in C++ should keepmemorysomeallocations from occurring and thus run much faster. It may be a moreusefulbenchmark vs. D.The sample set is the full text of "Alice in Wonderland", in which most words are far less than 16 characters. But even with SSO, C++ std::string *still* needs to copy the strings. I didn't tune the input data, nor did I tune the C++ code to look bad. In fact, I didn't even write the C++ version because I'm sure I'd have been accused of sabotaging C++ if I had <g>. The C++ version was written byC++ folks who were (I believe) trying to show that std::string was better than D strings. The C++ version has some bugs in it (lack of errorhandling)that I didn't bother to point out to its author(s).
Jun 29 2004
Yes, that's correct, I used the word count programs given on the D site, with only very minor modifications. As for the word length... I believe the "alice" text is a good test, because most words will be under 10 characters in length, and I very much doubt that any will be over 16 characters. So... perhaps if I try the test again with long (say, > 20 chars) words, there may be an even greater performance distinction... "Sean Kelly" <sean f4.ca> wrote in message news:cbsquv$5ca$1 digitaldaemon.com...In article <cbsq23$46i$1 digitaldaemon.com>, Walter says...[3]."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbskjv$2u3i$1 digitaldaemon.com...Wow! Pretty impressive! :) The results clearly show to me that thecompiledD program was approximately 10x faster than the compiled C++ programitsThe reason for the speedup is D doesn't need to do memory allocation formemorystrings, whereas C++ does.I haven't looked at the code, but it sounds like you were running a word counter? If so, pick a sample set containing words no longer than 16 characters. The Small String Optimization present in C++ should keep anyallocations from occurring and thus run much faster. It may be a moreusefulbenchmark vs. D. Sean
Jun 29 2004
"Walter" <newshound digitalmars.com> skrev i en meddelelse news:cbsq23$46i$1 digitaldaemon.com...There is a built-in sort property for arrays, but not swap.It reminds me - I think it should be documented if the sort is guaranteed to be stable or not. Regards, Martin
Jun 29 2004
"Martin M. Pedersen" <martin moeller-pedersen.dk> wrote in message news:cbsu2o$9r4$1 digitaldaemon.com..."Walter" <newshound digitalmars.com> skrev i en meddelelse news:cbsq23$46i$1 digitaldaemon.com...toThere is a built-in sort property for arrays, but not swap.It reminds me - I think it should be documented if the sort is guaranteedbe stable or not.What does 'stable' mean applied to sorts?
Jun 29 2004
On Tue, 29 Jun 2004 18:20:29 -0700, Walter wrote:"Martin M. Pedersen" <martin moeller-pedersen.dk> wrote in message news:cbsu2o$9r4$1 digitaldaemon.com...If two items with the same sort key are adjacent in the unsorted array, they will appear in the exact same sequence in the sorted array. eg. Unsorted... E:Eggplant B:Banana C:Carrot C:Cabbage O:Orange A:Apple Sorted: (Key is first character). A:Apple B:Banana C:Carrot C:Cabbage E:Eggplant O:Orange -- Derek Melbourne, Australia 30/Jun/04 11:54:55 AM"Walter" <newshound digitalmars.com> skrev i en meddelelse news:cbsq23$46i$1 digitaldaemon.com...toThere is a built-in sort property for arrays, but not swap.It reminds me - I think it should be documented if the sort is guaranteedbe stable or not.What does 'stable' mean applied to sorts?
Jun 29 2004
"Derek Parnell" <derek psych.ward> wrote in message news:cbt6u2$m41$1 digitaldaemon.com...On Tue, 29 Jun 2004 18:20:29 -0700, Walter wrote:guaranteed"Martin M. Pedersen" <martin moeller-pedersen.dk> wrote in message news:cbsu2o$9r4$1 digitaldaemon.com..."Walter" <newshound digitalmars.com> skrev i en meddelelse news:cbsq23$46i$1 digitaldaemon.com...There is a built-in sort property for arrays, but not swap.It reminds me - I think it should be documented if the sort isOk, I understand. But I don't know if qsort has that property or not.toIf two items with the same sort key are adjacent in the unsorted array, they will appear in the exact same sequence in the sorted array. eg. Unsorted... E:Eggplant B:Banana C:Carrot C:Cabbage O:Orange A:Apple Sorted: (Key is first character). A:Apple B:Banana C:Carrot C:Cabbage E:Eggplant O:Orangebe stable or not.What does 'stable' mean applied to sorts?
Jun 29 2004
Walter wrote:Ok, I understand. But I don't know if qsort has that property or not.No, quicksort is not stable. /Oskar
Jun 30 2004
"Oskar Linde" <d98-oliRE.MO.VE nada.kth.se> wrote in message news:cbu0k9$26ul$1 digitaldaemon.com...Walter wrote:Then .sort is not stable. <g>Ok, I understand. But I don't know if qsort has that property or not.No, quicksort is not stable.
Jun 30 2004
Walter wrote:"Martin M. Pedersen" <martin moeller-pedersen.dk> wrote in message news:cbsu2o$9r4$1 digitaldaemon.com...that is doesn't swap things that compare equal - though personally I think that usually means the definition of "equal" for that class is sortof flaky (so to speak)."Walter" <newshound digitalmars.com> skrev i en meddelelse news:cbsq23$46i$1 digitaldaemon.com...toThere is a built-in sort property for arrays, but not swap.It reminds me - I think it should be documented if the sort is guaranteedbe stable or not.What does 'stable' mean applied to sorts?
Jun 29 2004
In article <cbsu2o$9r4$1 digitaldaemon.com>, Martin M. Pedersen says..."Walter" <newshound digitalmars.com> skrev i en meddelelse news:cbsq23$46i$1 digitaldaemon.com...toThere is a built-in sort property for arrays, but not swap.It reminds me - I think it should be documented if the sort is guaranteedbe stable or not. Regards, MartinIt would be nice to have a few sorting methods to provide different sorting algorithms. For example if you know quickSort is going to perform badly for your array you might decide to call mergeSort instead.
Jun 30 2004
Indeed, this is why I was hoping for a built-in swap method, so that we could write our own sort algorithms and simply call swap(). "Jesus" <Jesus_member pathlink.com> wrote in message news:cbuf8e$5ko$1 digitaldaemon.com...In article <cbsu2o$9r4$1 digitaldaemon.com>, Martin M. Pedersen says...sorting"Walter" <newshound digitalmars.com> skrev i en meddelelse news:cbsq23$46i$1 digitaldaemon.com...toThere is a built-in sort property for arrays, but not swap.It reminds me - I think it should be documented if the sort is guaranteedbe stable or not. Regards, MartinIt would be nice to have a few sorting methods to provide differentalgorithms. For example if you know quickSort is going to perform badly for your array you might decide to call mergeSort instead.
Jun 30 2004
Dan Williams wrote:Indeed, this is why I was hoping for a built-in swap method, so that we could write our own sort algorithms and simply call swap().Where is the problem of using a temporary and doing the three assignments as usual? Of course, swap is more convenient, but that alone not a good enough reason to make it a language feature.
Jun 30 2004
Yes, it's mainly due to convenience, but not just syntactical convenience. With D, it would appear that pointers only rarely have to be used, and so a swap method would mean that people would not have to access the pointers directly in this scenario. "Norbert Nemec" <Norbert.Nemec gmx.de> wrote in message news:cbuneo$hpk$2 digitaldaemon.com...Dan Williams wrote:asIndeed, this is why I was hoping for a built-in swap method, so that we could write our own sort algorithms and simply call swap().Where is the problem of using a temporary and doing the three assignmentsusual? Of course, swap is more convenient, but that alone not a goodenoughreason to make it a language feature.
Jun 30 2004
"Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbuol1$jrb$1 digitaldaemon.com...With D, it would appear that pointers only rarely have to be used, and soaswap method would mean that people would not have to access the pointers directly in this scenario.Why not this: T[] foo; void swap(inout T e1, inout T e2) { T tmp = e1; e1 = e2; e2 = tmp; } ... swap(foo[i], foo[j]);
Jun 30 2004
"Walter" <newshound digitalmars.com> wrote in message news:cbuutj$sm8$1 digitaldaemon.com..."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbuol1$jrb$1 digitaldaemon.com...soWith D, it would appear that pointers only rarely have to be used, andaWell, unless I'm mistaken, doesn't that do exactly what I described and copy the actual data around memory? Imagine that e1 and e2 are 1Kb each, or 1Mb each, or whatever. Then imagine that your function has to perform, say, 1000 of these swaps. Surely you are going to be copying *far* more data around than is necessary?swap method would mean that people would not have to access the pointers directly in this scenario.Why not this: T[] foo; void swap(inout T e1, inout T e2) { T tmp = e1; e1 = e2; e2 = tmp; } ... swap(foo[i], foo[j]);
Jun 30 2004
"Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbv00u$uc2$1 digitaldaemon.com..."Walter" <newshound digitalmars.com> wrote in message news:cbuutj$sm8$1 digitaldaemon.com...pointers"Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbuol1$jrb$1 digitaldaemon.com...soWith D, it would appear that pointers only rarely have to be used, andaswap method would mean that people would not have to access thecopyWell, unless I'm mistaken, doesn't that do exactly what I described anddirectly in this scenario.Why not this: T[] foo; void swap(inout T e1, inout T e2) { T tmp = e1; e1 = e2; e2 = tmp; } ... swap(foo[i], foo[j]);the actual data around memory? Imagine that e1 and e2 are 1Kb each, or 1Mb each, or whatever. Thenimaginethat your function has to perform, say, 1000 of these swaps. Surely youaregoing to be copying *far* more data around than is necessary?Copying is not going to happen if T is a class because then e1 and e2 are references to objects and not the actual objects.
Jun 30 2004
"Ivan Senji" <ivan.senji public.srce.hr> wrote in message news:cbvaqc$1e7n$1 digitaldaemon.com..."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbv00u$uc2$1 digitaldaemon.com...and"Walter" <newshound digitalmars.com> wrote in message news:cbuutj$sm8$1 digitaldaemon.com..."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbuol1$jrb$1 digitaldaemon.com...With D, it would appear that pointers only rarely have to be used,I think you'll find you are mistaken... in my previous ramblings I described a situation with an array of large strings. Note carefully what is happening here: // an array exists called myArray // it has n elements // we want to swap indices 5 and 9 // let's say myArray[5] = "hello" // let's say myArray[9] = "goodbye" // so, we have: // myArray[5] = "hello" // myArray[9] = "goodbye" // temp = uninitialised temp = myArray[5]; // we now have: // myArray[5] = "hello" // myArray[9] = "goodbye" // temp = "hello" myArray[5] = myArray[9]; // we now have: // myArray[5] = "goodbye" // myArray[9] = "goodbye" // temp = "hello" myArray[9] = temp; // we now have: // myArray[5] = "goodbye" // myArray[9] = "hello" // temp = "hello" // finally we can clear up the temp value or whatever Notice that in doing this, the actual data has been swapped. I used short strings. I ask you to imagine the unneccessary data copying that would take place with multiple swaps of large strings. That is why it is obviously best to swap the pointers rather than the data itself. References to objects has nothing to do with it if you are copying the objects - and in any case, that's not really applicable because we are discussing the swapping of array elements. I'm more than slightly puzzled and disappointed that this elementary and fundamental technique is apparently meeting with such incomprehension. Initially I was a little embarrassed in case I appeared stupid in asking about the swapping (fully expecting someone to say, "there is such a swapping method here", or, "to swap the pointers, do this") but I am now feeling embarrassed in a different way because I feel that I am having to explain basic programming theory that surely most D users already know. Walter, the example you posted appears to do exactly what I have outlined step-by-step above, and swaps the actual data in memory. Can no-one see why that is a "bad thing"? Does no-one understand what I am asking? If I have somehow misunderstood then I apologise in advance for my stupidity, however I find it hard to believe that the method you gave would swap the pointers rather than the data, because if that were the case then they would all end up with the same value.sopointersaswap method would mean that people would not have to access thecopyWell, unless I'm mistaken, doesn't that do exactly what I described anddirectly in this scenario.Why not this: T[] foo; void swap(inout T e1, inout T e2) { T tmp = e1; e1 = e2; e2 = tmp; } ... swap(foo[i], foo[j]);the actual data around memory? Imagine that e1 and e2 are 1Kb each, or 1Mb each, or whatever. Thenimaginethat your function has to perform, say, 1000 of these swaps. Surely youaregoing to be copying *far* more data around than is necessary?Copying is not going to happen if T is a class because then e1 and e2 are references to objects and not the actual objects.
Jun 30 2004
On Wed, 30 Jun 2004 23:38:47 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:"Ivan Senji" <ivan.senji public.srce.hr> wrote in message news:cbvaqc$1e7n$1 digitaldaemon.com...No, it is you who are mistaken (I think) :) Pls see my other response on this topic, in another thread. Basically a string as you have below *is* an array, and an array *is* a reference type like so: struct { int length; void *data; } the thing you are copying around is the above struct, *not* the data pointed to by the void *data in that struct. I wrote a test case D program to proove this. I could be wrong, if so, forgive me. Regan"Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbv00u$uc2$1 digitaldaemon.com...and"Walter" <newshound digitalmars.com> wrote in message news:cbuutj$sm8$1 digitaldaemon.com..."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbuol1$jrb$1 digitaldaemon.com...With D, it would appear that pointers only rarely have to be used,I think you'll find you are mistaken...sopointersaswap method would mean that people would not have to access theand copyWell, unless I'm mistaken, doesn't that do exactly what I describeddirectly in this scenario.Why not this: T[] foo; void swap(inout T e1, inout T e2) { T tmp = e1; e1 = e2; e2 = tmp; } ... swap(foo[i], foo[j]);the actual data around memory? Imagine that e1 and e2 are 1Kb each, or 1Mb each, or whatever. Thenimaginethat your function has to perform, say, 1000 of these swaps. Surelyyou aregoing to be copying *far* more data around than is necessary?Copying is not going to happen if T is a class because then e1 and e2 are references to objects and not the actual objects.in my previous ramblings I described a situation with an array of large strings. Note carefully what is happening here: // an array exists called myArray // it has n elements // we want to swap indices 5 and 9 // let's say myArray[5] = "hello" // let's say myArray[9] = "goodbye" // so, we have: // myArray[5] = "hello" // myArray[9] = "goodbye" // temp = uninitialised temp = myArray[5]; // we now have: // myArray[5] = "hello" // myArray[9] = "goodbye" // temp = "hello" myArray[5] = myArray[9]; // we now have: // myArray[5] = "goodbye" // myArray[9] = "goodbye" // temp = "hello" myArray[9] = temp; // we now have: // myArray[5] = "goodbye" // myArray[9] = "hello" // temp = "hello" // finally we can clear up the temp value or whatever Notice that in doing this, the actual data has been swapped. I used short strings. I ask you to imagine the unneccessary data copying that would take place with multiple swaps of large strings. That is why it is obviously best to swap the pointers rather than the data itself. References to objects has nothing to do with it if you are copying the objects - and in any case, that's not really applicable because we are discussing the swapping of array elements. I'm more than slightly puzzled and disappointed that this elementary and fundamental technique is apparently meeting with such incomprehension. Initially I was a little embarrassed in case I appeared stupid in asking about the swapping (fully expecting someone to say, "there is such a swapping method here", or, "to swap the pointers, do this") but I am now feeling embarrassed in a different way because I feel that I am having to explain basic programming theory that surely most D users already know. Walter, the example you posted appears to do exactly what I have outlined step-by-step above, and swaps the actual data in memory. Can no-one see why that is a "bad thing"? Does no-one understand what I am asking? If I have somehow misunderstood then I apologise in advance for my stupidity, however I find it hard to believe that the method you gave would swap the pointers rather than the data, because if that were the case then they would all end up with the same value.-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 30 2004
Seems like the same thing is now being debated in multiple branches of this thread, so I will concentrate on the other ones (where I have just answered you!) ;) "Regan Heath" <regan netwin.co.nz> wrote in message news:opsafl26ir5a2sq9 digitalmars.com...On Wed, 30 Jun 2004 23:38:47 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:used,"Ivan Senji" <ivan.senji public.srce.hr> wrote in message news:cbvaqc$1e7n$1 digitaldaemon.com..."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbv00u$uc2$1 digitaldaemon.com..."Walter" <newshound digitalmars.com> wrote in message news:cbuutj$sm8$1 digitaldaemon.com..."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbuol1$jrb$1 digitaldaemon.com...With D, it would appear that pointers only rarely have to beshortandNo, it is you who are mistaken (I think) :) Pls see my other response on this topic, in another thread. Basically a string as you have below *is* an array, and an array *is* a reference type like so: struct { int length; void *data; } the thing you are copying around is the above struct, *not* the data pointed to by the void *data in that struct. I wrote a test case D program to proove this. I could be wrong, if so, forgive me. ReganI think you'll find you are mistaken...sopointersaswap method would mean that people would not have to access theand copyWell, unless I'm mistaken, doesn't that do exactly what I describeddirectly in this scenario.Why not this: T[] foo; void swap(inout T e1, inout T e2) { T tmp = e1; e1 = e2; e2 = tmp; } ... swap(foo[i], foo[j]);the actual data around memory? Imagine that e1 and e2 are 1Kb each, or 1Mb each, or whatever. Thenimaginethat your function has to perform, say, 1000 of these swaps. Surelyyou aregoing to be copying *far* more data around than is necessary?Copying is not going to happen if T is a class because then e1 and e2 are references to objects and not the actual objects.in my previous ramblings I described a situation with an array of large strings. Note carefully what is happening here: // an array exists called myArray // it has n elements // we want to swap indices 5 and 9 // let's say myArray[5] = "hello" // let's say myArray[9] = "goodbye" // so, we have: // myArray[5] = "hello" // myArray[9] = "goodbye" // temp = uninitialised temp = myArray[5]; // we now have: // myArray[5] = "hello" // myArray[9] = "goodbye" // temp = "hello" myArray[5] = myArray[9]; // we now have: // myArray[5] = "goodbye" // myArray[9] = "goodbye" // temp = "hello" myArray[9] = temp; // we now have: // myArray[5] = "goodbye" // myArray[9] = "hello" // temp = "hello" // finally we can clear up the temp value or whatever Notice that in doing this, the actual data has been swapped. I usedtostrings. I ask you to imagine the unneccessary data copying that would take place with multiple swaps of large strings. That is why it is obviously best to swap the pointers rather than the data itself. References to objects has nothing to do with it if you are copying the objects - and in any case, that's not really applicable because we are discussing the swapping of array elements. I'm more than slightly puzzled and disappointed that this elementary and fundamental technique is apparently meeting with such incomprehension. Initially I was a little embarrassed in case I appeared stupid in asking about the swapping (fully expecting someone to say, "there is such a swapping method here", or, "to swap the pointers, do this") but I am now feeling embarrassed in a different way because I feel that I am havingoutlinedexplain basic programming theory that surely most D users already know. Walter, the example you posted appears to do exactly what I havehavestep-by-step above, and swaps the actual data in memory. Can no-one see why that is a "bad thing"? Does no-one understand what I am asking? If Isomehow misunderstood then I apologise in advance for my stupidity, however I find it hard to believe that the method you gave would swap the pointers rather than the data, because if that were the case then they would all end up with the same value.-- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 30 2004
Dan Williams wrote:"Walter" <newshound digitalmars.com> wrote in message news:cbuutj$sm8$1 digitaldaemon.com...If they're value types, sure. (The only value types that could be that big I know of are structs and maybe static arrays?). If you're determined to swap them, and not pointers to them, how do you expect the compiler to get the value of e2 into e1 and the value of e1 into e2 without doing a lot of copying? Sam"Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbuol1$jrb$1 digitaldaemon.com...soWith D, it would appear that pointers only rarely have to be used, andaWell, unless I'm mistaken, doesn't that do exactly what I described and copy the actual data around memory? Imagine that e1 and e2 are 1Kb each, or 1Mb each, or whatever. Then imagine that your function has to perform, say, 1000 of these swaps. Surely you are going to be copying *far* more data around than is necessary?swap method would mean that people would not have to access the pointers directly in this scenario.Why not this: T[] foo; void swap(inout T e1, inout T e2) { T tmp = e1; e1 = e2; e2 = tmp; } ... swap(foo[i], foo[j]);
Jul 01 2004
"Sam McCall" <tunah.d tunah.net> wrote in message news:cc0pu0$lak$1 digitaldaemon.com...Dan Williams wrote:pointers"Walter" <newshound digitalmars.com> wrote in message news:cbuutj$sm8$1 digitaldaemon.com..."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbuol1$jrb$1 digitaldaemon.com...soWith D, it would appear that pointers only rarely have to be used, andaswap method would mean that people would not have to access thecopyWell, unless I'm mistaken, doesn't that do exactly what I described anddirectly in this scenario.Why not this: T[] foo; void swap(inout T e1, inout T e2) { T tmp = e1; e1 = e2; e2 = tmp; } ... swap(foo[i], foo[j]);imaginethe actual data around memory? Imagine that e1 and e2 are 1Kb each, or 1Mb each, or whatever. Thenarethat your function has to perform, say, 1000 of these swaps. Surely youNo no no, the point was that I wanted to swap the pointers and not the values :) I misunderstood how D did these things (and hence I'm currently wearing the Dunce cap for the next few days. The fact that the cap has D on it is poetic irony! <g>)going to be copying *far* more data around than is necessary?If they're value types, sure. (The only value types that could be that big I know of are structs and maybe static arrays?). If you're determined to swap them, and not pointers to them, how do you expect the compiler to get the value of e2 into e1 and the value of e1 into e2 without doing a lot of copying?
Jul 01 2004
Dan Williams Wrote:"Sam McCall" <tunah.d tunah.net> wrote in message news:cc0pu0$lak$1 digitaldaemon.com...Dan Williams wrote:pointers"Walter" <newshound digitalmars.com> wrote in message news:cbuutj$sm8$1 digitaldaemon.com..."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbuol1$jrb$1 digitaldaemon.com...soWith D, it would appear that pointers only rarely have to be used, andaswap method would mean that people would not have to access thecopyWell, unless I'm mistaken, doesn't that do exactly what I described anddirectly in this scenario.Why not this: T[] foo; void swap(inout T e1, inout T e2) { T tmp = e1; e1 = e2; e2 = tmp; } ... swap(foo[i], foo[j]);imaginethe actual data around memory? Imagine that e1 and e2 are 1Kb each, or 1Mb each, or whatever. Thenarethat your function has to perform, say, 1000 of these swaps. Surely youNo no no, the point was that I wanted to swap the pointers and not the values :) I misunderstood how D did these things (and hence I'm currently wearing the Dunce cap for the next few days. The fact that the cap has D on it is poetic irony! <g>)going to be copying *far* more data around than is necessary?If they're value types, sure. (The only value types that could be that big I know of are structs and maybe static arrays?). If you're determined to swap them, and not pointers to them, how do you expect the compiler to get the value of e2 into e1 and the value of e1 into e2 without doing a lot of copying?
May 12 2009
Thanks for the reply :) Comments below... "Walter" <newshound digitalmars.com> wrote in message news:cbsq23$46i$1 digitaldaemon.com...real-worldAfter reading things like the discussion at comp.lang.c++ [1], I realised that many of the peoplewhodislike D are simply being picky. I read through the first hundredmessagesof that discussion, and failed to see anything of use (such as'+'performance tests or in-depth language feature analysis) - instead, fartoomuch time was spent simply arguing about whether you should have usedIndeed :)instead of '~' and similar rubbish.I suspect people who latch on to something like that are ones who haven't read the spec. There's lots of legitimate things to criticise D on, but ~ isn't one of them.[2],I was a bit disappointed that the D executable was 110Kb (75kb after stripping) whereas the C++ program was only 36Kb (21Kb after stripping).I'mnot sure why the compiled D program is so much larger than the C oneofbut never mind. That alone is not really a bad thing, as file size is generally not a critical requirement these days.The D runtime library includes the garbage collector, which adds a chunkcode not present in a C++ executable. This chunk is a fixed overhead, though, and does not suggest that D compiled code is any larger.Ahhh, yes that would explain some of the overhead. Very much worth it though![3].Wow! Pretty impressive! :) The results clearly show to me that thecompiledD program was approximately 10x faster than the compiled C++ programThe reason for the speedup is D doesn't need to do memory allocation foritsstrings, whereas C++ does. The inefficiency in the C++ comes from, when you boil it down, not supporting garbage collection, so C++'s std.string constantly isallocatingand copying strings around. wc is a stellar example of why gc'd programscanrun far faster than explicitly managed programs, despite the myth that gc programs are slower.Again, that makes sense. I like the way that pointers are not needed for most of the things that they are in C++, but are still there if you need them... seems like D really does have benefits that are backed up by sound theory, and it wasn't just a fluke in my testing ;) <g>Any chance you (or anyone else) can point me toward something that already exists? In the DTL for example? (No idea where to get that from!) Or will I have to code it myself... in which case I'll post it on the newsgroup.All I can say about that type of array is that I agree with the proposalputforward by Norbert Nemec - has any of that been implemented yet? Is itgoingto be?It's a good candidate for 2.0. But right now, one can emulate such arrays using structs and operator overloading.hoodWhile on the subject on arrays, I have a question. Is it possible tocreateD arrays with mixed types?No, D is statically typed. But you can use templates to do the equivalent, or you can define a 'variant' type and create an array of those instead (which is what most dynamically typed scripting languages do under theanyway).Again, are there any examples of this around, or would I have to do it myself? I figure that people are going to need these things at some point, so if no-one else has written this stuff, I may as well do it. Do you think you will ever introduce a variant data type in D? And which method would you personally recommend - templating, or variant? I think I would go for variant.DMy final question on arrays is the methodology behind them. I figure theHmmmmm... Does that mean that the length of each array element is fixed? Surely I must be misunderstanding something here. Also, in such a case, surely when array keys are deleted you either get memory fragmentation which cannot easily be rectified, or else you have to move the data around upon the deletion itself? Neither of which would appeal to me. Surely there are pointers to the actual elements somewhere? Or are you using a method that I am simply not thinking of right now... (gone 2am, tired!)implementation is probably what I think is the best solution; i.e. that arrays are actually arrays of pointers to variable-length data. Is this correct?No. A D array is a pair of two items, the number of elements in the array and a pointer to the array data.IIn which case, I would like to see things like a built-in swap method, e.g. myArray.swap(index_a, index_b) or whatever syntax you like.behaven't noticed that feature available, but hopefully the benefits willthereapparent. When sorting etc. you don't want to be moving the actual array element data around in memory, just the pointers. I haven't seen ifisare any built-in sort functions, but it doesn't matter - a swap methodIn light of my above comments about the way that array data is stored, would there be an advantage in adding a swap method, or is it pointless?all you need for a lot of things, not just sort. If one is available,pleasepoint me to it! Plus, if this is not included and not going to be, Iassumethat it is still possible to swap the pointers in some way, seeing as wecanmanipulate pointers directly with D, like in C/C++? Please correct me ifanyof that is misunderstood.There is a built-in sort property for arrays, but not swap.inI noticed some talk about the way D programs have Phobos code compiledintothem, and the situation seems to be that the equivalent doesn't happenC,Windowsbecause the libraries are usually already available. Talk was made of turning off the incluusion of the Phobos code, however surely the better option is to simply build some static Phobos libraries, and put these in somewhere like /usr/lib, or even /lib (or wherever appropriate onbefor dlls) so that they are globally available? Isn't that what GCC and friends do? That would then mean that the common code would not have toDrecompiled every time, and neither would it have to be included in everyIndeed, that is what I am on about. I figure it would be nice to compile a .so separately to the individual D programs. Perhaps this is something that will be introduced after v1.0? Once more, thankyou for your time :) Danprogram. My apologies if this suggestion, which seems so obvious to me,hasalready been covered!What you're talking about are DLLs in Windows and shared libraries under linux. Right now, I prefer things to be statically linked in because that avoids "DLL hell" where versions get mismatched.
Jun 29 2004
There's someone in this newsgroup who gets paid by the amount of smileys put in a posting. And that particular person surely is a rich man. Dan Williams wrote:Thanks for the reply :) Comments below... "Walter" <newshound digitalmars.com> wrote in message news:cbsq23$46i$1 digitaldaemon.com...real-worldAfter reading things like the discussion at comp.lang.c++ [1], I realised that many of the peoplewhodislike D are simply being picky. I read through the first hundredmessagesof that discussion, and failed to see anything of use (such as'+'performance tests or in-depth language feature analysis) - instead, fartoomuch time was spent simply arguing about whether you should have usedIndeed :)instead of '~' and similar rubbish.I suspect people who latch on to something like that are ones who haven't read the spec. There's lots of legitimate things to criticise D on, but ~ isn't one of them.[2],I was a bit disappointed that the D executable was 110Kb (75kb after stripping) whereas the C++ program was only 36Kb (21Kb after stripping).I'mnot sure why the compiled D program is so much larger than the C oneofbut never mind. That alone is not really a bad thing, as file size is generally not a critical requirement these days.The D runtime library includes the garbage collector, which adds a chunkcode not present in a C++ executable. This chunk is a fixed overhead, though, and does not suggest that D compiled code is any larger.Ahhh, yes that would explain some of the overhead. Very much worth it though![3].Wow! Pretty impressive! :) The results clearly show to me that thecompiledD program was approximately 10x faster than the compiled C++ programThe reason for the speedup is D doesn't need to do memory allocation foritsstrings, whereas C++ does. The inefficiency in the C++ comes from, when you boil it down, not supporting garbage collection, so C++'s std.string constantly isallocatingand copying strings around. wc is a stellar example of why gc'd programscanrun far faster than explicitly managed programs, despite the myth that gc programs are slower.Again, that makes sense. I like the way that pointers are not needed for most of the things that they are in C++, but are still there if you need them... seems like D really does have benefits that are backed up by sound theory, and it wasn't just a fluke in my testing ;) <g>Any chance you (or anyone else) can point me toward something that already exists? In the DTL for example? (No idea where to get that from!) Or will I have to code it myself... in which case I'll post it on the newsgroup.All I can say about that type of array is that I agree with the proposalputforward by Norbert Nemec - has any of that been implemented yet? Is itgoingto be?It's a good candidate for 2.0. But right now, one can emulate such arrays using structs and operator overloading.hoodWhile on the subject on arrays, I have a question. Is it possible tocreateD arrays with mixed types?No, D is statically typed. But you can use templates to do the equivalent, or you can define a 'variant' type and create an array of those instead (which is what most dynamically typed scripting languages do under theanyway).Again, are there any examples of this around, or would I have to do it myself? I figure that people are going to need these things at some point, so if no-one else has written this stuff, I may as well do it. Do you think you will ever introduce a variant data type in D? And which method would you personally recommend - templating, or variant? I think I would go for variant.DMy final question on arrays is the methodology behind them. I figure theHmmmmm... Does that mean that the length of each array element is fixed? Surely I must be misunderstanding something here. Also, in such a case, surely when array keys are deleted you either get memory fragmentation which cannot easily be rectified, or else you have to move the data around upon the deletion itself? Neither of which would appeal to me. Surely there are pointers to the actual elements somewhere? Or are you using a method that I am simply not thinking of right now... (gone 2am, tired!)implementation is probably what I think is the best solution; i.e. that arrays are actually arrays of pointers to variable-length data. Is this correct?No. A D array is a pair of two items, the number of elements in the array and a pointer to the array data.IIn which case, I would like to see things like a built-in swap method, e.g. myArray.swap(index_a, index_b) or whatever syntax you like.behaven't noticed that feature available, but hopefully the benefits willthereapparent. When sorting etc. you don't want to be moving the actual array element data around in memory, just the pointers. I haven't seen ifisare any built-in sort functions, but it doesn't matter - a swap methodIn light of my above comments about the way that array data is stored, would there be an advantage in adding a swap method, or is it pointless?all you need for a lot of things, not just sort. If one is available,pleasepoint me to it! Plus, if this is not included and not going to be, Iassumethat it is still possible to swap the pointers in some way, seeing as wecanmanipulate pointers directly with D, like in C/C++? Please correct me ifanyof that is misunderstood.There is a built-in sort property for arrays, but not swap.inI noticed some talk about the way D programs have Phobos code compiledintothem, and the situation seems to be that the equivalent doesn't happenC,Windowsbecause the libraries are usually already available. Talk was made of turning off the incluusion of the Phobos code, however surely the better option is to simply build some static Phobos libraries, and put these in somewhere like /usr/lib, or even /lib (or wherever appropriate onbefor dlls) so that they are globally available? Isn't that what GCC and friends do? That would then mean that the common code would not have toDrecompiled every time, and neither would it have to be included in everyIndeed, that is what I am on about. I figure it would be nice to compile a .so separately to the individual D programs. Perhaps this is something that will be introduced after v1.0? Once more, thankyou for your time :) Danprogram. My apologies if this suggestion, which seems so obvious to me,hasalready been covered!What you're talking about are DLLs in Windows and shared libraries under linux. Right now, I prefer things to be statically linked in because that avoids "DLL hell" where versions get mismatched.
Jun 30 2004
I wish :) :D :P ;) "Chr. Grade" <tickle everymail.net> wrote in message news:cbt7ik$n3v$1 digitaldaemon.com...There's someone in this newsgroup who gets paid by the amount of smileys put in a posting. And that particular person surely is a rich man.
Jun 30 2004
Dan Williams wrote: ...Any chance you (or anyone else) can point me toward something that already exists? In the DTL for example? (No idea where to get that from!) Or will I have to code it myself... in which case I'll post it on the newsgroup.DTL hasn't been released yet. Matthew Wilson is working on it, but he's been distracted by his career as an author. You can read more here: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.dtl/57I'd love to see a variant type built into the language.hoodWhile on the subject on arrays, I have a question. Is it possible tocreateD arrays with mixed types?No, D is statically typed. But you can use templates to do the equivalent, or you can define a 'variant' type and create an array of those instead (which is what most dynamically typed scripting languages do under theanyway).... -- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/
Jun 29 2004
On Tue, 29 Jun 2004 23:16:54 -0500, J C Calvarese wrote:Dan Williams wrote: ...Hear! Hear! Long live the VARIANT type. <PLUG type="shameless"> Actually I'm spoilt because I use Euphoria as my main coding language and it's type system is so simple - it only has two data types: Numbers and Vectors. Numbers are IEEE 64-bit floats but are optimised for integers (up to 31-bits). Vectors are dynamic and each element can be either a number or a vector, and they are changeable at runtime. It also has something called an Object but that is just a variant placeholder for any data type. Even though its an interpreted language with garbage collection built-in, Euphoria is frighteningly fast! I'm looking towards D as my choice of compiled language. </PLUG> -- Derek Melbourne, Australia 30/Jun/04 2:46:55 PMAny chance you (or anyone else) can point me toward something that already exists? In the DTL for example? (No idea where to get that from!) Or will I have to code it myself... in which case I'll post it on the newsgroup.DTL hasn't been released yet. Matthew Wilson is working on it, but he's been distracted by his career as an author. You can read more here: http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.dtl/57I'd love to see a variant type built into the language.hoodWhile on the subject on arrays, I have a question. Is it possible tocreateD arrays with mixed types?No, D is statically typed. But you can use templates to do the equivalent, or you can define a 'variant' type and create an array of those instead (which is what most dynamically typed scripting languages do under theanyway)....
Jun 29 2004
Content-type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit On Wed, 30 Jun 2004 14:56:17 +1000, Derek Parnell wrote: [snip]Hear! Hear! Long live the VARIANT type. <PLUG type="shameless"> Actually I'm spoilt because I use Euphoria as my main coding language and it's type system is so simple - it only has two data types: Numbers and Vectors. Numbers are IEEE 64-bit floats but are optimised for integers (up to 31-bits). Vectors are dynamic and each element can be either a number or a vector, and they are changeable at runtime. It also has something called an Object but that is just a variant placeholder for any data type. Even though its an interpreted language with garbage collection built-in, Euphoria is frighteningly fast! I'm looking towards D as my choice of compiled language. </PLUG>I just did a quick speed comparision using the wc.d sample and its equivalent Euphoria program (attached if you're interested). Using a 36.7MB text file... Compiled D (wc.exe) took 1.15 seconds. Interpreted Euphoria (wc.ex) took 4.51 seconds. Not too sloppy for an interpreter! -- Derek Melbourne, Australia 30/Jun/04 4:48:47 PM
Jun 29 2004
"Derek Parnell" <derek psych.ward> wrote in message news:cbth5j$15ml$1 digitaldaemon.com...On Tue, 29 Jun 2004 23:16:54 -0500, J C Calvarese wrote:Glad to see that I'm not the only one who would find a variant data type useful! :DDan Williams wrote: ... I'd love to see a variant type built into the language.Hear! Hear! Long live the VARIANT type....
Jun 30 2004
On Wed, 30 Jun 2004 10:32:24 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:"Derek Parnell" <derek psych.ward> wrote in message news:cbth5j$15ml$1 digitaldaemon.com...What exactly is a variant type? Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/On Tue, 29 Jun 2004 23:16:54 -0500, J C Calvarese wrote:Glad to see that I'm not the only one who would find a variant data type useful! :DDan Williams wrote: ... I'd love to see a variant type built into the language.Hear! Hear! Long live the VARIANT type....
Jun 30 2004
On Thu, 01 Jul 2004 11:11:05 +1200, Regan Heath wrote:On Wed, 30 Jun 2004 10:32:24 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:Let's pretend a bit... variant A; int B = 5; float C = 1.1; char[] D = "a string"; A = B; // ok A = C; // ok A = D; // ok No casts involved. -- Derek Melbourne, Australia"Derek Parnell" <derek psych.ward> wrote in message news:cbth5j$15ml$1 digitaldaemon.com...What exactly is a variant type? Regan.On Tue, 29 Jun 2004 23:16:54 -0500, J C Calvarese wrote:Glad to see that I'm not the only one who would find a variant data type useful! :DDan Williams wrote: ... I'd love to see a variant type built into the language.Hear! Hear! Long live the VARIANT type....
Jun 30 2004
"Derek" <derek psyc.ward> wrote in message news:zp1piricvp4s.1lgdnwwty0ip6$.dlg 40tude.net...On Thu, 01 Jul 2004 11:11:05 +1200, Regan Heath wrote:<dnews ithium.NOSPAM.net>On Wed, 30 Jun 2004 10:32:24 +0100, Dan Williamstypewrote:"Derek Parnell" <derek psych.ward> wrote in message news:cbth5j$15ml$1 digitaldaemon.com...On Tue, 29 Jun 2004 23:16:54 -0500, J C Calvarese wrote:Glad to see that I'm not the only one who would find a variant dataDan Williams wrote: ... I'd love to see a variant type built into the language.Hear! Hear! Long live the VARIANT type.......which is exactly why I am keen to see a variant data type included in the core of the D language ;)Let's pretend a bit... variant A; int B = 5; float C = 1.1; char[] D = "a string"; A = B; // ok A = C; // ok A = D; // ok No casts involved.useful! :DWhat exactly is a variant type? Regan.
Jun 30 2004
On Thu, 1 Jul 2004 09:41:51 +1000, Derek <derek psyc.ward> wrote:On Thu, 01 Jul 2004 11:11:05 +1200, Regan Heath wrote:Cool.. If everything (even primitives) were derived from Object you could simply use that. Classes are, so you can go: class A { } class B : A { } void main() { A a = new A(); B b = new B(); Object v; v = a; v = b; a = b; } Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/On Wed, 30 Jun 2004 10:32:24 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:Let's pretend a bit... variant A; int B = 5; float C = 1.1; char[] D = "a string"; A = B; // ok A = C; // ok A = D; // ok No casts involved."Derek Parnell" <derek psych.ward> wrote in message news:cbth5j$15ml$1 digitaldaemon.com...What exactly is a variant type? Regan.On Tue, 29 Jun 2004 23:16:54 -0500, J C Calvarese wrote:Glad to see that I'm not the only one who would find a variant data type useful! :DDan Williams wrote: ... I'd love to see a variant type built into the language.Hear! Hear! Long live the VARIANT type....
Jun 30 2004
"Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbt4et$ihd$1 digitaldaemon.com...I forgot to add that gc code can also be incrementally smaller, because the logic to keep track of who owns the memory is no longer needed.The D runtime library includes the garbage collector, which adds a chunkofcode not present in a C++ executable. This chunk is a fixed overhead, though, and does not suggest that D compiled code is any larger.Ahhh, yes that would explain some of the overhead. Very much worth it though!Any chance you (or anyone else) can point me toward something that already exists? In the DTL for example? (No idea where to get that from!) Or willIhave to code it myself... in which case I'll post it on the newsgroup.As far as I know, it hasn't been implemented by anyone yet.equivalent,While on the subject on arrays, I have a question. Is it possible tocreateD arrays with mixed types?No, D is statically typed. But you can use templates to do theYou might as well give it a whirl <g>.or you can define a 'variant' type and create an array of those instead (which is what most dynamically typed scripting languages do under thehoodanyway).Again, are there any examples of this around, or would I have to do it myself? I figure that people are going to need these things at some point, so if no-one else has written this stuff, I may as well do it.Do you think you will ever introduce a variant data type in D? And which method would you personally recommend - templating, or variant? I think I would go for variant.Each has their strengths and weaknesses. Templating is part of the language, but variant can simply be part of the library.arrayNo. A D array is a pair of two items, the number of elements in theThink of an array as: struct { int length; void *data; }; You can change either or both members as required to do various things.and a pointer to the array data.Hmmmmm... Does that mean that the length of each array element is fixed? Surely I must be misunderstanding something here.Also, in such a case, surely when array keys are deleted you either get memory fragmentationwhichcannot easily be rectified, or else you have to move the data around upon the deletion itself?You're thinking of associative arrays, which are different from linear arrays?Neither of which would appeal to me. Surely there are pointers to the actual elements somewhere? Or are you using a method thatIam simply not thinking of right now... (gone 2am, tired!)The data member points to the elements. They are stored sequentially in memory.wouldThere is a built-in sort property for arrays, but not swap.In light of my above comments about the way that array data is stored,there be an advantage in adding a swap method, or is it pointless?There's some utility for it, but not a whole lot.thatWhat you're talking about are DLLs in Windows and shared libraries under linux. Right now, I prefer things to be statically linked in becausethatavoids "DLL hell" where versions get mismatched.Indeed, that is what I am on about. I figure it would be nice to compile a .so separately to the individual D programs. Perhaps this is somethingwill be introduced after v1.0?after 1.0
Jun 29 2004
"Walter" <newshound digitalmars.com> wrote in message news:cbtj75$18ub$1 digitaldaemon.com..."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbt4et$ihd$1 digitaldaemon.com...insteadequivalent,D is statically typed. But you can use templates to do theor you can define a 'variant' type and create an array of thoseOk, fair enough :) I'll try to find some time over the next few weeks to do so.You might as well give it a whirl <g>.(which is what most dynamically typed scripting languages do under thehoodanyway).Again, are there any examples of this around, or would I have to do it myself?IDo you think you will ever introduce a variant data type in D? And which method would you personally recommend - templating, or variant? I thinklanguage,would go for variant.Each has their strengths and weaknesses. Templating is part of thebut variant can simply be part of the library.To risk annoyance by repetition: Do you think you will ever introduce a variant data type in D? For instance if I wrote such a thing, would you include it as part of D?uponarrayA D array is a pair of two items, the number of elements in theThink of an array as: struct { int length; void *data; }; You can change either or both members as required to do various things.and a pointer to the array data.Hmmmmm... Does that mean that the length of each array element is fixed? Surely I must be misunderstanding something here.Also, in such a case, surely when array keys are deleted you either get memory fragmentationwhichcannot easily be rectified, or else you have to move the data aroundI think I see what you mean. An array itself is a struct with length n where n is both the count of the elements and also the amount of memory used by the sequentially-stored pointers to element data, yes? And each element then holds its own data with its own data properties. Ok, that makes sense, and this is essentially the way I would handle it in C++. The place that I came unstuck is in asking about element swapping. Let me explain that one further, so that you'll have a clearer idea of my question. Take an array with 100 elements, where each element is a variable-length string. When it comes to sort the array, obviously the best method is to swap the data pointers after a comparison, rather than swap the data itself. Now, this is why I asked about a swap method - there are several things that I would need to utilise a swap for, and obviously I want to be confident that I am swapping the pointers and not the data! As there is no swap method, how would I directly access the array index's data pointers in order to swap them? Imagine that elements 5 and 9 need swapping, and are around about 1Kb each. If I say, temp = myArray[5]; myArray[5] = myArray[9]; myArray[9] = temp; then I am needlessly copying 1Kb blocks around in memory, right? So I need to be able to swap the pointers and therefore temp needs to be a pointer, but while this is straightforward in C++, I don't know how I would do this in D. Therefore my ignorance when it comes to D has prompted what has undoubtably appeared to be a rather stupid question <g>the deletion itself?You're thinking of associative arrays, which are different from linear arrays?Surely there are pointers to the actual elements somewhere? Or are you using a method that I am simply not thinking of right now... (gone 2am, tired!)The data member points to the elements. They are stored sequentially in memory.
Jun 30 2004
In article <cbu32g$2cf0$1 digitaldaemon.com>, Dan Williams says...I think I see what you mean. An array itself is a struct with length n where n is both the count of the elements and also the amount of memory usedbythe sequentially-stored pointers to element data, yes? And each elementthenholds its own data with its own data properties. Ok, that makes sense,andthis is essentially the way I would handle it in C++. The place that I came unstuck is in asking about element swapping. Let me explain that one further, so that you'll have a clearer idea of my question. Take an array with 100 elements, where each element is avariable-lengthstring. When it comes to sort the array, obviously the best method is to swap the data pointers after a comparison, rather than swap the dataitself.Now, this is why I asked about a swap method - there are several thingsthatI would need to utilise a swap for, and obviously I want to be confident that I am swapping the pointers and not the data! As there is no swap method, how would I directly access the arrayindex'sdata pointers in order to swap them? Imagine that elements 5 and 9needswapping, and are around about 1Kb each. If I say, temp = myArray[5]; myArray[5] = myArray[9]; myArray[9] = temp; then I am needlessly copying1Kbblocks around in memory, right? So I need to be able to swap thepointersand therefore temp needs to be a pointer, but while this isstraightforwardin C++, I don't know how I would do this in D. Therefore my ignorancewhenit comes to D has prompted what has undoubtably appeared to be aratherstupid question <g>You appear to have a misunderstanding about the structure of arrays; allow me to clear this up. In an array you have data stored sequentially in memory. Imagine an array of bytes stored at, for the sake of argument, 0x10. byte[0] is stored at 0x10, byte[1] is stored at 0x11 etc. Since the elements are sequential you don't need a pointer to each element, just a single pointer to the first element, which can then be incremented by sizeof(<datatype>) to access subsequent elements. This is what an array in C is. byte[3] is the equivalent of *byte + 3. The problem with this is that you must either use static arrays so the compiler can check every access to make sure you don't try to access past the end of the array, or risk indexing garbage. D improves this by having each array store its length so you can check bounds at run time. You can have an array of pointers if you declare it as such, but if you declare an array of primitives you access them through increments of the base pointer. This is also why you can't mix types; array elements must be the same size so the program knows how many bytes to increment the pointer by. If you want to mix types you can always exploit polymorphism and have arrays of Objects. This, however, means you can't mix primitives unless you wrap them in classes (which is why Java has classes of Integer, Float etc). It would be nice if you can have arrays of "generic pointer" which is what some languages do, and is probably why you're confused. Scheme (LISP dialect) comes to mind as an "everything is a pointer" weakly typed language.
Jun 30 2004
"Jesus" <Jesus_member pathlink.com> wrote in message news:cbuh1n$89l$1 digitaldaemon.com...In article <cbu32g$2cf0$1 digitaldaemon.com>, Dan Williams says...whereI think I see what you mean. An array itself is a struct with length ncamen is both the count of the elements and also the amount of memory usedbythe sequentially-stored pointers to element data, yes? And each elementthenholds its own data with its own data properties. Ok, that makes sense,andthis is essentially the way I would handle it in C++. The place that INot arrays in general... just how D deals with them; specifically arrays with variable-length elements and also associative arrays.unstuck is in asking about element swapping. Let me explain that one further, so that you'll have a clearer idea of my question. Take an array with 100 elements, where each element is avariable-lengthstring. When it comes to sort the array, obviously the best method is to swap the data pointers after a comparison, rather than swap the dataitself.Now, this is why I asked about a swap method - there are several thingsthatI would need to utilise a swap for, and obviously I want to be confident that I am swapping the pointers and not the data! As there is no swap method, how would I directly access the arrayindex'sdata pointers in order to swap them? Imagine that elements 5 and 9needswapping, and are around about 1Kb each. If I say, temp = myArray[5]; myArray[5] = myArray[9]; myArray[9] = temp; then I am needlessly copying1Kbblocks around in memory, right? So I need to be able to swap thepointersand therefore temp needs to be a pointer, but while this isstraightforwardin C++, I don't know how I would do this in D. Therefore my ignorancewhenit comes to D has prompted what has undoubtably appeared to be aratherstupid question <g>You appear to have a misunderstanding about the structure of arrays; allow me to clear this up.In an array you have data stored sequentially in memory. Imagine an array of bytes stored at, for the sake of argument, 0x10. byte[0] is stored at0x10,byte[1] is stored at 0x11 etc. Since the elements are sequential you don't need a pointer to each element, just a single pointer to the first element, which can then be incremented by sizeof(<datatype>) to access subsequent elements. This is what an array in C is. byte[3] is the equivalent of *byte + 3.That works fine for arrays with fixed-length elements, such as arrays of type int, or arrays of pointers to other arrays.The problem with this is that you must either use static arrays so the compiler can check every access to make sure you don't try to access past the end of the array, or risk indexing garbage. D improves this by having each array store its length so you can check bounds at run time. You can have an array of pointers if you declare it as such, but if you declare an array of primitives you access them through increments of the base pointer. This is also why you can't mix types; array elements must be the same size so the program knows how many bytes to increment the pointer by.But this is the problem that I am asking about. If you notice, my question was directed not at arrays with fixed-length elements, but those with variable-length elements. Ten years or so ago I remember a similar problem with database filesystems. The whole sequential access versus random access thing (boy that takes me back!). In some ways this is the same - it's fine to have a fixed-size entity stored in the way you describe, because simple calculations will tell you where every element in the array starts and ends. However, it soon falls apart when you have a variable-length entity. For instance, let's say I want to store two strings; one is 10 bytes long and the other is 1000 bytes long. Right at the start I have a problem here because I don't personally know how D would store that. From what I can gather, because strings are dealt with as character arrays in D (similar to but better than C++) the main array would not "store" the complete string, but a reference to the character array, which of course in turn references its own elements. Is this correct?If you want to mix types you can always exploit polymorphism and have arrays of Objects. This, however, means you can't mix primitives unless you wrap them in classes (which is why Java has classes of Integer, Float etc). It would be nice if you can have arrays of "generic pointer" whichiswhat some languages do, and is probably why you're confused. Scheme (LISP dialect) comes to mind as an "everything is a pointer" weakly typed language.I think what is wrong here is that we are both missing what the other is saying, to some extent. Believe me, I understand all about arrays :) I've written code using what must surely be just about every array-type structure out there in the past ten years, and in various languages. My questions were badly explained, due to my ignorance of how D has been written. In the description of D's various features, I see things that make me think, "oh, is D doing that this way or that way?" and so I ask the question... and then someone doesn't quite understand what I am asking, because I am not sure how to ask :) If all D arrays are simply the same as C++ arrays but with length etc. built in (i.e. if the storage mechanism is, for the purpose of our needs, the same) then I have at least some familiar ground on which to stand. I guess maybe I should have experimented a bit before asking, however I wasn't even sure how to test to determine the method in use! Perhaps I should just have assumed that D arrays were stored in the way you describe, but I was always taught to ask questions because "assume makes an ass out of u and me" and all that <g> Which brings me back to the point I started rambling about in the first place. I have decided to reiterate it like this: "What happens, data-wise, when two elements in an array are swapped?" If you read what I said about wanting to avoid copying more memory than necessary, you will hopefully be able to pick up on my trail here and see why I was asking these silly questions in the first place. I do have a precedant in asking - I have seen C code written by people that needlessly swaps actual data around in memory rather than the pointers to said data, so I wish to ensure that I don't do the same thing in D by mistake as a result of not inquiring about the underlying mechanism.
Jun 30 2004
Dan Williams wrote:What you call "arrays with variable-length elements" should rather be called nested array. The array elements themselves always have a fixed size. If you need an array of strings, thats effectively an array holding references to arrays which then hold the individual string data. Just the same as in C. Your example for swapping data already is handling references as it is. Variable-sized data can always only be handled by reference. Just like in C. There is little mystic bahavior in D arrays, just that an array reference does not only keep the pointer, but also the length of the array.You appear to have a misunderstanding about the structure of arrays; allow me to clear this up.Not arrays in general... just how D deals with them; specifically arrays with variable-length elements and also associative arrays.
Jun 30 2004
Hmmmm... "Norbert Nemec" <Norbert.Nemec gmx.de> wrote in message news:cbun74$hpk$1 digitaldaemon.com...Dan Williams wrote:calledWhat you call "arrays with variable-length elements" should rather beYou appear to have a misunderstanding about the structure of arrays; allow me to clear this up.Not arrays in general... just how D deals with them; specifically arrays with variable-length elements and also associative arrays.nested array. The array elements themselves always have a fixed size. If you need an array of strings, thats effectively an array holdingreferencesto arrays which then hold the individual string data. Just the same as in C.I believe that is what I went on to describe.Your example for swapping data already is handling references as it is. Variable-sized data can always only be handled by reference. Just like in C.I think that what you are saying is right, but applied wrongly to my question. Making a copy will make a copy of the data, whether accessed by reference or not. This is precisely what I wish to avoid - I want to only swap the pointers. I do not see how three assignments using a temporary variable will acheive this; rather, it will copy the data itself three times.There is little mystic bahavior in D arrays, just that an array reference does not only keep the pointer, but also the length of the array.The first thing I wanted to find out was how D dealt with arrays. It seems I went about my questioning in a confusing way, but I got there in the end! :) The second thing was talking about element swapping, and for some reason it would appear that I'm still not quite being understood on this :( (not sure why, as it is pretty fundamental stuff).
Jun 30 2004
On Wed, 30 Jun 2004 17:19:17 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:Hmmmm... "Norbert Nemec" <Norbert.Nemec gmx.de> wrote in message news:cbun74$hpk$1 digitaldaemon.com...I think I have understood you in my last post.. haven't I? Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/Dan Williams wrote:calledarraysYou appear to have a misunderstanding about the structure of arrays; allow me to clear this up.Not arrays in general... just how D deals with them; specificallywith variable-length elements and also associative arrays.What you call "arrays with variable-length elements" should rather benested array. The array elements themselves always have a fixed size. If you need an array of strings, thats effectively an array holdingreferencesto arrays which then hold the individual string data. Just the same as in C.I believe that is what I went on to describe.Your example for swapping data already is handling references as it is. Variable-sized data can always only be handled by reference. Just like in C.I think that what you are saying is right, but applied wrongly to my question. Making a copy will make a copy of the data, whether accessed by reference or not. This is precisely what I wish to avoid - I want to only swap the pointers. I do not see how three assignments using a temporary variable will acheive this; rather, it will copy the data itself three times.There is little mystic bahavior in D arrays, just that an array reference does not only keep the pointer, but also the length of the array.The first thing I wanted to find out was how D dealt with arrays. It seems I went about my questioning in a confusing way, but I got there in the end! :) The second thing was talking about element swapping, and for some reason it would appear that I'm still not quite being understood on this :( (not sure why, as it is pretty fundamental stuff).
Jun 30 2004
"Regan Heath" <regan netwin.co.nz> wrote in message news:opsafkzewn5a2sq9 digitalmars.com...On Wed, 30 Jun 2004 17:19:17 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:IfHmmmm... "Norbert Nemec" <Norbert.Nemec gmx.de> wrote in message news:cbun74$hpk$1 digitaldaemon.com...Dan Williams wrote:calledarraysYou appear to have a misunderstanding about the structure of arrays; allow me to clear this up.Not arrays in general... just how D deals with them; specificallywith variable-length elements and also associative arrays.What you call "arrays with variable-length elements" should rather benested array. The array elements themselves always have a fixed size....I think so, but for some reason it seems everyone is missing the point of what I am trying to say about swapping. I find that very unnerving! <g>I think I have understood you in my last post.. haven't I? Regan.you need an array of strings, thats effectively an array holdingreferencesto arrays which then hold the individual string data. Just the same as in C.I believe that is what I went on to describe.Your example for swapping data already is handling references as it is. Variable-sized data can always only be handled by reference. Just like in C.I think that what you are saying is right, but applied wrongly to my question. Making a copy will make a copy of the data, whether accessed by reference or not. This is precisely what I wish to avoid - I want to only swap the pointers. I do not see how three assignments using a temporary variable will acheive this; rather, it will copy the data itself three times.There is little mystic bahavior in D arrays, just that an array reference does not only keep the pointer, but also the length of the array.The first thing I wanted to find out was how D dealt with arrays. It seems I went about my questioning in a confusing way, but I got there in the end! :) The second thing was talking about element swapping, and for some reason it would appear that I'm still not quite being understood on this :( (not sure why, as it is pretty fundamental stuff).
Jun 30 2004
On Wed, 30 Jun 2004 17:19:17 +0100, Dan Williams wrote:Hmmmm...[snip]The second thing was talking about element swapping, and for some reason it would appear that I'm still not quite being understood on this :( (not sure why, as it is pretty fundamental stuff).Okay, I'll have a go at describing D's swap behaviour... #char[] A = "first"; #char[] B = "second"; #void main() Using the code example above... Initially 'A' takes up a single two-32-bit area of RAM. Let's say A is located at RAM Address (RA) 1000. And likewise, B is at 2060. The first 32-bit portion of what makes up A's content has the string length of 5, and B's first 32-bit area contains 6 (the length of 'second'). The second 32-bit area of A contains the address of the bytes that make up the literal 'first'. Let's say this is RA 4016. B's string pointer also points to its data 'second'. Let's say it is at 5012. So summarizing... A --> [5,4016] B --> [6,5012] Now we have T which has no initial values. T is located at 7000 and also has a two-32-bit area. The assignment "T = A" cause T to have the contents [5,4016]. "A = B" cause A to now have the contents [6,5012]. "B = T" causes B to have the contents [5,4016]. So we end up with ... A --> [6,5012] B --> [5,4016] Meanwhile the actual string data has not moved a muscle. Hope this helps. -- Derek Melbourne, Australia
Jun 30 2004
"Derek" <derek psyc.ward> wrote in message news:1txb3s0xe4h7a$.oc6ijhdctn5l.dlg 40tude.net...On Wed, 30 Jun 2004 17:19:17 +0100, Dan Williams wrote:itHmmmm...[snip]The second thing was talking about element swapping, and for some reasonsurewould appear that I'm still not quite being understood on this :( (notandwhy, as it is pretty fundamental stuff).Okay, I'll have a go at describing D's swap behaviour... #char[] A = "first"; #char[] B = "second"; #void main() Using the code example above... Initially 'A' takes up a single two-32-bit area of RAM. Let's say A is located at RAM Address (RA) 1000. And likewise, B is at 2060. The first 32-bit portion of what makes up A's content has the string length of 5,B's first 32-bit area contains 6 (the length of 'second'). The second 32-bit area of A contains the address of the bytes that make up theliteral'first'. Let's say this is RA 4016. B's string pointer also points to its data 'second'. Let's say it is at 5012.So far, so good... I understand and agree with that, and it is what I would expect.So summarizing... A --> [5,4016] B --> [6,5012] Now we have T which has no initial values. T is located at 7000 and also has a two-32-bit area.Again, agreed.The assignment "T = A" cause T to have the contents [5,4016]. "A = B" cause A to now have the contents [6,5012]. "B = T" causes B to have the contents [5,4016]. So we end up with ...No, no, NO! Gah! ...I'll explain in a minute :DA --> [6,5012] B --> [5,4016] Meanwhile the actual string data has not moved a muscle.There are two, and only two, methods for this. A) The string data itself is copied B) The pointer is copied Now, B) is the method I want to use... and is also the method you have *described*, but *NOT* the method that would actually take place in the code example you have provided.This code will copy the string data, not the pointer! Stop, step back, think about it for a minute. What happens if you do this:OK? Yes? That's the way it should be; all is well. BUT if what you are saying is true:Uh-oh! Oh dear! Not what we wanted! Why has this happened? Because, in your example:The assignment "T = A" cause T to have the contents [5,4016]. "A = B" cause A to now have the contents [6,5012]. "B = T" causes B to have the contents [5,4016].So, that means that if part way through we change A, even though we already copied A to T, we are still changing T! Obviously this is incorrect and flawed, as that is not what assignment does or is supposed to do. Your example did not have anything in it to specify that a reference should be used, so in that case a copy should be made. Just like passing by reference or by value etc. So... the strings DO move around in memory if you copy in this way - they must do, they have to do so, otherwise the language would not make any sense. If everything was assigned by reference when you do a simple a = b then how would you make copies? I know that one can utilise pointers in D, and I haven't actually looked too deeply into that for two reasons: first, I hate pointers <g> and second, D seems geared up so that you shouldn't really have to use pointers. This is why I started asking about a swap method, although thinking about it, maybe it would be good to have simply as a standalone function and not as a dedicated array method. It's late for me right now (1am) but if I get chance tomorrow, I will look into how D deals with pointers, and write a test case to demonstrate the two different methods.
Jun 30 2004
On Thu, 1 Jul 2004 01:03:02 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:There are two, and only two, methods for this. A) The string data itself is copied B) The pointer is copied Now, B) is the method I want to use... and is also the method you have *described*, but *NOT* the method that would actually take place in the code example you have provided.B) is the method that *does* actually take place, try my example code... --[test.d]-- struct array { int length; void *data; } void swap(inout char[] A, inout char[] B) { char[] T; T = A; A = B; B = T; } void swapAssign(inout char[] A, inout char[] B, char[] value) { char[] T; T = A; A = value; B = T; } void output(char[] A, char[] label) { array *p = cast(array *)&A; printf("(%.*s) = %08x = (%.*s)\n",label,p.data,p.length,p.data); } void main() { char[] A = "first"; char[] B = "second"; char[] C = "third"; output(A,"A"); output(B,"B"); output(C,"C"); printf("\n"); swapAssign(A,B,"car"); output(A,"A"); output(B,"B"); output(C,"C"); printf("\n"); } it prints: D:\D\src\build\temp>copytest (A) = 0040f098 = (first) (B) = 0040f0a8 = (second) (C) = 0040f0b8 = (third) (A) = 0040f0f8 = (car) (B) = 0040f098 = (first) (C) = 0040f0b8 = (third)This cannot be applied as it does not take the assignment to the new array into account, it should now read... The assignment "T = A" cause T to have the contents [5,4016]. A = "car" cause A to have contents of the new array, say [3,6012]. "B = T" causes B to have the contents [5,4016].This code will copy the string data, not the pointer! Stop, step back, think about it for a minute. What happens if you do this:OK? Yes? That's the way it should be; all is well. BUT if what you are saying is true:Uh-oh! Oh dear! Not what we wanted! Why has this happened? Because, in your example:The assignment "T = A" cause T to have the contents [5,4016]. "A = B" cause A to now have the contents [6,5012]. "B = T" causes B to have the contents [5,4016].So, that means that if part way through we change A, even though we already copied A to T, we are still changing T! Obviously this is incorrect and flawed, as that is not what assignment does or is supposed to do. Your example did not have anything in it to specify that a reference should be used, so in that case a copy should be made. Just like passing by reference or by value etc. So... the strings DO move around in memory if you copy in this wayNope.- they must do, they have to do so, otherwise the language would not make any sense. If everything was assigned by reference when you do a simple a = b then how would you make copies?You call the .dup method on the array.I know that one can utilise pointers in D, and I haven't actually looked too deeply into that for two reasons: first, I hate pointers <g> and second, D seems geared up so that you shouldn't really have to use pointers.I don't mind pointers, they are powerful, if a little dangerous, that's part of the attraction. I do like that I can get almost the same power in D without them.This is why I started asking about a swap method, although thinking about it, maybe it would be good to have simply as a standalone function and not as a dedicated array method.Or this template: template swap(T) { void swap(inout T a, inout T b) { T c; c = a; a = b; b = c; } } which works for everything, copying memory only if T is a struct of some sort.It's late for me right now (1am) but if I get chance tomorrow, I will look into how D deals with pointers, and write a test case to demonstrate the two different methods.Try my test case. Let me know where/if it's wrong somehow. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 30 2004
"Regan Heath" <regan netwin.co.nz> wrote in message news:opsafn8xwr5a2sq9 digitalmars.com...On Thu, 1 Jul 2004 01:03:02 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:beThere are two, and only two, methods for this. A) The string data itself is copied B) The pointer is copied Now, B) is the method I want to use... and is also the method you have *described*, but *NOT* the method that would actually take place in the code example you have provided.B) is the method that *does* actually take place, try my example code... --[test.d]-- struct array { int length; void *data; } void swap(inout char[] A, inout char[] B) { char[] T; T = A; A = B; B = T; } void swapAssign(inout char[] A, inout char[] B, char[] value) { char[] T; T = A; A = value; B = T; } void output(char[] A, char[] label) { array *p = cast(array *)&A; printf("(%.*s) = %08x = (%.*s)\n",label,p.data,p.length,p.data); } void main() { char[] A = "first"; char[] B = "second"; char[] C = "third"; output(A,"A"); output(B,"B"); output(C,"C"); printf("\n"); swapAssign(A,B,"car"); output(A,"A"); output(B,"B"); output(C,"C"); printf("\n"); } it prints: D:\D\src\build\temp>copytest (A) = 0040f098 = (first) (B) = 0040f0a8 = (second) (C) = 0040f0b8 = (third) (A) = 0040f0f8 = (car) (B) = 0040f098 = (first) (C) = 0040f0b8 = (third)This cannot be applied as it does not take the assignment to the new array into account, it should now read... The assignment "T = A" cause T to have the contents [5,4016]. A = "car" cause A to have contents of the new array, say [3,6012]. "B = T" causes B to have the contents [5,4016].This code will copy the string data, not the pointer! Stop, step back, think about it for a minute. What happens if you do this:OK? Yes? That's the way it should be; all is well. BUT if what you are saying is true:Uh-oh! Oh dear! Not what we wanted! Why has this happened? Because, in your example:The assignment "T = A" cause T to have the contents [5,4016]. "A = B" cause A to now have the contents [6,5012]. "B = T" causes B to have the contents [5,4016].So, that means that if part way through we change A, even though we already copied A to T, we are still changing T! Obviously this is incorrect and flawed, as that is not what assignment does or is supposed to do. Your example did not have anything in it to specify that a reference shouldbused, so in that case a copy should be made. Just like passing by reference or by value etc. So... the strings DO move around in memory if you copy in this wayNope.- they must do, they have to do so, otherwise the language would not make any sense. If everything was assigned by reference when you do a simple a =Hey :) Thanks for doing that... I will look into it in more detail tomorrow. But for now, in the past few minutes I have quickly modified the other code example that you posted, and here it is: import std.random; void main() { char[][10] a; char[] temp; // create 10 random char[] of 10000 chars foreach(inout char[] s; a) { s.length = 10000; for(uint i = 0; i < s.length; i++) { s[i] = 'a' + rand()&25; } } // print the location and address of the elements 5 and 9 printf("\nbefore swap:\n"); printf("%02d. %08x\n",5,&a[5]); printf("%02d. %08x\n",9,&a[9]); // do swap temp = a[5]; a[5] = a[9]; a[9] = temp; // print the location and address of the elements 5 and 9 printf("\nafter swap:\n"); printf("%02d. %08x\n",5,&a[5]); printf("%02d. %08x\n",9,&a[9]); } Interestingly, the results are exactly what I would expect: before swap: 05. 0012ff00 09. 0012ff20 after swap: 05. 0012ff00 09. 0012ff20 The pointers have stayed the same, and the data has moved. I have not had chance to look at your code, or work out why it gets different results, and neither have I had the opportunity to examine my own in detail, so it is quite possible that I have mucked it up somewhere! :) However, I will leave you with that and maybe you can point out what I am doing "wrong" or how I *should* be doing this, etc. etc. etc.then how would you make copies?You call the .dup method on the array.I know that one can utilise pointers in D, and I haven't actually looked too deeply into that for two reasons: first, I hate pointers <g> and second, D seems geared up so that you shouldn't really have to use pointers.I don't mind pointers, they are powerful, if a little dangerous, that's part of the attraction. I do like that I can get almost the same power in D without them.This is why I started asking about a swap method, although thinking about it, maybe it would be good to have simply as a standalone function and not as a dedicated array method.Or this template: template swap(T) { void swap(inout T a, inout T b) { T c; c = a; a = b; b = c; } } which works for everything, copying memory only if T is a struct of some sort.It's late for me right now (1am) but if I get chance tomorrow, I will look into how D deals with pointers, and write a test case to demonstrate the two different methods.Try my test case. Let me know where/if it's wrong somehow. Regan --
Jun 30 2004
Dan Williams wrote:The pointers have stayed the same, and the data has moved.Pay attention.. the data in the case of a string IS A POINTER (and a length). --Steve
Jun 30 2004
On Thu, 1 Jul 2004 01:54:11 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:"Regan Heath" <regan netwin.co.nz> wrote in message news:opsafn8xwr5a2sq9 digitalmars.com...I took your code, compiled and verified, got the same results :) Then I looked closely, and the line: printf("%02d. %08x\n",5,&a[5]); is actually printing the address of the reference at position 5, not the address of the data referenced by that reference, changing it to printf("%02d. %08x\n",5,&(a[5])[0]); prints the address of the first element in the data, recompiling and running gives. D:\D\src\build\temp>dmd sort3.d d:\D\dmd\bin\..\..\dm\bin\link.exe sort3,,,user32+kernel32/noi; D:\D\src\build\temp>sort3 before swap: 05. 007e2000 09. 007ee000 after swap: 05. 007ee000 09. 007e2000 So.. there you have it. If you're still not convinced it is not copying, try this one static uint bytes = 134217728; void main() { char[] A = new char[bytes]; char[] B = new char[bytes]; printf("START (%d)\n",bytes); if (true) { char[] T; T = A; A = B; B = T; } printf("END\n"); } when you run it, it will take a while to print that first line (as it's allocating a large chunk of memory), but it prints the second immediately after it. You could argue flushing to stdout is an issue here, perhaps someone can verify and/or tell us how to ensure it's flushing the lines. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/On Thu, 1 Jul 2004 01:03:02 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:beThere are two, and only two, methods for this. A) The string data itself is copied B) The pointer is copied Now, B) is the method I want to use... and is also the method you have *described*, but *NOT* the method that would actually take place inthecode example you have provided.B) is the method that *does* actually take place, try my example code... --[test.d]-- struct array { int length; void *data; } void swap(inout char[] A, inout char[] B) { char[] T; T = A; A = B; B = T; } void swapAssign(inout char[] A, inout char[] B, char[] value) { char[] T; T = A; A = value; B = T; } void output(char[] A, char[] label) { array *p = cast(array *)&A; printf("(%.*s) = %08x = (%.*s)\n",label,p.data,p.length,p.data); } void main() { char[] A = "first"; char[] B = "second"; char[] C = "third"; output(A,"A"); output(B,"B"); output(C,"C"); printf("\n"); swapAssign(A,B,"car"); output(A,"A"); output(B,"B"); output(C,"C"); printf("\n"); } it prints: D:\D\src\build\temp>copytest (A) = 0040f098 = (first) (B) = 0040f0a8 = (second) (C) = 0040f0b8 = (third) (A) = 0040f0f8 = (car) (B) = 0040f098 = (first) (C) = 0040f0b8 = (third)This cannot be applied as it does not take the assignment to the new array into account, it should now read... The assignment "T = A" cause T to have the contents [5,4016]. A = "car" cause A to have contents of the new array, say [3,6012]. "B = T" causes B to have the contents [5,4016].This code will copy the string data, not the pointer! Stop, step back, think about it for a minute. What happens if you do this:OK? Yes? That's the way it should be; all is well. BUT if what you are saying is true:Uh-oh! Oh dear! Not what we wanted! Why has this happened? Because, in your example:The assignment "T = A" cause T to have the contents [5,4016]. "A = B" cause A to now have the contents [6,5012]. "B = T" causes B to have the contents [5,4016].So, that means that if part way through we change A, even though we already copied A to T, we are still changing T! Obviously this is incorrectandflawed, as that is not what assignment does or is supposed to do. Your example did not have anything in it to specify that a reference shouldbused, so in that case a copy should be made. Just like passing by reference or by value etc. So... the strings DO move around in memory if you copy in this wayNope.- they must do, they have to do so, otherwise the language would not make any sense. If everything was assigned by reference when you do a simple a=Hey :) Thanks for doing that... I will look into it in more detail tomorrow. But for now, in the past few minutes I have quickly modified the other code example that you posted, and here it is: import std.random; void main() { char[][10] a; char[] temp; // create 10 random char[] of 10000 chars foreach(inout char[] s; a) { s.length = 10000; for(uint i = 0; i < s.length; i++) { s[i] = 'a' + rand()&25; } } // print the location and address of the elements 5 and 9 printf("\nbefore swap:\n"); printf("%02d. %08x\n",5,&a[5]); printf("%02d. %08x\n",9,&a[9]); // do swap temp = a[5]; a[5] = a[9]; a[9] = temp; // print the location and address of the elements 5 and 9 printf("\nafter swap:\n"); printf("%02d. %08x\n",5,&a[5]); printf("%02d. %08x\n",9,&a[9]); } Interestingly, the results are exactly what I would expect: before swap: 05. 0012ff00 09. 0012ff20 after swap: 05. 0012ff00 09. 0012ff20 The pointers have stayed the same, and the data has moved. I have not had chance to look at your code, or work out why it gets different results, and neither have I had the opportunity to examine my own in detail, so it is quite possible that I have mucked it up somewhere! :) However, I will leave you with that and maybe you can point out what I am doing "wrong" or how I *should* be doing this, etc. etc. etc.then how would you make copies?You call the .dup method on the array.I know that one can utilise pointers in D, and I haven't actuallylookedtoo deeply into that for two reasons: first, I hate pointers <g> andsecond,D seems geared up so that you shouldn't really have to use pointers.I don't mind pointers, they are powerful, if a little dangerous, that's part of the attraction. I do like that I can get almost the same power in D without them.This is why I started asking about a swap method, although thinking about it, maybe it would be good to have simply as a standalone function and not as a dedicated array method.Or this template: template swap(T) { void swap(inout T a, inout T b) { T c; c = a; a = b; b = c; } } which works for everything, copying memory only if T is a struct of some sort.It's late for me right now (1am) but if I get chance tomorrow, I will look into how D deals with pointers, and write a test case to demonstratethetwo different methods.Try my test case. Let me know where/if it's wrong somehow. Regan --
Jun 30 2004
"Regan Heath" <regan netwin.co.nz> wrote in message news:opsafqgl0r5a2sq9 digitalmars.com...On Thu, 1 Jul 2004 01:54:11 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:have"Regan Heath" <regan netwin.co.nz> wrote in message news:opsafn8xwr5a2sq9 digitalmars.com...On Thu, 1 Jul 2004 01:03:02 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:There are two, and only two, methods for this. A) The string data itself is copied B) The pointer is copied Now, B) is the method I want to use... and is also the method youcode...*described*, but *NOT* the method that would actually take place inthecode example you have provided.B) is the method that *does* actually take place, try my exampleback,--[test.d]-- struct array { int length; void *data; } void swap(inout char[] A, inout char[] B) { char[] T; T = A; A = B; B = T; } void swapAssign(inout char[] A, inout char[] B, char[] value) { char[] T; T = A; A = value; B = T; } void output(char[] A, char[] label) { array *p = cast(array *)&A; printf("(%.*s) = %08x = (%.*s)\n",label,p.data,p.length,p.data); } void main() { char[] A = "first"; char[] B = "second"; char[] C = "third"; output(A,"A"); output(B,"B"); output(C,"C"); printf("\n"); swapAssign(A,B,"car"); output(A,"A"); output(B,"B"); output(C,"C"); printf("\n"); } it prints: D:\D\src\build\temp>copytest (A) = 0040f098 = (first) (B) = 0040f0a8 = (second) (C) = 0040f0b8 = (third) (A) = 0040f0f8 = (car) (B) = 0040f098 = (first) (C) = 0040f0b8 = (third)This code will copy the string data, not the pointer! Stop, steparethink about it for a minute. What happens if you do this:OK? Yes? That's the way it should be; all is well. BUT if what youinsaying is true:Uh-oh! Oh dear! Not what we wanted! Why has this happened? Because,Youryour example:This cannot be applied as it does not take the assignment to the new array into account, it should now read... The assignment "T = A" cause T to have the contents [5,4016]. A = "car" cause A to have contents of the new array, say [3,6012]. "B = T" causes B to have the contents [5,4016].The assignment "T = A" cause T to have the contents [5,4016]. "A = B" cause A to now have the contents [6,5012]. "B = T" causes B to have the contents [5,4016].So, that means that if part way through we change A, even though we already copied A to T, we are still changing T! Obviously this is incorrectandflawed, as that is not what assignment does or is supposed to do.shouldexample did not have anything in it to specify that a referenceanybeused, so in that case a copy should be made. Just like passing by reference or by value etc. So... the strings DO move around in memory if you copy in this wayNope.- they must do, they have to do so, otherwise the language would not makesomebsense. If everything was assigned by reference when you do a simple a=then how would you make copies?You call the .dup method on the array.I know that one can utilise pointers in D, and I haven't actuallylookedtoo deeply into that for two reasons: first, I hate pointers <g> andsecond,D seems geared up so that you shouldn't really have to use pointers.I don't mind pointers, they are powerful, if a little dangerous, that's part of the attraction. I do like that I can get almost the same power in D without them.This is why I started asking about a swap method, although thinking about it, maybe it would be good to have simply as a standalone function and not as a dedicated array method.Or this template: template swap(T) { void swap(inout T a, inout T b) { T c; c = a; a = b; b = c; } } which works for everything, copying memory only if T is a struct of:)sort.Hey :) Thanks for doing that... I will look into it in more detail tomorrow. But for now, in the past few minutes I have quickly modified the other code example that you posted, and here it is: import std.random; void main() { char[][10] a; char[] temp; // create 10 random char[] of 10000 chars foreach(inout char[] s; a) { s.length = 10000; for(uint i = 0; i < s.length; i++) { s[i] = 'a' + rand()&25; } } // print the location and address of the elements 5 and 9 printf("\nbefore swap:\n"); printf("%02d. %08x\n",5,&a[5]); printf("%02d. %08x\n",9,&a[9]); // do swap temp = a[5]; a[5] = a[9]; a[9] = temp; // print the location and address of the elements 5 and 9 printf("\nafter swap:\n"); printf("%02d. %08x\n",5,&a[5]); printf("%02d. %08x\n",9,&a[9]); } Interestingly, the results are exactly what I would expect: before swap: 05. 0012ff00 09. 0012ff20 after swap: 05. 0012ff00 09. 0012ff20 The pointers have stayed the same, and the data has moved. I have not had chance to look at your code, or work out why it gets different results, and neither have I had the opportunity to examine my own in detail, so it is quite possible that I have mucked it up somewhere!It's late for me right now (1am) but if I get chance tomorrow, I will look into how D deals with pointers, and write a test case to demonstratethetwo different methods.Try my test case. Let me know where/if it's wrong somehow. Regan --amHowever, I will leave you with that and maybe you can point out what IHeh... I had simply altered your code for that bit ;)doing "wrong" or how I *should* be doing this, etc. etc. etc.I took your code, compiled and verified, got the same results :) Then I looked closely, and the line: printf("%02d. %08x\n",5,&a[5]); is actually printing the address of the reference at position 5, not the address of the data referenced by that reference, changing it to printf("%02d. %08x\n",5,&(a[5])[0]);prints the address of the first element in the data, recompiling and running gives. D:\D\src\build\temp>dmd sort3.d d:\D\dmd\bin\..\..\dm\bin\link.exe sort3,,,user32+kernel32/noi; D:\D\src\build\temp>sort3 before swap: 05. 007e2000 09. 007ee000 after swap: 05. 007ee000 09. 007e2000Indeed, I got the same result.So.. there you have it. If you're still not convinced it is not copying, try this one static uint bytes = 134217728; void main() { char[] A = new char[bytes]; char[] B = new char[bytes]; printf("START (%d)\n",bytes); if (true) { char[] T; T = A; A = B; B = T; } printf("END\n"); } when you run it, it will take a while to print that first line (as it's allocating a large chunk of memory), but it prints the second immediately after it.Yup, that happened.You could argue flushing to stdout is an issue here, perhaps someone can verify and/or tell us how to ensure it's flushing the lines.That shouldn't be an issue... changing your code to the following example will prove that: static uint bytes = 134217728; void main() { printf("START\n"); char[] A = new char[bytes]; printf("A\n"); char[] T; T = A; printf("T=A\n"); char[] B = new char[bytes]; printf("B\n"); A = B; printf("A=B\n"); B = T; printf("B=T\n"); printf("END\n"); } The duration of the pauses shows what is happening. So... I was not all that happy. I had to go and carefully step through the "test.d" code you gave at the top of this post, before I was satisfied that I understood what was happening. I think part of my problem was that I did not expect something like A = "car" to work as it does. I understand now that in D, "car" becomes a new character array (can I say an anonymous one in current context?) and A is then pointed at it, rather than the *contents* being altered. This had the effect of making me go back to the start and trying to figure out why I didn't pick up on it in the first place. After all, once it falls into place, it's clear as crystal, logical, and simple. So why did I just "not get it" for so long? Well, if I can try and pass the buck slightly... <g> excessive programming in PHP over the past two years have gotten me used to the way PHP does things like this. I find that every time I go back to C for something, there is a harsh jarring in my head as my brain resets to "C-mode" ;) So I think that because of some of the things D does differently to C/C++, I was kind of expecting some things to be a bit like PHP. My bad. Woopsy! Another issue was that when I read the documentation, I read this: "There are two broad kinds of operations to do on an array - affecting the handle to the array, and affecting the contents of the array. C only has operators to affect the handle. In D, both are accessible." ...and didn't quite realise the scope of what it meant. More careful study reveals, in light of our discussions, the answer that I was looking for waaaaay back at the start of this. Here's my summary: A = B I would love to say that if someone had said at the beginning that "A = B copies by reference whereas to copy the data you need to slice" then I would have been "oh, ok that's great" but although no-one seems to have specifically mentioned slicing to copy, I also realise I just missed that whole thing completely. So... it seems like I started out with a miscomprehension about the way D did this. Because I was uncertain, I asked a question. Because I was ignorant, I asked the question in such a way as to apparently make no sense <g>. Because of that, a debate over methodology evolved, in which both sides were correct about the underlying fundamentals of what was happening, except I was not applying my theory to D correctly because I had no idea how D did it... hence my question in the first place :D Messy! Well, I got there in the end, and I must say, thanks for your time and efforts in enlightening me. I'm sure that I must by now have given you the impression that I'm terribly thick, but I'm kinda used to making blunders by now :) Right, so, to answer my original question: "No swap method is needed, because using a temporary variable will swap the pointers. To make a copy, do so by slicing the array." Now that I have the second part of that answer to join to the first, it makes sense, and I am happy!
Jul 01 2004
"Dan Williams" <dnews ithium.NOSPAM.net> escribió en el mensaje news:cc0oro$kan$1 digitaldaemon.com | | ... | | Right, so, to answer my original question: "No swap method is needed, | because using a temporary variable will swap the pointers. To make a copy, | do so by slicing the array." Now that I have the second part of that answer | to join to the first, it makes sense, and I am happy! Or use the .dup property ----------------------- Carlos Santander Bernal
Jul 01 2004
Dan Williams wrote:I think part of my problem was that I did not expect something like A = "car" to work as it does. I understand now that in D, "car" becomes a new character array (can I say an anonymous one in current context?) and A is then pointed at it, rather than the *contents* being altered.You might have been confused by the fact that in D, we write: str = "dan" Rather than: str = new "dan" /* not real code */ Is this a flaw in the language? I don't know, but you quickly get used to it. James McComb
Jul 01 2004
"James McComb" <alan jamesmccomb.id.au> wrote in message news:cc26dl$2u2m$1 digitaldaemon.com...Dan Williams wrote:newI think part of my problem was that I did not expect something like A = "car" to work as it does. I understand now that in D, "car" becomes aischaracter array (can I say an anonymous one in current context?) and AThat's a good way of putting it actually :)then pointed at it, rather than the *contents* being altered.You might have been confused by the fact that in D, we write: str = "dan" Rather than: str = new "dan" /* not real code */Is this a flaw in the language? I don't know, but you quickly get used to it.I don't know whether I would call it a flaw... but I think that maybe the online docs need fleshing out ;)
Jul 01 2004
On Thu, 1 Jul 2004 01:03:02 +0100, Dan Williams wrote:"Derek" <derek psyc.ward> wrote in message news:1txb3s0xe4h7a$.oc6ijhdctn5l.dlg 40tude.net...You didn't actually try this code out, did you? You are just guessing, I suppose. Okay, here is ACTUAL code that I compiled and ran... #char[] A = "first"; #char[] B = "second"; #void main() And here is the results... c:\>dmd test C:\DPARNELL\DMD\BIN\..\..\dm\bin\link.exe test,,,user32+kernel32/noi; c:\>test 1 A='first' B='second' T='' 2 A='car' B='first' T='first' c:\> As you can PLAINLY see, 'B' does not equal "car", but "first" as I suggested would happen.On Wed, 30 Jun 2004 17:19:17 +0100, Dan Williams wrote:itHmmmm...[snip]The second thing was talking about element swapping, and for some reasonsurewould appear that I'm still not quite being understood on this :( (notandwhy, as it is pretty fundamental stuff).Okay, I'll have a go at describing D's swap behaviour... #char[] A = "first"; #char[] B = "second"; #void main() Using the code example above... Initially 'A' takes up a single two-32-bit area of RAM. Let's say A is located at RAM Address (RA) 1000. And likewise, B is at 2060. The first 32-bit portion of what makes up A's content has the string length of 5,B's first 32-bit area contains 6 (the length of 'second'). The second 32-bit area of A contains the address of the bytes that make up theliteral'first'. Let's say this is RA 4016. B's string pointer also points to its data 'second'. Let's say it is at 5012.So far, so good... I understand and agree with that, and it is what I would expect.So summarizing... A --> [5,4016] B --> [6,5012] Now we have T which has no initial values. T is located at 7000 and also has a two-32-bit area.Again, agreed.The assignment "T = A" cause T to have the contents [5,4016]. "A = B" cause A to now have the contents [6,5012]. "B = T" causes B to have the contents [5,4016]. So we end up with ...No, no, NO! Gah! ...I'll explain in a minute :DA --> [6,5012] B --> [5,4016] Meanwhile the actual string data has not moved a muscle.There are two, and only two, methods for this. A) The string data itself is copied B) The pointer is copied Now, B) is the method I want to use... and is also the method you have *described*, but *NOT* the method that would actually take place in the code example you have provided.This code will copy the string data, not the pointer! Stop, step back, think about it for a minute. What happens if you do this:OK? Yes? That's the way it should be; all is well. BUT if what you are saying is true:Uh-oh! Oh dear! Not what we wanted! Why has this happened?Because, in your example:Well that turns out not to be the case, Dan. Let me run through it... D is truely copying pointers (and lengths) and not the data being pointed to.The assignment "T = A" cause T to have the contents [5,4016]. "A = B" cause A to now have the contents [6,5012]. "B = T" causes B to have the contents [5,4016].So, that means that if part way through we change A, even though we already copied A to T, we are still changing T!The assignment "T = A" cause T to have the contents [5,4016]. "A = B" cause A to now have the contents [6,5012]. "B = T" causes B to have the contents [5,4016].Obviously this is incorrect and flawed, as that is not what assignment does or is supposed to do. Your example did not have anything in it to specify that a reference should be used, so in that case a copy should be made. Just like passing by reference or by value etc.Dan, please try out this in real code. You are presupposing that D behaves a certain way without actually testing your hypothesis. Set up some tests for yourself to see what D is really doing. Have a look at the generated machine code to verify this if you like.So... the strings DO move around in memory if you copy in this way - they must do, they have to do so, otherwise the language would not make any sense. If everything was assigned by reference when you do a simple a = b then how would you make copies?Believe it or not, this is how D works. void main() { char[] A = "test"; char[] B = A; // Both A and B print out as "test" printf("A='%.*s' B='%.*s'\n", A, B); A[2] = 'x'; // Both A and B print out as "text", even though we only 'changed' A! printf("A='%.*s' B='%.*s'\n", A, B); A = "test"; B = A.dup; // <<<<< NOTICE the .dup to make a copy. // Both A and B print out as "test" printf("A='%.*s' B='%.*s'\n", A, B); A[2] = 'x'; // Now A is "text" and B is still "test" printf("A='%.*s' B='%.*s'\n", A, B); }I know that one can utilise pointers in D, and I haven't actually looked too deeply into that for two reasons: first, I hate pointers <g> and second, D seems geared up so that you shouldn't really have to use pointers. This is why I started asking about a swap method, although thinking about it, maybe it would be good to have simply as a standalone function and not as a dedicated array method. It's late for me right now (1am) but if I get chance tomorrow, I will look into how D deals with pointers, and write a test case to demonstrate the two different methods.Hopefully a goodnight's sleep will help. -- Derek Melbourne, Australia 1/Jul/04 10:57:42 AM
Jun 30 2004
"Derek Parnell" <derek psych.ward> wrote in message news:cbvoiv$21tu$1 digitaldaemon.com...On Thu, 1 Jul 2004 01:03:02 +0100, Dan Williams wrote:reason"Derek" <derek psyc.ward> wrote in message news:1txb3s0xe4h7a$.oc6ijhdctn5l.dlg 40tude.net...On Wed, 30 Jun 2004 17:19:17 +0100, Dan Williams wrote:Hmmmm...[snip]The second thing was talking about element swapping, and for someitsitsurewould appear that I'm still not quite being understood on this :( (notandwhy, as it is pretty fundamental stuff).Okay, I'll have a go at describing D's swap behaviour... #char[] A = "first"; #char[] B = "second"; #void main() Using the code example above... Initially 'A' takes up a single two-32-bit area of RAM. Let's say A is located at RAM Address (RA) 1000. And likewise, B is at 2060. The first 32-bit portion of what makes up A's content has the string length of 5,B's first 32-bit area contains 6 (the length of 'second'). The second 32-bit area of A contains the address of the bytes that make up theliteral'first'. Let's say this is RA 4016. B's string pointer also points towoulddata 'second'. Let's say it is at 5012.So far, so good... I understand and agree with that, and it is what Ialsoexpect.So summarizing... A --> [5,4016] B --> [6,5012] Now we have T which has no initial values. T is located at 7000 andcodehas a two-32-bit area.Again, agreed.The assignment "T = A" cause T to have the contents [5,4016]. "A = B" cause A to now have the contents [6,5012]. "B = T" causes B to have the contents [5,4016]. So we end up with ...No, no, NO! Gah! ...I'll explain in a minute :DA --> [6,5012] B --> [5,4016] Meanwhile the actual string data has not moved a muscle.There are two, and only two, methods for this. A) The string data itself is copied B) The pointer is copied Now, B) is the method I want to use... and is also the method you have *described*, but *NOT* the method that would actually take place in thethinkexample you have provided.This code will copy the string data, not the pointer! Stop, step back,alreadyabout it for a minute. What happens if you do this:You didn't actually try this code out, did you? You are just guessing, I suppose. Okay, here is ACTUAL code that I compiled and ran... #char[] A = "first"; #char[] B = "second"; #void main() And here is the results... c:\>dmd test C:\DPARNELL\DMD\BIN\..\..\dm\bin\link.exe test,,,user32+kernel32/noi; c:\>test 1 A='first' B='second' T='' 2 A='car' B='first' T='first' c:\> As you can PLAINLY see, 'B' does not equal "car", but "first" as I suggested would happen.OK? Yes? That's the way it should be; all is well. BUT if what you are saying is true:Uh-oh! Oh dear! Not what we wanted! Why has this happened?Because, in your example:The assignment "T = A" cause T to have the contents [5,4016]. "A = B" cause A to now have the contents [6,5012]. "B = T" causes B to have the contents [5,4016].So, that means that if part way through we change A, even though webecopied A to T, we are still changing T!Well that turns out not to be the case, Dan. Let me run through it... D is truely copying pointers (and lengths) and not the data being pointed to.The assignment "T = A" cause T to have the contents [5,4016]. "A = B" cause A to now have the contents [6,5012]. "B = T" causes B to have the contents [5,4016].Obviously this is incorrect and flawed, as that is not what assignment does or is supposed to do. Your example did not have anything in it to specify that a reference shouldreferenceused, so in that case a copy should be made. Just like passing bytheyor by value etc.Dan, please try out this in real code. You are presupposing that D behaves a certain way without actually testing your hypothesis. Set up some tests for yourself to see what D is really doing. Have a look at the generated machine code to verify this if you like.So... the strings DO move around in memory if you copy in this way -bmust do, they have to do so, otherwise the language would not make any sense. If everything was assigned by reference when you do a simple a =toothen how would you make copies?Believe it or not, this is how D works. void main() { char[] A = "test"; char[] B = A; // Both A and B print out as "test" printf("A='%.*s' B='%.*s'\n", A, B); A[2] = 'x'; // Both A and B print out as "text", even though we only 'changed' A! printf("A='%.*s' B='%.*s'\n", A, B); A = "test"; B = A.dup; // <<<<< NOTICE the .dup to make a copy. // Both A and B print out as "test" printf("A='%.*s' B='%.*s'\n", A, B); A[2] = 'x'; // Now A is "text" and B is still "test" printf("A='%.*s' B='%.*s'\n", A, B); }I know that one can utilise pointers in D, and I haven't actually lookedDdeeply into that for two reasons: first, I hate pointers <g> and second,isseems geared up so that you shouldn't really have to use pointers. Thismaybewhy I started asking about a swap method, although thinking about it,lookit would be good to have simply as a standalone function and not as a dedicated array method. It's late for me right now (1am) but if I get chance tomorrow, I willtwointo how D deals with pointers, and write a test case to demonstrate theIt sure did - I carefully went through the code examples this morning, and finally twigged it! :D Although, please have the grace to let me point this out:different methods.Hopefully a goodnight's sleep will help.If you (or anyone else) had answered me regarding how to make copies in D (by slicing) then chances are that I would have understood a few posts ago :) But as to what those chances are, I would not like to say... <g> Thanks for your patience with this old fool!If everything was assigned by reference when you do a simple a = b then how would you make copies?Believe it or not, this is how D works.
Jul 01 2004
On Thu, 1 Jul 2004 11:31:34 +0100, Dan Williams wrote: [snip]G'day, mate. Great news! I too was a bit confused by D's assignment semantics at first. But you eventually get used to it. It's sort of makes sense. In most languages assignment means copying the value of the righthand side expression to the variable on the left hand side. So naturally if we are talking strings (arrays of chars?) we think that the string data is being copied. But of course, D does actually copy the value, but in its case, the value is not the string data, but the string reference. I work with a language that does similar to D, but it does an automatic deep copy if you modify the contents. For example... A = "abc"; B = A; // Copies the string reference A[0] = 'A'; // Recognizes that the base data is being changed // so it copies the data, updates A's reference to // the new copy and then updates the first element. This has overheads that D wishes to avoid, but its nice anyhow.Hopefully a goodnight's sleep will help.It sure did - I carefully went through the code examples this morning, and finally twigged it! :DAlthough, please have the grace to let me point this out:Hmmmm...don't follow you here. What do you mean by copying by slicing? Can you given a code example? Here is what I tried and there was no copying done... #void main() the results were ... f:\temp>dmd test F:\DMD\BIN\..\..\dm\bin\link.exe test,,,user32+kernel32/noi; f:\temp>test A='fIrst' T='Ir' f:\temp> As you can see, the "T = A[1..3]" did not take a copy of the underlying array, but just made T point into the same RAM block that A was pointing to.If you (or anyone else) had answered me regarding how to make copies in D (by slicing) then chances are that I would have understood a few posts ago :) But as to what those chances are, I would not like to say... <g>If everything was assigned by reference when you do a simple a = b then how would you make copies?Believe it or not, this is how D works.Thanks for your patience with this old fool!As a friend keeps reminding me, the only stupid question is one that is never asked. -- Derek Melbourne, Australia
Jul 01 2004
"Derek" <derek psyc.ward> wrote in message news:10fi5ofl3p0yj.1icwu3beyyn63$.dlg 40tude.net...On Thu, 1 Jul 2004 11:31:34 +0100, Dan Williams wrote: [snip]andHopefully a goodnight's sleep will help.It sure did - I carefully went through the code examples this morning,Yup, that's were I came unstuck.finally twigged it! :DG'day, mate. Great news! I too was a bit confused by D's assignment semantics at first. But you eventually get used to it. It's sort of makes sense. In most languages assignment means copying the value of the righthand side expression to the variable on the left hand side. So naturally if we are talking strings (arrays of chars?) we think that the string data is being copied.But of course, D does actually copy the value, but in its case, the value is not the string data, but the string reference. I work with a language that does similar to D, but it does an automatic deep copy if you modify the contents. For example... A = "abc"; B = A; // Copies the string reference A[0] = 'A'; // Recognizes that the base data is being changed // so it copies the data, updates A's reference to // the new copy and then updates the first element. This has overheads that D wishes to avoid, but its nice anyhow.DAlthough, please have the grace to let me point this out:If you (or anyone else) had answered me regarding how to make copies inIf everything was assigned by reference when you do a simple a = b then how would you make copies?Believe it or not, this is how D works.ago(by slicing) then chances are that I would have understood a few postsSure! This is simply copied (no pun intended! <g>) straight from http://www.digitalmars.com/d/arrays.html Array Copying When the slice operator appears as the lvalue of an assignment expression, it means that the contents of the array are the target of the assignment rather than a reference to the array. Array copying happens when the lvalue is a slice, and the rvalue is an array of or pointer to the same type. int[3] s; int[3] t; s[] = t; the 3 elements of t[3] are copied into s[3] s[] = t[]; the 3 elements of t[3] are copied into s[3]:) But as to what those chances are, I would not like to say... <g>Hmmmm...don't follow you here. What do you mean by copying by slicing? Can you given a code example?Here is what I tried and there was no copying done... #void main() the results were ... f:\temp>dmd test F:\DMD\BIN\..\..\dm\bin\link.exe test,,,user32+kernel32/noi; f:\temp>test A='fIrst' T='Ir' f:\temp> As you can see, the "T = A[1..3]" did not take a copy of the underlying array, but just made T point into the same RAM block that A was pointing to.Indeed, it would appear (as I think I noted in another post in another branch of this thread) that the array is only copied if the slicing operator is on the left side. So: s = t[]; // points s[] = t; // copies s[] = t[]; // copies So that's what I would guess the problem is with your T = A[1..3] example. Interesting, because I didn't really think about the logical extension of the method, but from what you did it is apparent that: s = t[a..b] // points to the sliced sectionI like the sound of that - it lets me off the hook! ;)Thanks for your patience with this old fool!As a friend keeps reminding me, the only stupid question is one that is never asked.
Jul 01 2004
On Wed, 30 Jun 2004 11:03:42 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:char[][100] list;I think I see what you mean. An array itself is a struct with length n where n is both the count of the elements and also the amount of memory used by the sequentially-stored pointers to element data, yes? And each element then holds its own data with its own data properties. Ok, that makes sense, and this is essentially the way I would handle it in C++. The place that I came unstuck is in asking about element swapping. Let me explain that one further, so that you'll have a clearer idea of my question. Take an array with 100 elements, where each element is a variable-length string.Surely there are pointers to the actual elements somewhere? Or are you using a method that I am simply not thinking of right now... (gone 2am, tired!)The data member points to the elements. They are stored sequentially in memory.When it comes to sort the array, obviously the best method is to swap the data pointers after a comparison, rather than swap the data itself. Now, this is why I asked about a swap method - there are several things that I would need to utilise a swap for, and obviously I want to be confident that I am swapping the pointers and not the data! As there is no swap method, how would I directly access the array index's data pointers in order to swap them? Imagine that elements 5 and 9 need swapping, and are around about 1Kb each. If I say, temp = myArray[5]; myArray[5] = myArray[9]; myArray[9] = temp; then I am needlessly copying 1Kb blocks around in memory, right?It depends on the array. Using the array: char[][100] list; If you swap list[5] with list[9] you're swapping array references, not the data they point to. Here is a test case which prooves this (I believe): import std.random; void main() { char[][100] a; char[] test; //create 100 random char[] of 1000 chars foreach(inout char[] s; a) { s.length = 1000; for(uint i = 0; i < s.length; i++) s[i] = 'a' + rand()&25; } //pick one as a test case test = a[0]; //print the location and address of the first element printf("%02d. %08x\n",0,&test[0]); //sort the array a.sort; //find the test case foreach(uint i, char[] s; a) { if (s == test) { //print the location and address of the first element printf("%02d. %08x\n",i,&s[0]); break; } } } If the array is an array of pointers eg. char*[100] list; then swapping list[5] with list[9] you're swapping pointer, so again you're not swapping 1k of data. But, if you use: Foo[100] list; and Foo is a 1k large structure, then yes, you're swapping 1k of data. The same does not apply if Foo is a 1k class, because classes are handled by reference so you're swaping references to 1k classes, not the 1k classes themselves. Basically if it's a reference type, you're fine, if it's a value type, your swapping (the size of the value type)k each time. Is that clear as mud? If I'm wrong someone pls correct me.So I need to be able to swap the pointers and therefore temp needs to be a pointer, but while this is straightforward in C++, I don't know how I would do this in D. Therefore my ignorance when it comes to D has prompted what has undoubtably appeared to be a rather stupid question <g>Whatever you would do in C++ you can still do in D, but, D's arrays give you a better way to do it. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 30 2004
In article <opsafkvvct5a2sq9 digitalmars.com>, Regan Heath says...Really? This does kind of make sense, because it's a hundred of n of char. But then how do you get the 50th string? list[50]? list[][50]? Surely the indexes are in the same order as the dimensions. I thought I understood this :'( SamTake an array with 100 elements, where each element is a variable-length string.char[][100] list;
Jun 30 2004
On Wed, 30 Jun 2004 23:47:56 +0000 (UTC), Sam McCall <Sam_member pathlink.com> wrote:In article <opsafkvvct5a2sq9 digitalmars.com>, Regan Heath says...I believe so. My test program uses it.Really?Take an array with 100 elements, where each element is a variable-length string.char[][100] list;This does kind of make sense, because it's a hundred of n of char.I thought so too. :)But then how do you get the 50th string? list[50]?Yep.list[][50]? Surely the indexes are in the same order as the dimensions.They are, see the 'catch' below :)I thought I understood this :'(I think the 'catch' here is this.. arrays are defined with "TYPE[] NAME" the TYPE can be an array, in my example above the TYPE is char[]. It can all start to get really, really funky.. char[][char[int]] list; an associative array of char arrays, indexed by an associative array of chars indexed by an int. etc.. and this is a simple example of funky. Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 30 2004
In article <opsafm5lh55a2sq9 digitalmars.com>, Regan Heath says...On Wed, 30 Jun 2004 23:47:56 +0000 (UTC), Sam McCall <Sam_member pathlink.com> wrote:No they're not. If I have a hundred strings, defined as char[][100] list And I want to access the nth one, you say I should use list[n]. So if I want the k-th char of the n-th string, clearly i use list[n][k] So I'm defining with char[number-of-chars][number-of-strings] list And accessing with list[string-number][char-number]. In particular, the range of the first index is determined by the second dimension, and vice versa. This runs counter to my intuition. SamIn article <opsafkvvct5a2sq9 digitalmars.com>, Regan Heath says...I believe so. My test program uses it.Really?Take an array with 100 elements, where each element is a variable-length string.char[][100] list;This does kind of make sense, because it's a hundred of n of char.I thought so too. :)But then how do you get the 50th string? list[50]?Yep.list[][50]? Surely the indexes are in the same order as the dimensions.They are, see the 'catch' below :)
Jun 30 2004
On Thu, 1 Jul 2004 00:51:24 +0000 (UTC), Sam McCall <Sam_member pathlink.com> wrote:In article <opsafm5lh55a2sq9 digitalmars.com>, Regan Heath says...Yep.On Wed, 30 Jun 2004 23:47:56 +0000 (UTC), Sam McCall <Sam_member pathlink.com> wrote:No they're not. If I have a hundred strings, defined as char[][100] list And I want to access the nth one, you say I should use list[n].In article <opsafkvvct5a2sq9 digitalmars.com>, Regan Heath says...I believe so. My test program uses it.Really?Take an array with 100 elements, where each element is a variable-length string.char[][100] list;This does kind of make sense, because it's a hundred of n of char.I thought so too. :)But then how do you get the 50th string? list[50]?Yep.list[][50]? Surely the indexes are in the same order as the dimensions.They are, see the 'catch' below :)So if I want the k-th char of the n-th string, clearly i use list[n][k]Yep. You're right they go backwards.So I'm defining with char[number-of-chars][number-of-strings] list And accessing with list[string-number][char-number]. In particular, the range of the first index is determined by the second dimension, and vice versa. This runs counter to my intuition.It makes sense to me, the first index, indexes a char[][] meaning you get a char[] back, the second index indexes a char[] meaning you get a char back. Conceptually I break it up into these steps in my head. given: char[][100] list; char c; c = list[5][9]; I think: char[][100] list; char[] p; char c; p = list[5]; c = p[9]; Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 30 2004
Regan Heath wrote:On Thu, 1 Jul 2004 00:51:24 +0000 (UTC), Sam McCall <Sam_member pathlink.com> wrote:Yes, yes, I get all that, but the _indices_ are _backwards_. Java certainly doesn't do it this way, do other languages? SamIn article <opsafm5lh55a2sq9 digitalmars.com>, Regan Heath says...Yep.On Wed, 30 Jun 2004 23:47:56 +0000 (UTC), Sam McCall <Sam_member pathlink.com> wrote:No they're not. If I have a hundred strings, defined as char[][100] list And I want to access the nth one, you say I should use list[n].In article <opsafkvvct5a2sq9 digitalmars.com>, Regan Heath says...I believe so. My test program uses it.Really?Take an array with 100 elements, where each element is a variable-length string.char[][100] list;This does kind of make sense, because it's a hundred of n of char.I thought so too. :)But then how do you get the 50th string? list[50]?Yep.list[][50]? Surely the indexes are in the same order as the dimensions.They are, see the 'catch' below :)So if I want the k-th char of the n-th string, clearly i use list[n][k]Yep. You're right they go backwards.So I'm defining with char[number-of-chars][number-of-strings] list And accessing with list[string-number][char-number]. In particular, the range of the first index is determined by the second dimension, and vice versa. This runs counter to my intuition.It makes sense to me, the first index, indexes a char[][] meaning you get a char[] back, the second index indexes a char[] meaning you get a char back. Conceptually I break it up into these steps in my head.
Jul 01 2004
"Sam McCall" <tunah.d tunah.net> wrote in message news:cc0qeq$m0u$1 digitaldaemon.com...Regan Heath wrote:I'm with Sam on this one... it appears confusing to reverse the order. I certainly would have run into problems with this at some point if his posts had not brought it to my attention.On Thu, 1 Jul 2004 00:51:24 +0000 (UTC), Sam McCall <Sam_member pathlink.com> wrote:Yes, yes, I get all that, but the _indices_ are _backwards_. Java certainly doesn't do it this way, do other languages? SamIn article <opsafm5lh55a2sq9 digitalmars.com>, Regan Heath says...Yep.On Wed, 30 Jun 2004 23:47:56 +0000 (UTC), Sam McCall <Sam_member pathlink.com> wrote:No they're not. If I have a hundred strings, defined as char[][100] list And I want to access the nth one, you say I should use list[n].In article <opsafkvvct5a2sq9 digitalmars.com>, Regan Heath says...I believe so. My test program uses it.Really?Take an array with 100 elements, where each element is a variable-length string.char[][100] list;This does kind of make sense, because it's a hundred of n of char.I thought so too. :)But then how do you get the 50th string? list[50]?Yep.list[][50]? Surely the indexes are in the same order as the dimensions.They are, see the 'catch' below :)So if I want the k-th char of the n-th string, clearly i use list[n][k]Yep. You're right they go backwards.So I'm defining with char[number-of-chars][number-of-strings] list And accessing with list[string-number][char-number]. In particular, the range of the first index is determined by the second dimension, and vice versa. This runs counter to my intuition.It makes sense to me, the first index, indexes a char[][] meaning you get a char[] back, the second index indexes a char[] meaning you get a char back. Conceptually I break it up into these steps in my head.
Jul 01 2004
On Thu, 01 Jul 2004 22:56:01 +1200, Sam McCall <tunah.d tunah.net> wrote:Regan Heath wrote:See "Norbert Nemec"'s post. he explains it well. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/On Thu, 1 Jul 2004 00:51:24 +0000 (UTC), Sam McCall <Sam_member pathlink.com> wrote:Yes, yes, I get all that, but the _indices_ are _backwards_. Java certainly doesn't do it this way, do other languages?In article <opsafm5lh55a2sq9 digitalmars.com>, Regan Heath says...Yep.On Wed, 30 Jun 2004 23:47:56 +0000 (UTC), Sam McCall <Sam_member pathlink.com> wrote:No they're not. If I have a hundred strings, defined as char[][100] list And I want to access the nth one, you say I should use list[n].In article <opsafkvvct5a2sq9 digitalmars.com>, Regan Heath says...I believe so. My test program uses it.Really?Take an array with 100 elements, where each element is a variable-length string.char[][100] list;This does kind of make sense, because it's a hundred of n of char.I thought so too. :)But then how do you get the 50th string? list[50]?Yep.list[][50]? Surely the indexes are in the same order as the dimensions.They are, see the 'catch' below :)So if I want the k-th char of the n-th string, clearly i use list[n][k]Yep. You're right they go backwards.So I'm defining with char[number-of-chars][number-of-strings] list And accessing with list[string-number][char-number]. In particular, the range of the first index is determined by the second dimension, and vice versa. This runs counter to my intuition.It makes sense to me, the first index, indexes a char[][] meaning you get a char[] back, the second index indexes a char[] meaning you get a char back. Conceptually I break it up into these steps in my head.
Jul 01 2004
Sam McCall wrote:In article <opsafkvvct5a2sq9 digitalmars.com>, Regan Heath says...Careful: in nested arrays, the type declaration looks the other way around from the indexing operator: int[C][R] x; int sum = 0; for(int r=0;r<R;r++) for(int c=0;c<C;c++) sum += x[r][c]; To see the background for this, think of a typedef: typedef int[C] intC; intC[R] x; for(int r=0;r<R;r++) { intC row = x[r]; for(int c=0;c<C;c++) sum += row[c]; } This is a strange quirk that appeared when C-style array specifiers were shuffled from behind the variable name to the variable type: C-style: int x[R][C]; intermediate: int[C] x[R]; D-style: int[C][R] x; The strangeness will be possible to avoid in future by using the multidimensional static arrays (a minor part of the proposal): int[R,C] y; int sum = 0; for(int r=0;r<R;r++) for(int c=0;c<C;c++) sum += x[r,c];Really? This does kind of make sense, because it's a hundred of n of char. But then how do you get the 50th string? list[50]? list[][50]? Surely the indexes are in the same order as the dimensions. I thought I understood this :'( SamTake an array with 100 elements, where each element is a variable-length string.char[][100] list;
Jul 01 2004
"Regan Heath" <regan netwin.co.nz> wrote in message news:opsafkvvct5a2sq9 digitalmars.com...On Wed, 30 Jun 2004 11:03:42 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:youSurely there are pointers to the actual elements somewhere? Or arebyI think I see what you mean. An array itself is a struct with length n where n is both the count of the elements and also the amount of memory usedusing a method that I am simply not thinking of right now... (gone 2am, tired!)The data member points to the elements. They are stored sequentially in memory.index'sthe sequentially-stored pointers to element data, yes? And each element then holds its own data with its own data properties. Ok, that makes sense, and this is essentially the way I would handle it in C++. The place that I came unstuck is in asking about element swapping. Let me explain that one further, so that you'll have a clearer idea of my question. Take an array with 100 elements, where each element is a variable-length string.char[][100] list;When it comes to sort the array, obviously the best method is to swap the data pointers after a comparison, rather than swap the data itself. Now, this is why I asked about a swap method - there are several things that I would need to utilise a swap for, and obviously I want to be confident that I am swapping the pointers and not the data! As there is no swap method, how would I directly access the arrayNow THAT is starting to get somewhere :) Looks like you can see what I am on about... I thought I was going mad, out here on my own! <g> Ok, your test case is nice, but it is not very convincing to me. In my view, it simply proves that the *in-built* sort method does what it should do, and swaps the pointers not the data; i.e. the pointer remains the same but has moved to a different position in the array. What you go on to say about the large data structure Foo and also about the array of pointers is, as far as I am concerned, totally correct and totally clear. *BUT* there is still something outstanding! ...how to swap the elements (or, forgetting about arrays, any same-type entities for that matter) and make sure that the pointers are getting swapped and not the data. So, in the case of a normal array (i.e. char[] not char*[]), I would like to know how to correctly swap the pointers, and similarly for large structure Foo I would like to do the same. Finally, from your comments I am not sure what the distinction is (is there is one) between what D assigns by reference and by value. If a and b are of type int, does a = b assign by value? The answer would appear to be obvious: yes. How about class instances A and B though? In this case, are you saying that A = B makes a reference to B and that therefore setting B.z would reflect in A.z? In which case what is the D method to copy a class instance? And surely arrays must be assigned by value just like integers, otherwise: a="x"; b="y"; t=a; a="z"; b=t; would end up with b being "z" and not "x". When I first asked about the swapping, I never thought it would be debated so much! Because I don't know much about D (2 days playing with it so far) I am trying to establish the correct ways to do things in it at the start, rather than discovering at a later date that I had reinvented the wheel or missed something important. Maybe I should go and make a swap function first, and then come back and discuss it further. But that will have to wait until tomorrow; I'll try and find some time to do it then.data pointers in order to swap them? Imagine that elements 5 and 9 need swapping, and are around about 1Kb each. If I say, temp = myArray[5]; myArray[5] = myArray[9]; myArray[9] = temp; then I am needlessly copying 1Kb blocks around in memory, right?It depends on the array. Using the array: char[][100] list; If you swap list[5] with list[9] you're swapping array references, not the data they point to. Here is a test case which prooves this (I believe): import std.random; void main() { char[][100] a; char[] test; //create 100 random char[] of 1000 chars foreach(inout char[] s; a) { s.length = 1000; for(uint i = 0; i < s.length; i++) s[i] = 'a' + rand()&25; } //pick one as a test case test = a[0]; //print the location and address of the first element printf("%02d. %08x\n",0,&test[0]); //sort the array a.sort; //find the test case foreach(uint i, char[] s; a) { if (s == test) { //print the location and address of the first element printf("%02d. %08x\n",i,&s[0]); break; } } } If the array is an array of pointers eg. char*[100] list; then swapping list[5] with list[9] you're swapping pointer, so again you're not swapping 1k of data. But, if you use: Foo[100] list; and Foo is a 1k large structure, then yes, you're swapping 1k of data. The same does not apply if Foo is a 1k class, because classes are handled by reference so you're swaping references to 1k classes, not the 1k classes themselves. Basically if it's a reference type, you're fine, if it's a value type, your swapping (the size of the value type)k each time. Is that clear as mud? If I'm wrong someone pls correct me.So I need to be able to swap the pointers and therefore temp needs to be a pointer, but while this is straightforward in C++, I don't know how I would do this in D. Therefore my ignorance when it comes to D has prompted what has undoubtably appeared to be a rather stupid question <g>Whatever you would do in C++ you can still do in D, but, D's arrays give you a better way to do it. Regan
Jun 30 2004
On Thu, 1 Jul 2004 01:23:38 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:"Regan Heath" <regan netwin.co.nz> wrote in message news:opsafkvvct5a2sq9 digitalmars.com...I get that feeling sometimes too.. sometimes I wonder if they do it on purpose.On Wed, 30 Jun 2004 11:03:42 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:youSurely there are pointers to the actual elements somewhere? Or arebyinusing a method that I am simply not thinking of right now... (gone 2am, tired!)The data member points to the elements. They are stored sequentiallymemory.I think I see what you mean. An array itself is a struct with length n where n is both the count of the elements and also the amount of memory usedindex'sthe sequentially-stored pointers to element data, yes? And eachelementthen holds its own data with its own data properties. Ok, that makes sense, and this is essentially the way I would handle it in C++. The place that I came unstuck is in asking about element swapping. Let me explain that one further, so that you'll have a clearer idea of my question. Take an array with 100 elements, where each element is avariable-lengthstring.char[][100] list;When it comes to sort the array, obviously the best method is to swap the data pointers after a comparison, rather than swap the data itself. Now, this is why I asked about a swap method - there are severalthingsthat I would need to utilise a swap for, and obviously I want to beconfidentthat I am swapping the pointers and not the data! As there is no swap method, how would I directly access the arrayNow THAT is starting to get somewhere :) Looks like you can see what I am on about... I thought I was going mad, out here on my own! <g>data pointers in order to swap them? Imagine that elements 5 and 9needswapping, and are around about 1Kb each. If I say, temp = myArray[5]; myArray[5] = myArray[9]; myArray[9] = temp; then I am needlesslycopying1Kb blocks around in memory, right?It depends on the array. Using the array: char[][100] list; If you swap list[5] with list[9] you're swapping array references, not the data they point to. Here is a test case which prooves this (I believe): import std.random; void main() { char[][100] a; char[] test; //create 100 random char[] of 1000 chars foreach(inout char[] s; a) { s.length = 1000; for(uint i = 0; i < s.length; i++) s[i] = 'a' + rand()&25; } //pick one as a test case test = a[0]; //print the location and address of the first element printf("%02d. %08x\n",0,&test[0]); //sort the array a.sort; //find the test case foreach(uint i, char[] s; a) { if (s == test) { //print the location and address of the first element printf("%02d. %08x\n",i,&s[0]); break; } } } If the array is an array of pointers eg. char*[100] list; then swapping list[5] with list[9] you're swapping pointer, so again you're not swapping 1k of data. But, if you use: Foo[100] list; and Foo is a 1k large structure, then yes, you're swapping 1k of data. The same does not apply if Foo is a 1k class, because classes are handled by reference so you're swaping references to 1k classes, not the 1k classes themselves. Basically if it's a reference type, you're fine, if it's a value type, your swapping (the size of the value type)k each time. Is that clear as mud? If I'm wrong someone pls correct me.So I need to be able to swap the pointers and therefore temp needs to be a pointer, but while this is straightforward in C++, I don't know how I would do this in D. Therefore my ignorance when it comes to D has prompted what has undoubtably appeared to be aratherstupid question <g>Whatever you would do in C++ you can still do in D, but, D's arrays give you a better way to do it. ReganOk, your test case is nice, but it is not very convincing to me. In my view, it simply proves that the *in-built* sort method does what it should do, and swaps the pointers not the data; i.e. the pointer remains the same but has moved to a different position in the array. What you go on to say about the large data structure Foo and also about the array of pointers is, as far as I am concerned, totally correct and totally clear.Whew.*BUT* there is still something outstanding! ...how to swap the elements (or, forgetting about arrays, any same-type entities for that matter) and make sure that the pointers are getting swapped and not the data. So, in the case of a normal array (i.e. char[] not char*[]), I would like to know how to correctly swap the pointers, and similarly for large structure Foo I would like to do the same.With char[] I think my latest example prooves the data is not copied.Finally, from your comments I am not sure what the distinction is (is there is one) between what D assigns by reference and by value. If a and b are of type int, does a = b assign by value? The answer would appear to be obvious: yes.Yes.How about class instances A and B though? In this case, are you saying that A = B makes a reference to B and that therefore setting B.z would reflect in A.z?Yes. Example: class A { this(int _val) { val = _val; } int val; } void main() { A a = new A(1); A b = new A(2); printf("A(%08x)(%d) B(%08x)(%d)\n",&a.val,a.val,&b.val,b.val); b = a; printf("A(%08x)(%d) B(%08x)(%d)\n",&a.val,a.val,&b.val,b.val); b.val = 5; printf("A(%08x)(%d) B(%08x)(%d)\n",&a.val,a.val,&b.val,b.val); b = new A(a.val); printf("A(%08x)(%d) B(%08x)(%d)\n",&a.val,a.val,&b.val,b.val); }In which case what is the D method to copy a class instance?There isn't one, you do it the same as in C++. Either by a copy constructor doing a deep-copy and/or by a method, dup() is a good name for it. eg. class Foo { this(Foo f) { //deep-copy contents of f } Foo dup() { Foo f = new Foo(this); return f; } }And surely arrays must be assigned by value just like integers, otherwise: a="x"; b="y"; t=a; a="z"; b=t; would end up with b being "z" and not "x".When you write "z" D creates a char[] array and assigns "z" to the data pointer. So by going a="z" you create a new array and assign a to it by reference. They also have a built-in dup method i.e. char[] a = "regan"; char[] b; b = a.dup; a and b both contain "regan" but they are not the same "regan" but different ones living in different places in memory.When I first asked about the swapping, I never thought it would be debated so much! Because I don't know much about D (2 days playing with it so far) I am trying to establish the correct ways to do things in it at the start, rather than discovering at a later date that I had reinvented the wheel or missed something important.This is a wise decision IMO.Maybe I should go and make a swap function first, and then come back and discuss it further.I try to try/test everything before I bring it up. It saves time, and potentially embarrassment. That said everyones understanding starts somewhere and IMO you don't learn unless you question.But that will have to wait until tomorrow; I'll try and find some time to do it then.I can't wait :) Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 30 2004
"Regan Heath" <regan netwin.co.nz> wrote in message news:opsafrtctm5a2sq9 digitalmars.com...On Thu, 1 Jul 2004 01:23:38 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote::D so it's not just me then!Now THAT is starting to get somewhere :) Looks like you can see what I am on about... I thought I was going mad, out here on my own! <g>I get that feeling sometimes too.. sometimes I wonder if they do it on purpose.Should there be a clone() method in the core D language? Kinda like PHP5? Or is that another stupid question? :) (Maybe I should not ask questions for a while!)...what is the D method to copy a class instance?There isn't one, you do it the same as in C++. Either by a copy constructor doing a deep-copy and/or by a method, dup() is a good name for it.When you write "z" D creates a char[] array and assigns "z" to the data pointer. So by going a="z" you create a new array and assign a to it by reference. They also have a built-in dup method i.e. char[] a = "regan"; char[] b; b = a.dup; a and b both contain "regan" but they are not the same "regan" but different ones living in different places in memory.Indeed, I finally twigged that. Not sure about the need for dup though... see my other post, doesn't slicing do the same thing? Or does dup do a multi-level copy? (whereas slicing would only copy the outermost array, and subarrays would still point to the same places.) I think I really missed the boat on this one earlier :(Thankyou... however the decision has to be made whether knowledge at the price of embarrassment of ignorance is worth it compared to not asking, not being embarrassed, but maybe not understanding either. In my case, if there is one thing I have learnt, it is how much I don't know, so I've gotten used to being ignorant by now :)When I first asked about the swapping, I never thought it would be debated so much! Because I don't know much about D (2 days playing with it so far) I am trying to establish the correct ways to do things in it at the start, rather than discovering at a later date that I had reinvented the wheel or missed something important.This is a wise decision IMO. I try to try/test everything before I bring it up. It saves time, and potentially embarrassment. That said everyones understanding starts somewhere and IMO you don't learn unless you question.
Jul 01 2004
On Thu, 1 Jul 2004 11:41:46 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote:"Regan Heath" <regan netwin.co.nz> wrote in message news:opsafrtctm5a2sq9 digitalmars.com...If there were a way to query a thing for all its members and if every thing had a copy constructor then this would be possible I reckon.On Thu, 1 Jul 2004 01:23:38 +0100, Dan Williams <dnews ithium.NOSPAM.net> wrote::D so it's not just me then!Now THAT is starting to get somewhere :) Looks like you can see what I am on about... I thought I was going mad, out here on my own! <g>I get that feeling sometimes too.. sometimes I wonder if they do it on purpose.Should there be a clone() method in the core D language? Kinda like PHP5?...what is the D method to copy a class instance?There isn't one, you do it the same as in C++. Either by a copy constructor doing a deep-copy and/or by a method, dup() is a good name for it.Or is that another stupid question? :) (Maybe I should not ask questions for a while!)Nah.. keep em coming, it gives me something to do when I am dodging work.Yes. dup is the same as b[] = a[] I believe.. but not the same as a partial slice i.e. b[0..5] = a[0..5].When you write "z" D creates a char[] array and assigns "z" to the data pointer. So by going a="z" you create a new array and assign a to it by reference. They also have a built-in dup method i.e. char[] a = "regan"; char[] b; b = a.dup; a and b both contain "regan" but they are not the same "regan" but different ones living in different places in memory.Indeed, I finally twigged that. Not sure about the need for dup though... see my other post, doesn't slicing do the same thing?Or does dup do a multi-level copy? (whereas slicing would only copy the outermost array, and subarrays would still point to the same places.)If 'multi-level' is the same as 'deep' copy .. no, dup is only a shallow copy.I think I really missed the boat on this one earlier :(It happens.You'll only suffer the embarrassment once, you'll suffer the ignorance forever. Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/Thankyou... however the decision has to be made whether knowledge at the price of embarrassment of ignorance is worth it compared to not asking, not being embarrassed, but maybe not understanding either. In my case, if there is one thing I have learnt, it is how much I don't know, so I've gotten used to being ignorant by now :)When I first asked about the swapping, I never thought it would be debated so much! Because I don't know much about D (2 days playing with it so far) I am trying to establish the correct ways to do things in it at thestart,rather than discovering at a later date that I had reinvented thewheelor missed something important.This is a wise decision IMO. I try to try/test everything before I bring it up. It saves time, and potentially embarrassment. That said everyones understanding starts somewhere and IMO you don't learn unless you question.
Jul 01 2004
In article <cbsq23$46i$1 digitaldaemon.com>, Walter says...[...]D does need some testimonials from using it in significant projects.I think now it's time for a few commercial questions: - When Digital Mars D development toolkit will be available? - Which commercial formula will be used? How about tech help? - Will it be possible to buy the compiler sources, just in case? [..]What you're talking about are DLLs in Windows and shared libraries under linux. Right now, I prefer things to be statically linked in because that avoids "DLL hell" where versions get mismatched.I see. But what if I want to distribute a bunch of executables forming a complete suite? It would be very useful to have a single shared library with Phobos/Garbage Collector. Ciao
Jun 30 2004
"Roberto Mariottini" <Roberto_member pathlink.com> wrote in message news:cbtq14$1k9r$1 digitaldaemon.com...In article <cbsq23$46i$1 digitaldaemon.com>, Walter says...You can download it now! That's what dmd.zip is.[...]D does need some testimonials from using it in significant projects.I think now it's time for a few commercial questions: - When Digital Mars D development toolkit will be available?- Which commercial formula will be used? How about tech help? - Will it be possible to buy the compiler sources, just in case?Yes.[..]It would save some disk space, that's it.What you're talking about are DLLs in Windows and shared libraries under linux. Right now, I prefer things to be statically linked in because that avoids "DLL hell" where versions get mismatched.I see. But what if I want to distribute a bunch of executables forming a complete suite? It would be very useful to have a single shared library with Phobos/Garbage Collector.
Jun 30 2004
In article <cbttqo$1uio$1 digitaldaemon.com>, Walter says..."Roberto Mariottini" <Roberto_member pathlink.com> wrote in message news:cbtq14$1k9r$1 digitaldaemon.com...[...]I think you missed the point, that is in the next question:- When Digital Mars D development toolkit will be available?You can download it now! That's what dmd.zip is.Sure, I can use the (for now?) freely downloadable tools. But I think that it's easier to persuade my employer to adopt D for a project if behind D there's a company working to solve bugs and improve the toolkit.- Which commercial formula will be used? How about tech help?Good. But this can be oly a parachute, I prefer having a working plane ;-) [...]- Will it be possible to buy the compiler sources, just in case?Yes.And load time, and maybe some memory (depending on the O.S.). I think it's worth. CiaoI see. But what if I want to distribute a bunch of executables forming a complete suite? It would be very useful to have a single shared library with Phobos/Garbage Collector.It would save some disk space, that's it.
Jun 30 2004
"Roberto Mariottini" <Roberto_member pathlink.com> wrote in message news:cbu46c$2fq4$1 digitaldaemon.com...Sure, I can use the (for now?) freely downloadable tools. But I think that it's easier to persuade my employer to adopt D for aproject ifbehind D there's a company working to solve bugs and improve the toolkit.There is - Digital Mars. It's a real, licensed company, been around for years. We even pay taxes <g>. The track record for tech support is open for all to see in this newsgroup, and the track record of resolving bugs and improving the toolkit is evident in www.digitalmars.com/d/changelog.html
Jun 30 2004
Shared libraries could be very advantageous to minimize download size for a "suite" of applications. Not everyone has broadband. [And pda development ... for eventual consideration] The only reason I use "hold-your-nose" Visual C++ MFC is that my freeware apps can assume the end-user has mfc40.dll (Win95), mfc42.dll (Win98), and msvcrt.dll. MyAppUpdate.exe (just executable update without fixed data, source, and documentation files) can have significant functionality in well under 100kb, including NSIS installer.It would be very useful to have a single shared library with Phobos/Garbage Collector.It would save some disk space, that's it.
Jul 01 2004
"Roberto Mariottini" <Roberto_member pathlink.com> wrote in message news:cbtq14$1k9r$1 digitaldaemon.com...But what if I want to distribute a bunch of executables forming a complete suite? It would be very useful to have a single shared librarywithPhobos/Garbage Collector.Indeed... exactly my problem also. In Walter's reply he says: "Walter" <newshound digitalmars.com> wrote in message news:cbttqo$1uio$1 digitaldaemon.com...It would save some disk space, that's it....however, it's memory space as well really, isn't it? Although it's not the end of the world to compile Phobos and the GC into the executable, we really do need that option. And I mean an option; a compiler flag or whatever - not just simply changed. The default should remain as it is now, with the facility for those that so require to compile the separate shared library. I know you said "after 1.0" Walter, but is that definite? Is there a D roadmap somewhere to show where the language is going, and what things are going to be done at what stages? If not, that would be useful, and save extroneous discussion ;) As you can probably tell, this is an important issue to me <g>
Jun 30 2004
"Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbu130$2930$1 digitaldaemon.com..."Walter" <newshound digitalmars.com> wrote in message news:cbttqo$1uio$1 digitaldaemon.com...No, not unless the programs are running simultaneously. And even so, how many are you going to have running simultaneously? 3 or 4? That would be an extra 200k on a machine with (likely) 256 megabytes on it. I don't think it would be noticed.It would save some disk space, that's it....however, it's memory space as well really, isn't it?Although it's not the end of the world to compile Phobos and the GC into the executable, we really do need that option. And I mean an option; a compiler flag or whatever - not just simply changed. The default should remain as it isnow,with the facility for those that so require to compile the separate shared library. I know you said "after 1.0" Walter, but is that definite? Is there a D roadmap somewhere to show where the language is going, and what things are going to be done at what stages? If not, that would be useful, and save extroneous discussion ;)There isn't a concrete roadmap, we'll just be pushing it in the direction that the D community wants it to go.As you can probably tell, this is an important issue to me <g>I understand it is, but I'm not sure why in these days of incomprehensibly large disk and memory spaces <g>.
Jun 30 2004
"Walter" <newshound digitalmars.com> wrote in message news:cbuuao$rsk$2 digitaldaemon.com..."Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbu130$2930$1 digitaldaemon.com...an"Walter" <newshound digitalmars.com> wrote in message news:cbttqo$1uio$1 digitaldaemon.com...No, not unless the programs are running simultaneously. And even so, how many are you going to have running simultaneously? 3 or 4? That would beIt would save some disk space, that's it....however, it's memory space as well really, isn't it?extra 200k on a machine with (likely) 256 megabytes on it. I don't thinkitwould be noticed.Heheh... well, I've always preferred to conserve resources wherever possible, and just because there's a lot of disk and memory space doesn't mean we should be inefficient in its usage, surely? ;) There are some valid uses where the space would be very important - such as in embedded software - but I don't write anything like that, so I'm going to drop this one here now and just hope that it gets "fixed" at some point in the future :DAs you can probably tell, this is an important issue to me <g>I understand it is, but I'm not sure why in these days of incomprehensibly large disk and memory spaces <g>.
Jun 30 2004
There are some valid uses where the space would be very important - suchasin embedded software - but I don't write anything like that, so I'm goingtodrop this one here now and just hope that it gets "fixed" at some point in the future :Dpda development (Palm and Pocket-PC) still have important resource limitations. "D" might be a great language for pda development.
Jun 30 2004
Walter wrote:"Dan Williams" <dnews ithium.NOSPAM.net> wrote in message news:cbskjv$2u3i$1 digitaldaemon.com...D is a great language, I'm a huge fan, and have been since its earliest days. However... This is quite unfortunate - how can we expect to achieve real-world (i.e. useful) linear algebra performance through such an emulation mechanism? I want to use D in games (I'm a Lead on a PSP title), possibly even in the near future. Others, I'm sure, would love to use D in scientific applications. For these applications, we need some real linear algebra code, and for that, we need (something like) Norbert's stuff to become reality. What say you on this topic??? --Steve PS - Our linear algebra "packages" in C++ are all major hacks - operator overloads galore, super fugly template trickery. Having something IN THE LANGUAGE that makes these things easier, more elegant, and more efficient would be a dream come true for many a coder.All I can say about that type of array is that I agree with the proposal put forward by Norbert Nemec - has any of that been implemented yet? Is it going to be?It's a good candidate for 2.0. But right now, one can emulate such arrays using structs and operator overloading.
Jun 30 2004
"Stephen Waits" <steve waits.net> wrote in message news:cbvhur$1on6$1 digitaldaemon.com...This is quite unfortunate - how can we expect to achieve real-world (i.e. useful) linear algebra performance through such an emulation mechanism?I think you can get much closer in D than you can in C++, because in D you can overload [] to take multiple indices. This is not possible in C++.I want to use D in games (I'm a Lead on a PSP title), possibly even in the near future. Others, I'm sure, would love to use D in scientific applications.D has much better *standard* handling of floating point than C++ - for example, behavior is specified to be IEEE 754 conformant. Nans must be handled properly. This is not addressed by C++. Also, D has 80 bit floating point, and built in complex numbers.For these applications, we need some real linear algebra code, and for that, we need (something like) Norbert's stuff to become reality. What say you on this topic???I'm aware of the importance of this issue. But I'm also painfully aware that D is not stable enough at the moment, and that must be the priority.--Steve PS - Our linear algebra "packages" in C++ are all major hacks - operator overloads galore, super fugly template trickery. Having something IN THE LANGUAGE that makes these things easier, more elegant, and more efficient would be a dream come true for many a coder.
Jul 01 2004
Walter wrote:"Stephen Waits" <steve waits.net> wrote in message news:cbvhur$1on6$1 digitaldaemon.com...Careful: the multiple index opIndex may help you in writing *comfortable* linalg-libraries. For writing high-performance code, you need completely different means, namely vectorization. C++ offers means for vectorization via expression templates, which are a clumsy, sub-optimal solution. D doesn't offer anything in that direction at all. Array expressions are a small step in that direction. Anyhow, I think the current specs in that direction should not be implemented at all. They are a best a toy-solution for the problem that will get in our way lateron, when we look for a real solution. For some more thoughts on vectorization see my separate post.This is quite unfortunate - how can we expect to achieve real-world (i.e. useful) linear algebra performance through such an emulation mechanism?I think you can get much closer in D than you can in C++, because in D you can overload [] to take multiple indices. This is not possible in C++.
Jul 01 2004
If you're truely after cross platform, the D is probably not at a stage that would be useful. There's a Windows version, a Linux version, oh and I hacked together a really out of date version for BeOS and Zeta (lol). All intel based, all fixed to specific platforms.really. Try looking at Free Pascal. It does intel, powerpc, arm and 68000. It has a MacOSX, DOS (via Go32v2 dos extender), Windows, Amiga, BeOS (intel), BSD, Linux (including PPC, INTEL and AMD64 is in the works too.) There's probably more platforms - I know PalmOS 68000 was in the works at one point. Classic MacOS (PPC) is also being worked on. It supports a number of Pascal dialects. Borland Turbo Pascal, Borland Delphi, a FPC Hybrid ObjectPascal and also a Mac Pascal dialect in the latest version (not yet avalable for all Platforms.) It seems odd to push for Pascal in a D forum, but I know of quite a few people who actively maintain multiple platform code using Free Pascal. It has all of your major requirements (e.g. OO, dynamic string type, RTTI, etc) and is on a par with D on the Windows platform. Couple this with the Lazarus project, and you have RAD on a number of the available platforms too. http://www.freepascal.org. MattBasic and Pascal derivatives? ...nothing I know of fits the bill,
Jun 30 2004