www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Various D language matters

reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
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:

 PHP: nowhere near fast enough; not compilable. However, it is
cross-platform, and the language itself is near perfect for what I need - except it isn't strict enough.
 Ruby: getting better - a lot faster than PHP, and although not strictly
compilable, 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.
 Python: not even worth considering. I don't really like the language, and
it's very slow. There are wrappers, but all things compared, Ruby would be a better choice.
 Perl: faster than PHP, but worse language-wise; for me, at least. Again,
not compilable.
 C/C++: very fast, obviously compilable, and cross-platform. Perfect? NO!
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 :)
 Smalltalk: quite fast, compilable, and the language supports much of what
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.
 Forth, Ada, similar friends: similar to my comments on Smalltalk. Some do
what 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.
 Basic and Pascal derivatives? ...nothing I know of fits the bill, really.
 Lua: a very interesting option, this one. Lua is a beautiful language,
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.
 Java: Many people (probably Java lovers!) would have immediately touted
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 Dan
Jun 29 2004
next sibling parent Norbert Nemec <Norbert.Nemec gmx.de> writes:
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
prev sibling next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"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 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.
Hype? What hype? <g>
 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 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'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.
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 the
compiled
 D 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 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 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,
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' :)
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. 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.
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 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.
 While on the subject on arrays, I have a question. Is it possible to
create
 D 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,
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.
There is a built-in sort property for arrays, but not swap.
 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!
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
next sibling parent reply Sean Kelly <sean f4.ca> writes:
In article <cbsq23$46i$1 digitaldaemon.com>, Walter says...
"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 the
compiled
 D 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.
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. Sean
Jun 29 2004
next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Sean Kelly" <sean f4.ca> wrote in message
news:cbsquv$5ca$1 digitaldaemon.com...
 In article <cbsq23$46i$1 digitaldaemon.com>, Walter says...
"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 the
compiled
 D 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.
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.
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
parent "Dan Williams" <dnews ithium.NOSPAM.net> writes:
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...
 In article <cbsq23$46i$1 digitaldaemon.com>, Walter says...
"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 the
compiled
 D 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.
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.
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
prev sibling parent "Dan Williams" <dnews ithium.NOSPAM.net> writes:
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...
"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 the
compiled
 D 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.
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.


 Sean
Jun 29 2004
prev sibling next sibling parent reply "Martin M. Pedersen" <martin moeller-pedersen.dk> writes:
"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
next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"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 is guaranteed
to
 be stable or not.
What does 'stable' mean applied to sorts?
Jun 29 2004
next sibling parent reply Derek Parnell <derek psych.ward> writes:
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...
 "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.
What does 'stable' mean applied to sorts?
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
Jun 29 2004
parent reply "Walter" <newshound digitalmars.com> writes:
"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:

 "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 is
guaranteed
 to
 be stable or not.
What does 'stable' mean applied to sorts?
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
Ok, I understand. But I don't know if qsort has that property or not.
Jun 29 2004
parent reply Oskar Linde <d98-oliRE.MO.VE nada.kth.se> writes:
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
parent "Walter" <newshound digitalmars.com> writes:
"Oskar Linde" <d98-oliRE.MO.VE nada.kth.se> wrote in message
news:cbu0k9$26ul$1 digitaldaemon.com...
 Walter wrote:

 Ok, I understand. But I don't know if qsort has that property or not.
No, quicksort is not stable.
Then .sort is not stable. <g>
Jun 30 2004
prev sibling parent Ben Hinkle <bhinkle4 juno.com> writes:
Walter wrote:

 
 "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 is guaranteed
to
 be stable or not.
What does 'stable' mean applied to sorts?
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).
Jun 29 2004
prev sibling parent reply Jesus <Jesus_member pathlink.com> writes:
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...
 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
It 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
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
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...
"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
It 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
parent reply Norbert Nemec <Norbert.Nemec gmx.de> writes:
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
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
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:

 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
parent reply "Walter" <newshound digitalmars.com> writes:
"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 so
a
 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
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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, and
so
 a
 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]);
Well, 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?
Jun 30 2004
next sibling parent reply "Ivan Senji" <ivan.senji public.srce.hr> writes:
"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 be used, and
so
 a
 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]);
Well, 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?
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
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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 be used,
and
 so
 a
 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]);
Well, 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?
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.
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.
Jun 30 2004
parent reply Regan Heath <regan netwin.co.nz> writes:
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...
 "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 be used,
and
 so
 a
 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]);
Well, 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?
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.
I think you'll find you are mistaken...
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
 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
parent "Dan Williams" <dnews ithium.NOSPAM.net> writes:
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:

 "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 be
used,
 and
 so
 a
 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]);
Well, 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?
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.
I think you'll find you are mistaken...
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
 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
prev sibling parent reply Sam McCall <tunah.d tunah.net> writes:
Dan Williams wrote:

 "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, and
so
a

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]);
Well, 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?
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
Jul 01 2004
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"Sam McCall" <tunah.d tunah.net> wrote in message
news:cc0pu0$lak$1 digitaldaemon.com...
 Dan Williams wrote:

 "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, and
so
a

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]);
Well, 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?
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?
No 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>)
Jul 01 2004
parent ardita <erza_13 zbavitu.net> writes:
Dan Williams Wrote:

 
 "Sam McCall" <tunah.d tunah.net> wrote in message
 news:cc0pu0$lak$1 digitaldaemon.com...
 Dan Williams wrote:

 "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, and
so
a

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]);
Well, 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?
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?
No 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>)
May 12 2009
prev sibling next sibling parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
Thanks for the reply :) Comments below...


"Walter" <newshound digitalmars.com> wrote in message
news:cbsq23$46i$1 digitaldaemon.com...
 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 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.
Indeed :)
 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.
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.
Ahhh, yes that would explain some of the overhead. Very much worth it though!
 Wow! Pretty impressive! :) The results clearly show to me that the
compiled
 D 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.

 The 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.
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>
 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.
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.
 While on the subject on arrays, I have a question. Is it possible to
create
 D 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).
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.
 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.
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 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!)
 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.
There 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, would there be an advantage in adding a swap method, or is it pointless?
 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!
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.
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 something that will be introduced after v1.0? Once more, thankyou for your time :) Dan
Jun 29 2004
next sibling parent reply "Chr. Grade" <tickle everymail.net> writes:
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...
 
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 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.
Indeed :)
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.
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.
Ahhh, yes that would explain some of the overhead. Very much worth it though!
Wow! Pretty impressive! :) The results clearly show to me that the
compiled
D 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.

The 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.
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>
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.
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.
While on the subject on arrays, I have a question. Is it possible to
create
D 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).
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.
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.
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 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!)
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.
There 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, would there be an advantage in adding a swap method, or is it pointless?
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!
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.
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 something that will be introduced after v1.0? Once more, thankyou for your time :) Dan
Jun 30 2004
parent "Dan Williams" <dnews ithium.NOSPAM.net> writes:
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
prev sibling next sibling parent reply J C Calvarese <jcc7 cox.net> writes:
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/57
 
 
 
While on the subject on arrays, I have a question. Is it possible to
create
D 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).
I'd love to see a variant type built into the language.

... -- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/
Jun 29 2004
parent reply Derek Parnell <derek psych.ward> writes:
On Tue, 29 Jun 2004 23:16:54 -0500, J C Calvarese wrote:

 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/57
 
While on the subject on arrays, I have a question. Is it possible to
create
D 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).
I'd love to see a variant type built into the language.

...
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 PM
Jun 29 2004
next sibling parent Derek Parnell <derek psych.ward> writes:
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
prev sibling parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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:

 Dan Williams wrote:
 ...

 I'd love to see a variant type built into the language.


...
Hear! Hear! Long live the VARIANT type.
Glad to see that I'm not the only one who would find a variant data type useful! :D
Jun 30 2004
parent reply Regan Heath <regan netwin.co.nz> writes:
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...
 On Tue, 29 Jun 2004 23:16:54 -0500, J C Calvarese wrote:

 Dan Williams wrote:
 ...

 I'd love to see a variant type built into the language.


...
Hear! Hear! Long live the VARIANT type.
Glad to see that I'm not the only one who would find a variant data type useful! :D
What exactly is a variant type? Regan. -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jun 30 2004
parent reply Derek <derek psyc.ward> writes:
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:
 
 "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:

 Dan Williams wrote:
 ...

 I'd love to see a variant type built into the language.


...
Hear! Hear! Long live the VARIANT type.
Glad to see that I'm not the only one who would find a variant data type useful! :D
What exactly is a variant type? Regan.
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
Jun 30 2004
next sibling parent "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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:

 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...
 On Tue, 29 Jun 2004 23:16:54 -0500, J C Calvarese wrote:

 Dan Williams wrote:
 ...

 I'd love to see a variant type built into the language.


...
Hear! Hear! Long live the VARIANT type.
Glad to see that I'm not the only one who would find a variant data
type
 useful! :D
What exactly is a variant type? Regan.
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.
...which is exactly why I am keen to see a variant data type included in the core of the D language ;)
Jun 30 2004
prev sibling parent Regan Heath <regan netwin.co.nz> writes:
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:

 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...
 On Tue, 29 Jun 2004 23:16:54 -0500, J C Calvarese wrote:

 Dan Williams wrote:
 ...

 I'd love to see a variant type built into the language.


...
Hear! Hear! Long live the VARIANT type.
Glad to see that I'm not the only one who would find a variant data type useful! :D
What exactly is a variant type? Regan.
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.
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/
Jun 30 2004
prev sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Dan Williams" <dnews ithium.NOSPAM.net> wrote in message
news:cbt4et$ihd$1 digitaldaemon.com...
 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.
Ahhh, yes that would explain some of the overhead. Very much worth it though!
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.
 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.
As far as I know, it hasn't been implemented by anyone yet.
 While on the subject on arrays, I have a question. Is it possible to
create
 D 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).
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.
You might as well give it a whirl <g>.
 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.
 No. A D array is a pair of two items, the number of elements in the
array
 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.
Think of an array as: struct { int length; void *data; }; You can change either or both members as required to do various things.
 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?
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 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.
 There 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,
would
 there be an advantage in adding a swap method, or is it pointless?
There's some utility for it, but not a whole lot.
 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.
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 something
that
 will be introduced after v1.0?
after 1.0
Jun 29 2004
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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...
 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).
Again, are there any examples of this around, or would I have to do it myself?
You might as well give it a whirl <g>.
Ok, fair enough :) I'll try to find some time over the next few weeks to do so.
 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.
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?
 A D array is a pair of two items, the number of elements in the
array
 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.
Think of an array as: struct { int length; void *data; }; You can change either or both members as required to do various things.
 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?
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.
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. 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>
Jun 30 2004
next sibling parent reply Jesus <Jesus_member pathlink.com> writes:
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 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>
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
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"Jesus" <Jesus_member pathlink.com> wrote in message
news:cbuh1n$89l$1 digitaldaemon.com...
 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 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>
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.
 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.
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" 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.
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
parent reply Norbert Nemec <Norbert.Nemec gmx.de> writes:
Dan Williams wrote:

 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.
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.
Jun 30 2004
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
Hmmmm...


"Norbert Nemec" <Norbert.Nemec gmx.de> wrote in message
news:cbun74$hpk$1 digitaldaemon.com...
 Dan Williams wrote:

 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.
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.
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
next sibling parent reply Regan Heath <regan netwin.co.nz> writes:
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...
 Dan Williams wrote:

 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.
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.
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).
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/
Jun 30 2004
parent "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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:

 Hmmmm...


 "Norbert Nemec" <Norbert.Nemec gmx.de> wrote in message
 news:cbun74$hpk$1 digitaldaemon.com...
 Dan Williams wrote:

 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.
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.
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).
I think I have understood you in my last post.. haven't I? Regan.
...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>
Jun 30 2004
prev sibling parent reply Derek <derek psyc.ward> writes:
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
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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 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 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 :D
 A --> [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
next sibling parent reply Regan Heath <regan netwin.co.nz> writes:
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 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].
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].
 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
Nope.
 - 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
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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 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 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].
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].
 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
Nope.
 - 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 --
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.
Jun 30 2004
next sibling parent Stephen Waits <steve waits.net> writes:
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
prev sibling parent reply Regan Heath <regan netwin.co.nz> writes:
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...
 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 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].
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].
 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
Nope.
 - 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 --
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.
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/
Jun 30 2004
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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:
 "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 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 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].
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].
 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
Nope.
 - 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 --
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.
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]);
Heh... I had simply altered your code for that bit ;)
 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
Indeed, 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
next sibling parent "Carlos Santander B." <carlos8294 msn.com> writes:
"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
prev sibling parent reply James McComb <alan jamesmccomb.id.au> writes:
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
parent "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"James McComb" <alan jamesmccomb.id.au> wrote in message
news:cc26dl$2u2m$1 digitaldaemon.com...
 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 */
That's a good way of putting it actually :)
 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
prev sibling parent reply Derek Parnell <derek psych.ward> writes:
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...
 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 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 :D
 A --> [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?
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.
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!
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 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
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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:

 "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 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 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 :D
 A --> [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?
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.
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!
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 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.
It 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:
 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.
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!
Jul 01 2004
parent reply Derek <derek psyc.ward> writes:
On Thu, 1 Jul 2004 11:31:34 +0100, Dan Williams wrote:

[snip]
 Hopefully a goodnight's sleep will help.
It sure did - I carefully went through the code examples this morning, and finally twigged it! :D
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.
 Although, please have the grace to let me point this out:
 
 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.
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>
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.
 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
parent "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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]
 Hopefully a goodnight's sleep will help.
It sure did - I carefully went through the code examples this morning,
and
 finally twigged it! :D
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.
Yup, that's were I came unstuck.
 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.

 Although, please have the grace to let me point this out:

 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.
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>
Hmmmm...don't follow you here. What do you mean by copying by slicing? Can you given a code example?
Sure! 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]
 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 section
 Thanks for your patience with this old fool!
As a friend keeps reminding me, the only stupid question is one that is never asked.
I like the sound of that - it lets me off the hook! ;)
Jul 01 2004
prev sibling parent reply Regan Heath <regan netwin.co.nz> writes:
On Wed, 30 Jun 2004 11:03:42 +0100, Dan Williams <dnews ithium.NOSPAM.net> 
wrote:
 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.
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.
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 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
next sibling parent reply Sam McCall <Sam_member pathlink.com> writes:
In article <opsafkvvct5a2sq9 digitalmars.com>, Regan Heath says...
 Take an array with 100 elements, where each element is a variable-length
 string.
char[][100] list;
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 :'( Sam
Jun 30 2004
next sibling parent reply Regan Heath <regan netwin.co.nz> writes:
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...
 Take an array with 100 elements, where each element is a 
 variable-length
 string.
char[][100] list;
Really?
I believe so. My test program uses it.
 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
parent reply Sam McCall <Sam_member pathlink.com> writes:
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:

 In article <opsafkvvct5a2sq9 digitalmars.com>, Regan Heath says...
 Take an array with 100 elements, where each element is a 
 variable-length
 string.
char[][100] list;
Really?
I believe so. My test program uses it.
 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 :)
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. Sam
Jun 30 2004
parent reply Regan Heath <regan netwin.co.nz> writes:
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...
 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...
 Take an array with 100 elements, where each element is a
 variable-length
 string.
char[][100] list;
Really?
I believe so. My test program uses it.
 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 :)
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].
Yep.
 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
parent reply Sam McCall <tunah.d tunah.net> writes:
Regan Heath wrote:

 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...

 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...

 Take an array with 100 elements, where each element is a
 variable-length
 string.
char[][100] list;
Really?
I believe so. My test program uses it.
 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 :)
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].
Yep.
 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.
Yes, yes, I get all that, but the _indices_ are _backwards_. Java certainly doesn't do it this way, do other languages? Sam
Jul 01 2004
next sibling parent "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"Sam McCall" <tunah.d tunah.net> wrote in message
news:cc0qeq$m0u$1 digitaldaemon.com...
 Regan Heath wrote:

 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...

 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...

 Take an array with 100 elements, where each element is a
 variable-length
 string.
char[][100] list;
Really?
I believe so. My test program uses it.
 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 :)
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].
Yep.
 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.
Yes, yes, I get all that, but the _indices_ are _backwards_. Java certainly doesn't do it this way, do other languages? Sam
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.
Jul 01 2004
prev sibling parent Regan Heath <regan netwin.co.nz> writes:
On Thu, 01 Jul 2004 22:56:01 +1200, Sam McCall <tunah.d tunah.net> wrote:

 Regan Heath wrote:

 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...

 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...

 Take an array with 100 elements, where each element is a
 variable-length
 string.
char[][100] list;
Really?
I believe so. My test program uses it.
 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 :)
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].
Yep.
 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.
Yes, yes, I get all that, but the _indices_ are _backwards_. Java certainly doesn't do it this way, do other languages?
See "Norbert Nemec"'s post. he explains it well. Regan -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Jul 01 2004
prev sibling parent Norbert Nemec <Norbert.Nemec gmx.de> writes:
Sam McCall wrote:

 In article <opsafkvvct5a2sq9 digitalmars.com>, Regan Heath says...
 Take an array with 100 elements, where each element is a variable-length
 string.
char[][100] list;
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 :'( Sam
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];
Jul 01 2004
prev sibling parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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:
 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.
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.
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 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
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> 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.
Jun 30 2004
parent reply Regan Heath <regan netwin.co.nz> writes:
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...
 On Wed, 30 Jun 2004 11:03:42 +0100, Dan Williams 
 <dnews ithium.NOSPAM.net>
 wrote:
 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.
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.
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 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
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.
 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.
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
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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:
 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.
:D so it's not just me then!
 ...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.
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!)
 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 :(
 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.
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 :)
Jul 01 2004
parent Regan Heath <regan netwin.co.nz> writes:
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...
 On Thu, 1 Jul 2004 01:23:38 +0100, Dan Williams 
 <dnews ithium.NOSPAM.net>
 wrote:
 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.
:D so it's not just me then!
 ...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.
Should there be a clone() method in the core D language? Kinda like PHP5?
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.
 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.
 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?
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].
 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.
 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.
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 :)
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/
Jul 01 2004
prev sibling next sibling parent reply Roberto Mariottini <Roberto_member pathlink.com> writes:
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
next sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Roberto Mariottini" <Roberto_member pathlink.com> wrote in message
news:cbtq14$1k9r$1 digitaldaemon.com...
 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?
You can download it now! That's what dmd.zip is.
 - Which commercial formula will be used? How about tech help?
 - Will it be possible to buy the compiler sources, just in case?
Yes.
 [..]
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.
It would save some disk space, that's it.
Jun 30 2004
next sibling parent reply Roberto Mariottini <Roberto_member pathlink.com> writes:
In article <cbttqo$1uio$1 digitaldaemon.com>, Walter says...
"Roberto Mariottini" <Roberto_member pathlink.com> wrote in message
news:cbtq14$1k9r$1 digitaldaemon.com...
[...]
 - When Digital Mars D development toolkit will be available?
You can download it now! That's what dmd.zip is.
I think you missed the point, that is in the next question:
 - Which commercial formula will be used? How about tech help?
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.
 - Will it be possible to buy the compiler sources, just in case?
Yes.
Good. But this can be oly a parachute, I prefer having a working plane ;-) [...]
 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.
It would save some disk space, that's it.
And load time, and maybe some memory (depending on the O.S.). I think it's worth. Ciao
Jun 30 2004
parent "Walter" <newshound digitalmars.com> writes:
"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 a
project if
 behind 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
prev sibling parent "Lynn Allan" <l.allan att.net> writes:
 It would be very useful to have a single shared library with
 Phobos/Garbage Collector.
It would save some disk space, that's it.
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.
Jul 01 2004
prev sibling parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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 library
with
 Phobos/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
parent reply "Walter" <newshound digitalmars.com> writes:
"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...
 It would save some disk space, that's it.
...however, it's memory space as well really, isn't it?
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.
 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 ;)
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
parent reply "Dan Williams" <dnews ithium.NOSPAM.net> writes:
"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...
 "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?
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.

 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>.
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 :D
Jun 30 2004
parent "Lynn Allan" <l.allan att.net> writes:
 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 :D
pda development (Palm and Pocket-PC) still have important resource limitations. "D" might be a great language for pda development.
Jun 30 2004
prev sibling parent reply Stephen Waits <steve waits.net> writes:
Walter wrote:

 "Dan Williams" <dnews ithium.NOSPAM.net> wrote in message
 news:cbskjv$2u3i$1 digitaldaemon.com...
 
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.
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.
Jun 30 2004
parent reply "Walter" <newshound digitalmars.com> writes:
"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
parent Norbert Nemec <Norbert.Nemec gmx.de> writes:
Walter wrote:

 
 "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++.
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.
Jul 01 2004
prev sibling parent "me" <memsom interalpha.co.uk> writes:
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.

 Basic and Pascal derivatives? ...nothing I know of fits the bill,
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. Matt
Jun 30 2004