www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - (OT) Slashdot on the future of C++

reply Nick <Nick_member pathlink.com> writes:
Slashdot just ran a discussion on the future of C++:
http://developers.slashdot.org/article.pl?sid=05/07/11/1134203&tid=156&tid=8

Naturally a lot of people came out to vent their misgivings about the language.
Here's some of the stuff I found complaints about:

- No garbage collection
- Member function pointers (ie. no delegates)
- Lack of "abstract" and "typeof" keywords
- No modules, and the namespace system is a hack to try to fix this
- Memory safety and language safety in general
- Too many complicated and unecessary language rules

I think I might know a language that fixes, or improves on, all these :D

Nick
Jul 11 2005
next sibling parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Nick" <Nick_member pathlink.com> wrote in message 
news:daug61$1tn6$1 digitaldaemon.com...
 Slashdot just ran a discussion on the future of C++:
 http://developers.slashdot.org/article.pl?sid=05/07/11/1134203&tid=156&tid=8

 Naturally a lot of people came out to vent their misgivings about the 
 language.
 Here's some of the stuff I found complaints about:

 - No garbage collection
 - Member function pointers (ie. no delegates)
 - Lack of "abstract" and "typeof" keywords
 - No modules, and the namespace system is a hack to try to fix this
 - Memory safety and language safety in general
 - Too many complicated and unecessary language rules

 I think I might know a language that fixes, or improves on, all these :D
E.g. memory safety is available only in managed environments so far. Andrew.
Jul 11 2005
parent reply AJG <AJG_member pathlink.com> writes:

1) Call native, unsafe code directly (P/Invoke && DllImport).
2) Use raw pointers and arithmetic (IntPtr).

So it doesn't have complete memory safety either. I don't know about Java.
There's probably a per-platform way of doing that too, if you really wanted to.

I think it's "safe" to say that D has relatively safe memory management, in most
cases. Granted, it's still possible to blow your whole leg off, but you can do
that everywhere, if you set your mind to it ;)

--AJG.

"Nick" <Nick_member pathlink.com> wrote in message 
news:daug61$1tn6$1 digitaldaemon.com...
 Slashdot just ran a discussion on the future of C++:
 http://developers.slashdot.org/article.pl?sid=05/07/11/1134203&tid=156&tid=8

 Naturally a lot of people came out to vent their misgivings about the 
 language.
 Here's some of the stuff I found complaints about:

 - No garbage collection
 - Member function pointers (ie. no delegates)
 - Lack of "abstract" and "typeof" keywords
 - No modules, and the namespace system is a hack to try to fix this
 - Memory safety and language safety in general
 - Too many complicated and unecessary language rules

 I think I might know a language that fixes, or improves on, all these :D
E.g. memory safety is available only in managed environments so far. Andrew.
Jul 11 2005
parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
"AJG" <AJG_member pathlink.com> wrote in message 
news:daum5v$22uh$1 digitaldaemon.com...

 1) Call native, unsafe code directly (P/Invoke && DllImport).
 2) Use raw pointers and arithmetic (IntPtr).

 So it doesn't have complete memory safety either. I don't know about Java.
 There's probably a per-platform way of doing that too, if you really 
 wanted to.

 I think it's "safe" to say that D has relatively safe memory management, 
 in most
 cases. Granted, it's still possible to blow your whole leg off, but you 
 can do
 that everywhere, if you set your mind to it ;)
Your answer just proves that but in some exceptional cases like:
 1) Call native, unsafe code directly (P/Invoke && DllImport).
 2) Use raw pointers and arithmetic (IntPtr).
(or using JNI calls in Java) you can break that builtin memory safety rules. I am not against D. I am just trying to be impartial. Any memory safety has its own price. Pretty frequently (at least in my cases) this mandatory price is not acceptable. That's it.
 --AJG.

"Nick" <Nick_member pathlink.com> wrote in message
news:daug61$1tn6$1 digitaldaemon.com...
 Slashdot just ran a discussion on the future of C++:
 http://developers.slashdot.org/article.pl?sid=05/07/11/1134203&tid=156&tid=8

 Naturally a lot of people came out to vent their misgivings about the
 language.
 Here's some of the stuff I found complaints about:

 - No garbage collection
 - Member function pointers (ie. no delegates)
 - Lack of "abstract" and "typeof" keywords
 - No modules, and the namespace system is a hack to try to fix this
 - Memory safety and language safety in general
 - Too many complicated and unecessary language rules

 I think I might know a language that fixes, or improves on, all these :D
E.g. memory safety is available only in managed environments so far. Andrew.
Jul 11 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message
news:dauv5e$2b1f$1 digitaldaemon.com...
 Any memory safety has its own price. Pretty frequently
 (at least in my cases) this mandatory price is not acceptable.
 That's it.
True. D doesn't eliminate the potential for memory corruption. What it does try to do, however, is reduce the probability of them by 1) providing less error-prone ways to get the functionality, such as using out and inout parameters rather than pointers and 2) adding runtime checks such as array bounds overflow checking and contract programming.
Jul 12 2005
parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:db114l$16o3$1 digitaldaemon.com...
 "Andrew Fedoniouk" <news terrainformatica.com> wrote in message
 news:dauv5e$2b1f$1 digitaldaemon.com...
 Any memory safety has its own price. Pretty frequently
 (at least in my cases) this mandatory price is not acceptable.
 That's it.
True. D doesn't eliminate the potential for memory corruption. What it does try to do, however, is reduce the probability of them by 1) providing less error-prone ways to get the functionality, such as using out and inout parameters rather than pointers and 2) adding runtime checks such as array bounds overflow checking and contract programming.
True. Except one: I just don't understand - how contract programming helps to increase memory safety. Currently D's DbC features allows you only check for NULL. Did I miss something in principle? "const", as a part of DbC, will definitely help more here. This is true.
Jul 12 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message
news:db12la$17to$1 digitaldaemon.com...
 Except one: I just don't understand - how contract programming
 helps to increase memory safety.
 Currently D's DbC features allows you only check for NULL.

 Did I miss something in principle?
You can write the contracts to test for anything you want, not just NULL.
Jul 14 2005
parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:db63at$31dn$2 digitaldaemon.com...
 "Andrew Fedoniouk" <news terrainformatica.com> wrote in message
 news:db12la$17to$1 digitaldaemon.com...
 Except one: I just don't understand - how contract programming
 helps to increase memory safety.
 Currently D's DbC features allows you only check for NULL.

 Did I miss something in principle?
You can write the contracts to test for anything you want, not just NULL.
Walter, it was all about memory safety and DbC. The only one test available for DbC (runtime DbC test, sic!) now is to test on NULL pointer. What else I can do to verify is it safe to write into this memory or not? Preferably in compile/design time. Andrew.
Jul 14 2005
parent "Walter" <newshound digitalmars.com> writes:
"Andrew Fedoniouk" <news terrainformatica.com> wrote in message
news:db649h$ob$1 digitaldaemon.com...
 Walter, it was all about memory safety and DbC.
I understand that.
 The only one test available for DbC (runtime DbC test, sic!) now is to
test
 on NULL pointer.
No, you can test for anything you can express in code. You can, for example, run a consistency check on a free list.
Jul 14 2005
prev sibling next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Nick wrote:

 Slashdot just ran a discussion on the future of C++:
 http://developers.slashdot.org/article.pl?sid=05/07/11/1134203&tid=156&tid=8
Actually they linked to an article of Bjarne about the future "C++0x"... (http://www.research.att.com/~bs/rules.pdf) I think there was a major difference between C++ and D almost at once, he wants to use the standard library while Walter wants to build it in: See "Rationale for Builtins" http://www.digitalmars.com/d/builtin.html --anders PS. I must confess I stopped reading somewhere at "C++0x will be almost 100-percent compatible with the existing Standard C++."... Same old ?
Jul 11 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Anders F Björklund" <afb algonet.se> wrote in message
news:daunef$245r$1 digitaldaemon.com...
 I think there was a major difference between C++ and D almost at once,
 he wants to use the standard library while Walter wants to build it in:

 See "Rationale for Builtins" http://www.digitalmars.com/d/builtin.html
Yes, although many C++ programmers think this is a wider gulf between C++ and D than it actually is. C++ has core strings and core arrays, for example, they just work so poorly one is motiviated to do a library replacement. Unfortunately, those replacements don't work well either.
Jul 12 2005
parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Walter" <newshound digitalmars.com> wrote in message 
news:db114m$16o3$2 digitaldaemon.com...
 "Anders F Björklund" <afb algonet.se> wrote in message
 news:daunef$245r$1 digitaldaemon.com...
 I think there was a major difference between C++ and D almost at once,
 he wants to use the standard library while Walter wants to build it in:

 See "Rationale for Builtins" http://www.digitalmars.com/d/builtin.html
Yes, although many C++ programmers think this is a wider gulf between C++ and D than it actually is. C++ has core strings and core arrays, for example, they just work so poorly one is motiviated to do a library replacement. Unfortunately, those replacements don't work well either.
Walter, sorry for beating this horse again but D does not yet have strings either. Very convenient character arrays and slices - yes. But strings (as value type) - not yet. String is an immutable value and has no analogues in D. D's char[] is just a StringBuffer/StringBuilder. And this is main concern enterprise developers. They just get used to such String robustness. BTW: modern java.lang.String implementation is capable to represent string slices too.
Jul 12 2005
parent reply Charles Hixson <charleshixsn earthlink.net> writes:
Andrew Fedoniouk wrote:
...
 Walter, sorry for beating this horse again but D does not yet have strings 
 either.
 Very convenient character arrays and slices - yes. But strings (as value 
 type) -
 not yet. String  is an immutable value and has no analogues in D.
 D's char[] is just a StringBuffer/StringBuilder. And this is main concern 

 enterprise developers. They just get used to such String robustness.
 BTW: modern java.lang.String implementation is capable to represent string 
 slices too.
Perhaps allowing Java terminology to define things isn't exactly fair. Many languages have had mutable strings (often, admittedly, by accident). Being mutable DOESN'T mean it isn't a string, it means it's not a Java String class, which nobody ever claimed it was. OTOH, a char[] isn't really a full fledged string, even with slicing. It's quite close, but not quite there. To get to String status you need to do something like importing std.string. But char[]'s really build in most features that need to be built in. Basically what should be added is some special magic so that if you import std.string, the std.string methods are all available as methods of variables/literals of type char[], so you would be able to do things like: j = "This is a test".rfind("is"); Even that isn't quite perfect. It would be nice to be able to do things like: s = "This is a test"; s.removechars("/is/"); // N.B.: Note the /'s this should mean // "interpret this as a pattern" Notice that the syntax has changed a bit from the current usage as this is now a method invocation rather than a function call. Also notice that this function would need to realize that it's arguments couldn't be const's. (A standard requirement, but another change from the current approach.) This might even be a reasonable approach, given that already char[]'s need to be converted to Stringz if one wants to use them in C. OTTH (or is this the fourth hand), perhaps this extension is better handled with a library. I don't even think it would be a hard one to write...the sole problem is method invocation off of string literals, to which I see no solution without direct intervention in the compiler.
Jul 13 2005
parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Charles Hixson" <charleshixsn earthlink.net> wrote in message 
news:db3s4k$tn9$1 digitaldaemon.com...
 Andrew Fedoniouk wrote:
...
 Walter, sorry for beating this horse again but D does not yet have 
 strings either.
 Very convenient character arrays and slices - yes. But strings (as value 
 type) -
 not yet. String  is an immutable value and has no analogues in D.
 D's char[] is just a StringBuffer/StringBuilder. And this is main concern 

 enterprise developers. They just get used to such String robustness.
 BTW: modern java.lang.String implementation is capable to represent 
 string slices too.
Perhaps allowing Java terminology to define things isn't exactly fair. Many languages have had mutable strings (often, admittedly, by accident). Being mutable DOESN'T mean it isn't a string, it means it's not a Java String class, which nobody ever claimed it was.
String is an immutable value. Consider this: char [] key = "one"; int [char[] ] map; map[ key ] = 1; key[0] = 'a'; This will ruin your map, isn't it?
 Perhaps allowing Java terminology to define things isn't exactly fair.
I am using String not only as Java string but as entity describing "immutable string value": In C you have char* and const char* In C++ you have std::string and const std::string In Java you have String and StringBuffer In Delphi you also able to use const Strings (limitied cases)
 OTOH, a char[] isn't really a full fledged string, even with slicing. 
 It's quite close, but not quite there.  To get to String status you need 
 to do something like importing std.string. But char[]'s really build in 
 most features that need to be built in.  Basically what should be added is 
 some special magic so that if you import std.string, the std.string 
 methods are all available as methods of variables/literals of type char[], 
 so you would be able to do things like:
 j = "This is a test".rfind("is");
Try to write it: "This is a test".rfind("is"); It should run flawlessly. By some accident D allows to do such trick with array parameters.
 Even that isn't quite perfect.  It would be nice to be able to do things 
 like:
 s = "This is a test";
 s.removechars("/is/");  //   N.B.:  Note the /'s this should mean
                         //       "interpret this as a pattern"
 Notice that the syntax has changed a bit from the current usage as this is 
 now a method invocation rather than a function call.
As I mentioned if removechars is declared as void removechars(char[],char[]) then you can call it as s.removechars("/is/"); I wouldn't rely on this behavior though as it is not specified - "D's hidden treasure"
 Also notice that this function would need to realize that it's arguments 
 couldn't be const's. (A standard requirement, but another change from the 
 current approach.)

 This might even be a reasonable approach, given that already char[]'s need 
 to be converted to Stringz if one wants to use them in C.

 OTTH (or is this the fourth hand), perhaps this extension is better 
 handled with a library.  I don't even think it would be a hard one to 
 write...the sole problem is method invocation off of string literals, to 
 which I see no solution without direct intervention in the compiler.
literals as they are immutable by nature.
Jul 13 2005
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Andrew Fedoniouk wrote:

 I am using String not only as Java string but as entity describing
 "immutable string value":
 
 In C you have char* and const char*
 In C++ you have std::string and const std::string
 In Java you have String and StringBuffer

 In Delphi you also able to use const Strings (limitied cases)
And in D you have char[] and char[] Some people find that confusing :-) Seriously, D does have two types of strings too - it is "just" that the compiler doesn't enforce any difference between them, so one just has the Gentlemen's Agreement to honor the C-o-w*. (*See http://en.wikipedia.org/wiki/Copy-on-write, or Phobos doc) And just like you (and several others) I think it would be very nice if there was some addition to the language to make it able to separate between them, and enforce the (default) immutability. But it still needs some nice new D syntax... Maybe: "char [inout]", or "mutable char[]" ? --anders PS. Inspired by NSString/NSMutableString and NSArray/NSMutableArray, and their other similar friends, from NeXTSTEP and Objective-C : http://www.gnustep.org/resources/OpenStepSpec/FoundationKit/Classes/NSString.html But "mutable" does have the issues with the local variables raised by Walter, basically them being something of a pain to add there ? http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D/26096 Still seems like the lesser evil to me, but that's up to Walter...
Jul 13 2005
parent reply Brad Beveridge <brad somewhere.net> writes:
Anders F Björklund wrote:

 Seriously, D does have two types of strings too - it is "just"
 that the compiler doesn't enforce any difference between them,
 so one just has the Gentlemen's Agreement to honor the C-o-w*.
 
 (*See http://en.wikipedia.org/wiki/Copy-on-write, or Phobos doc)
 
Actually, the Wikipedia entry on COW disagrees with D's take on COW. From Wikipedia "This fiction can be maintained until a caller tries to modify its "copy" of the resource, at which point a true private copy is created to prevent the changes becoming visible to everyone else. All of this happens transparently to the callers." The key thing being "all this happens transparently to callers", in D's take on COW the callers must explicitly manage their own COW. Now, as a thought experiment imagine that COW in D was transparent. Imagine that when you returned an array in D it acted just as it does now, except that when you wrote to it, the D compiler/runtime automatically duped it and you wrote to your own array. Would this make a difference to how we programed? Certainly it would make the idea that we needed immutable strings go away (all arrays are effectively immutable). Now of course we would need some mechanism for actually returning a modifiable array. Thoughts? Brad
Jul 13 2005
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Brad Beveridge wrote:

 The key thing being "all this happens transparently to callers", in D's 
 take on COW the callers must explicitly manage their own COW.
Right, it's not that transparent for the routine that modifies a string. (i.e. if you write to it, you need to .dup it - or similar - yourself)
 Now, as a thought experiment imagine that COW in D was transparent. 
 Imagine that when you returned an array in D it acted just as it does 
 now, except that when you wrote to it, the D compiler/runtime 
 automatically duped it and you wrote to your own array.  Would this make 
 a difference to how we programed?  Certainly it would make the idea that 
 we needed immutable strings go away (all arrays are effectively 
 immutable).  Now of course we would need some mechanism for actually 
 returning a modifiable array.  Thoughts?
It would be nice, but is hard to implement outside the MMU sphere... See this old post http://www.digitalmars.com/drn-bin/wwwnews?D/27605 --anders
Jul 13 2005
parent reply Brad Beveridge <brad somewhere.net> writes:
Anders F Björklund wrote:
 Brad Beveridge wrote:
 
<snip>
 
 It would be nice, but is hard to implement outside the MMU sphere...
 See this old post http://www.digitalmars.com/drn-bin/wwwnews?D/27605
 
 --anders
Any particular reason that we need to move outside of the MMU sphere? About the only one that I can think of is the fact that MMUs work with fixed sized pages, so you will loose some memory due to page wastage. I was thinking it should be possible to do something like char[] dynamic = "Thlkjdhlaksdjfj"; char[] locked = dynamic.MMUlock; locked.MMUunlock; MMUlock dupes the array into a new page & uses OS specific functions to lock down the MMU page to read onlyness. MMUunlock is not needed, except to release the page. I don't know if the locked MMU page can be under GC control or not. Also MMUlock would need to be synchronized. In this way you will generate runtime exceptions when people accidentally write to the locked array, and you won't incur any runtime overhead. I might try to implement something like this tonight. Brad
Jul 13 2005
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Brad Beveridge wrote:

 Any particular reason that we need to move outside of the MMU sphere? 
 About the only one that I can think of is the fact that MMUs work with 
 fixed sized pages, so you will loose some memory due to page wastage.
I don't know, it just sounded like a portability nightmare - much like how the current handling of "null pointer dereferencing" works in D...?
 I might try to implement something like this tonight.
Let us know how it goes, it all brings back memories of doing hacks like "video-on-segfault" to optimize emulator video performance... (Basilisk) --anders
Jul 13 2005
parent reply Brad Beveridge <brad somewhere.net> writes:
Anders F Björklund wrote:
 Brad Beveridge wrote:
 
 Any particular reason that we need to move outside of the MMU sphere? 
 About the only one that I can think of is the fact that MMUs work with 
 fixed sized pages, so you will loose some memory due to page wastage.
I don't know, it just sounded like a portability nightmare - much like how the current handling of "null pointer dereferencing" works in D...?
 I might try to implement something like this tonight.
Let us know how it goes, it all brings back memories of doing hacks like "video-on-segfault" to optimize emulator video performance... (Basilisk) --anders
Well, I'm sure that there will be portibility issues - but as far as I know, all OSes/CPUs that D will run on will support some sort of MMU protection. The actual handling of the exception trap might be a little hairy (as you say, like the null pointer now) - but I think all debuggers will trap the exception if nothing else. Brad
Jul 13 2005
parent reply brad beveridge <brad nowhere.com> writes:
Well, I have done a very simple proof of concept.  It only works under 
linux, and basically memory protecting pages in userspace isn't as nice 
or easy as I would like.  You basically need to create an actual file, 
and them mmap it.  Though I don't think the disk file actually gets 
anything written to.  To implement this properly you would need to be 
able to unlock memory pages, hook into the GC somehow, and reclaim empty 
areas of the memory mapped file.

In short, this is possible to do but pretty ugly to implement, and 
locking/unlocking may be expensive.  Though if the runtime implemented 
it then average joe programmers wouldn't see the ugliness.

Here is the code, do what you will with it :)

Brad

import std.stdio;
import std.c.linux.linuxextern;
import std.c.linux.linux;
import std.string;

int global_fd;

static this ()
{
     char[] junk = "t";
     global_fd = open ("tempfile", O_CREAT | O_RDWR, 0600);
     if (global_fd == -1)
     {
         writefln ("Error 0");
     }
     // don't know why I have to do this, but if the file is empty you
     // cannot write to it after it is mmaped
     write (global_fd,junk, 1);
}

static ~this ()
{
     close (global_fd);
     remove ("tempfile");
}

char[] MMU_lock(char[] array)
{
     void *p;
     void *r;
     char[] readonly;
     p = mmap(null, array.length, PROT_READ | PROT_WRITE, MAP_SHARED, 
global_fd, 0);
     if (p == MAP_FAILED)
     {
         writefln ("Error 1");
         return null;
     }
     writefln ("P is %x", p);
     memcpy (p, array, array.length);

     r = mmap(null, array.length, PROT_READ, MAP_SHARED, global_fd, 0);
     munmap(p, array.length);
     if (r == MAP_FAILED)
     {
         writefln ("Error 2");
         return null;
     }
     writefln ("R is %x", r);
     readonly = cast(char[])r[0 .. array.length];
     return readonly;
}

char[] MMU_unlock(char[] array)
{
}

int main(char[][] args)
{
     char[] stat = "This is a static String";
     char[] d = stat.dup;
     d[0] = 't';
     char[] ro = MMU_lock(d);
     writefln ("ro string is :: %s %d %x", ro, ro.length, ro.ptr);
     writefln ("About to write to ro string");
     ro[0] = 'T';  // this causes a segfault
     writefln ("Done and finished");
     return 1;
}
Jul 13 2005
parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
"brad beveridge" <brad nowhere.com> wrote in message 
news:db4jab$1gnu$1 digitaldaemon.com...
 Well, I have done a very simple proof of concept.  It only works under 
 linux, and basically memory protecting pages in userspace isn't as nice or 
 easy as I would like.  You basically need to create an actual file, and 
 them mmap it.  Though I don't think the disk file actually gets anything 
 written to.  To implement this properly you would need to be able to 
 unlock memory pages, hook into the GC somehow, and reclaim empty areas of 
 the memory mapped file.

 In short, this is possible to do but pretty ugly to implement, and 
 locking/unlocking may be expensive.  Though if the runtime implemented it 
 then average joe programmers wouldn't see the ugliness.

 Here is the code, do what you will with it :)

 Brad

 import std.stdio;
 import std.c.linux.linuxextern;
 import std.c.linux.linux;
 import std.string;

 int global_fd;

 static this ()
 {
     char[] junk = "t";
     global_fd = open ("tempfile", O_CREAT | O_RDWR, 0600);
     if (global_fd == -1)
     {
         writefln ("Error 0");
     }
     // don't know why I have to do this, but if the file is empty you
     // cannot write to it after it is mmaped
     write (global_fd,junk, 1);
 }

 static ~this ()
 {
     close (global_fd);
     remove ("tempfile");
 }

 char[] MMU_lock(char[] array)
 {
     void *p;
     void *r;
     char[] readonly;
     p = mmap(null, array.length, PROT_READ | PROT_WRITE, MAP_SHARED, 
 global_fd, 0);
     if (p == MAP_FAILED)
     {
         writefln ("Error 1");
         return null;
     }
     writefln ("P is %x", p);
     memcpy (p, array, array.length);

     r = mmap(null, array.length, PROT_READ, MAP_SHARED, global_fd, 0);
     munmap(p, array.length);
     if (r == MAP_FAILED)
     {
         writefln ("Error 2");
         return null;
     }
     writefln ("R is %x", r);
     readonly = cast(char[])r[0 .. array.length];
     return readonly;
 }

 char[] MMU_unlock(char[] array)
 {
 }

 int main(char[][] args)
 {
     char[] stat = "This is a static String";
     char[] d = stat.dup;
     d[0] = 't';
     char[] ro = MMU_lock(d);
     writefln ("ro string is :: %s %d %x", ro, ro.length, ro.ptr);
     writefln ("About to write to ro string");
     ro[0] = 'T';  // this causes a segfault
     writefln ("Done and finished");
     return 1;
 }
Thanks, Brad. Extremely cool. Concept car looked nice but was not moving :) BTW: on Windows you would use VirtualAlloc for that. With the same result, though. And try to imagine that you are passing something like root node of some XML DOM into function designed to return second child node....
Jul 13 2005
parent reply Brad Beveridge <brad somewhere.net> writes:
Andrew Fedoniouk wrote:

 
 Thanks, Brad. Extremely cool.
 Concept car looked nice but was not moving :)
 
 BTW: on Windows you would use VirtualAlloc for that.
 With the same result, though.
 
 And try to imagine that you are passing something
 like root node of some XML DOM into function
 designed to return second child node....
 
 
:) That's pretty much what I thought. But it was worth a shot to see if something could be done - we do after all have an MMU so we should try to use it :) Brad
Jul 14 2005
parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Brad Beveridge" <brad somewhere.net> wrote in message 
news:db600b$2to6$1 digitaldaemon.com...
 Andrew Fedoniouk wrote:

 Thanks, Brad. Extremely cool.
 Concept car looked nice but was not moving :)

 BTW: on Windows you would use VirtualAlloc for that.
 With the same result, though.

 And try to imagine that you are passing something
 like root node of some XML DOM into function
 designed to return second child node....
:) That's pretty much what I thought. But it was worth a shot to see if something could be done - we do after all have an MMU so we should try to use it :)
Yep. But *we* do not have MMU. It is OS who has it. Andrew.
Jul 14 2005
parent reply Brad Beveridge <brad somewhere.net> writes:
Andrew Fedoniouk wrote:

:) That's pretty much what I thought.  But it was worth a shot to see if 
something could be done - we do after all have an MMU so we should try to 
use it :)
Yep. But *we* do not have MMU. It is OS who has it. Andrew.
True. I program device drivers & OS level stuff for a day job, so I tend to think about things as they are close to the hardware. It is a shame that user applications don't have better control of the MMU in modern OSes - but such is life :) Brad
Jul 14 2005
parent "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Brad Beveridge" <brad somewhere.net> wrote in message 
news:db6o65$hug$1 digitaldaemon.com...
 Andrew Fedoniouk wrote:

:) That's pretty much what I thought.  But it was worth a shot to see if 
something could be done - we do after all have an MMU so we should try to 
use it :)
Yep. But *we* do not have MMU. It is OS who has it. Andrew.
True. I program device drivers & OS level stuff for a day job, so I tend to think about things as they are close to the hardware. It is a shame that user applications don't have better control of the MMU in modern OSes - but such is life :)
I see you are a bit pessimistic about life... Well, it has good sides too. Just need to take a gaze and you'll see... For example here is a shot named "Furniture for eXtreme Programming. Chair." http://www.terrainformatica.com/screenshots/xpchair.jpg I've made it in my office week ago. Disclaimer: For those who practicing XP - nothing personal. Andrew.
Jul 14 2005
prev sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Wed, 13 Jul 2005 15:43:31 -0700, Brad Beveridge <brad somewhere.net>  
wrote:
 Anders F Björklund wrote:

 Seriously, D does have two types of strings too - it is "just"
 that the compiler doesn't enforce any difference between them,
 so one just has the Gentlemen's Agreement to honor the C-o-w*.
  (*See http://en.wikipedia.org/wiki/Copy-on-write, or Phobos doc)
Actually, the Wikipedia entry on COW disagrees with D's take on COW. From Wikipedia "This fiction can be maintained until a caller tries to modify its "copy" of the resource, at which point a true private copy is created to prevent the changes becoming visible to everyone else. All of this happens transparently to the callers." The key thing being "all this happens transparently to callers", in D's take on COW the callers must explicitly manage their own COW. Now, as a thought experiment imagine that COW in D was transparent. Imagine that when you returned an array in D it acted just as it does now, except that when you wrote to it, the D compiler/runtime automatically duped it and you wrote to your own array. Would this make a difference to how we programed? Certainly it would make the idea that we needed immutable strings go away (all arrays are effectively immutable). Now of course we would need some mechanism for actually returning a modifiable array. Thoughts?
I think the default case would be mutable, eg char[] foo() {} returns a mutable array, however: readonly char[] foo() {} returns an immutable one. An array declared in the current scope would default to being mutable, eg. char[] bar; it would be mutable and not create a duplicate when you wrote to it (in this scope). Passing it to an 'in' parameter would treat is as immutable, causing a dup on write, eg. void foobar(char[] p) { p[0] = 'a'; } Assigning a mutable reference to an immutable one would make the mutable immutable. eg. immutable char[] p; char[] s; s = p; //s is now immutable. The question is how do you implement this sort of thing. It's essentially an Auto Pointer or Reference Counter, there seem to be 2 choices for implementation: 1. runtime mutable bit flag. (if false dup, set to true on copy) 2. 2 distinct types. (writing to immutable type, creates mutable copy) Though it might be possible for the compiler to determine at compile time the cases where a dup is required and for it to silently insert them into the code during compile. Not sure if that makes sense, just floating the idea. Regan p.s. This is essentially the readonly idea I have posted before. What can I say, I think it works as an idea. The implementation is the difficult part. (as Anders has just posted)
Jul 13 2005
parent reply =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Regan Heath wrote:

 I think the default case would be mutable, eg
   char[] foo() {}
 
 returns a mutable array, however:
   readonly char[] foo() {}
 
 returns an immutable one.
I think the default case should be immutable... AFAIK, it already is - although not enforced ? If nothing else, "const char *" is boring to type, and I don't think "readonly char[]" would be less. Better to have readwrite/mutable for "the other 10%", than having a readonly/immutable applied to "most" ? --anders
Jul 13 2005
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 14 Jul 2005 01:30:11 +0200, Anders F Björklund <afb algonet.se>  
wrote:
 Regan Heath wrote:

 I think the default case would be mutable, eg
   char[] foo() {}
  returns a mutable array, however:
   readonly char[] foo() {}
  returns an immutable one.
I think the default case should be immutable... AFAIK, it already is - although not enforced ?
Well, COW dictates you should be copying it before you write, so, yes, all arrays are immutable though not enforced. I think it should be mutable because I think if you return something, most of the time it's the only copy, and you're not holding it anywhere i.e. char[] toString(int i); Of course class members might return references or slices to internal data, then you'd use 'readonly'. I don't think this is as common as returning a new array, one that can safely be written to. I might be wrong.
 If nothing else, "const char *" is boring to type,
 and I don't think "readonly char[]" would be less.
True. Which is why I chose 'mutable' as the default, I think it's more common, thus less typing. You obviously disagree. Only code analysis will tell us for sure, and then I suspect different types/areas will show a different result.
 Better to have readwrite/mutable for "the other 10%",
 than having a readonly/immutable applied to "most" ?
I disagree with 10%, and "most", obviously. Regan
Jul 13 2005
parent reply =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Regan Heath wrote:

 True. Which is why I chose 'mutable' as the default, I think it's more  
 common, thus less typing. You obviously disagree. Only code analysis 
 will  tell us for sure, and then I suspect different types/areas will 
 show a  different result.
Actually, I think "immutable" is the most common case for parameters. As for local variables, there it is pretty common to want "mutable" ? Too bad that the C++ usage of the keywords "const" and "mutable" have muddied the waters enough to make any discussion about it confusing... Meanwhile, it seems it's back to the usual warnings on the wrapping: "use caution.contents might be hot.slippery when wet.immutable inside" >> Better to have readwrite/mutable for "the other 10%",
 than having a readonly/immutable applied to "most" ?
I disagree with 10%, and "most", obviously.
Obviously. I don't have any numbers to back it up - I just meant it as in the 90/10 rule... (a.k.a. 80/20 rule, etc). As in common/uncommon ? It also assumes that you can do a _whole lot_ of manipulation with immutable strings, just not change the referenced contents directly. i.e. you could still concat strings and use functions to convert it to upper case and so and so forth. (by creating new immutable copies) Actual syntax could probably still need some design work, though. (but I'm supposed to be on summer vacation soon, so I'll leave it) --anders
Jul 14 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 14 Jul 2005 09:46:35 +0200, Anders F Björklund <afb algonet.se>  
wrote:

 Regan Heath wrote:

 True. Which is why I chose 'mutable' as the default, I think it's more   
 common, thus less typing. You obviously disagree. Only code analysis  
 will  tell us for sure, and then I suspect different types/areas will  
 show a  different result.
Actually, I think "immutable" is the most common case for parameters.
I agree. I was talking about return values being mutable.
 As for local variables, there it is pretty common to want "mutable" ?
Yep. That's what I said too.
 Too bad that the C++ usage of the keywords "const" and "mutable" have
 muddied the waters enough to make any discussion about it confusing...
You may have miss-read what I wrote?
 Meanwhile, it seems it's back to the usual warnings on the wrapping:
 "use caution.contents might be hot.slippery when wet.immutable inside"
LOL.
   >> Better to have readwrite/mutable for "the other 10%",
 than having a readonly/immutable applied to "most" ?
I disagree with 10%, and "most", obviously.
Obviously. I don't have any numbers to back it up - I just meant it as in the 90/10 rule... (a.k.a. 80/20 rule, etc). As in common/uncommon ? It also assumes that you can do a _whole lot_ of manipulation with immutable strings, just not change the referenced contents directly. i.e. you could still concat strings and use functions to convert it to upper case and so and so forth. (by creating new immutable copies) Actual syntax could probably still need some design work, though. (but I'm supposed to be on summer vacation soon, so I'll leave it)
Here is a summary of what I expect to be common. return values: mutable local variables: mutable parameters: immutable Regan
Jul 14 2005
parent reply =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Regan Heath wrote:

 Too bad that the C++ usage of the keywords "const" and "mutable" have
 muddied the waters enough to make any discussion about it confusing...
You may have miss-read what I wrote?
Could be, we seem to be in agreement. (now it's "just the details")
 Here is a summary of what I expect to be common.
 
 return values: mutable
 local variables: mutable
 parameters: immutable
I think e.g. "char[] toString()" should return an immutable string. String literals should definitely be immutable, as well. (local too) But I do need to write more D code, in order to test this out fully. --anders
Jul 14 2005
parent "Regan Heath" <regan netwin.co.nz> writes:
On Thu, 14 Jul 2005 11:25:03 +0200, Anders F Björklund <afb algonet.se>  
wrote:
 Regan Heath wrote:

 Too bad that the C++ usage of the keywords "const" and "mutable" have
 muddied the waters enough to make any discussion about it confusing...
You may have miss-read what I wrote?
Could be, we seem to be in agreement. (now it's "just the details")
 Here is a summary of what I expect to be common.
  return values: mutable
 local variables: mutable
 parameters: immutable
I think e.g. "char[] toString()" should return an immutable string.
Maybe, maybe not, whatever is most common.
 String literals should definitely be immutable, as well. (local too)
Yeah, I agree. You can always .dup for a mutable one.
 But I do need to write more D code, in order to test this out fully.
In cases where it's a class method the return value is more likely to be immutable, for a normal function (unless it's returning static data, as toString does) it's more likely to be mutable, or so I reasoned. Regan
Jul 14 2005
prev sibling parent reply "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Anders F Björklund" <afb algonet.se> wrote in message 
news:db4863$17dt$1 digitaldaemon.com...
 Regan Heath wrote:

 I think the default case would be mutable, eg
   char[] foo() {}

 returns a mutable array, however:
   readonly char[] foo() {}

 returns an immutable one.
I think the default case should be immutable... AFAIK, it already is - although not enforced ? If nothing else, "const char *" is boring to type, and I don't think "readonly char[]" would be less. Better to have readwrite/mutable for "the other 10%", than having a readonly/immutable applied to "most" ? --anders
Other choices : C99 trigraphs style char[<>], char[:], etc.
Jul 13 2005
parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Andrew Fedoniouk wrote:


Alternative: The argument "char[inout]" (contents) would be pretty similar to "inout char[]" (reference), but still a bit hard to decipher ? (that is: the first would be like "const char*", and the second would be like "char* const" BTW; The "readonly" attribute was only a less-loaded const alternative. But it seems like it still burdened by all the Const Correctness... --anders
Jul 14 2005
parent "Andrew Fedoniouk" <news terrainformatica.com> writes:
"Anders F Björklund" <afb algonet.se> wrote in message 
news:db57bf$27s3$1 digitaldaemon.com...
 Andrew Fedoniouk wrote:


Alternative: The argument "char[inout]" (contents) would be pretty similar to "inout char[]" (reference), but still a bit hard to decipher ? (that is: the first would be like "const char*", and the second would be like "char* const" BTW; The "readonly" attribute was only a less-loaded const alternative. But it seems like it still burdened by all the Const Correctness... --anders
I've already published this proposal, I'll repeat it then: ---------------------------------------------------------- Possible syntax for immutable arrays and pointers. declarations: // arrays char a[]; // RW array/slice char a[ 100 ] ; // static RW array/slice. // pointers char * pa; // RW pointer // associative arrays/maps int[ char[] ] a; // RW map ---------------------------- Rationale: readonly attribute syntacticaly should be as close as possible to array/pointer designator ( [ ] ), ideally it should be part of it. Andrew. http://terrainformatica.com
Jul 14 2005
prev sibling parent Hasan Aljudy <hasan.aljudy gmail.com> writes:
This is cool, except it's not documented.

Can I assume that this is how native-type-methods are implemented in D?
And is that behaviour intended or is it just a bug? (I'm referring to 
the behaviour that Andrew explained)

Walter? Are you reading this?

Andrew Fedoniouk wrote:
OTOH, a char[] isn't really a full fledged string, even with slicing. 
It's quite close, but not quite there.  To get to String status you need 
to do something like importing std.string. But char[]'s really build in 
most features that need to be built in.  Basically what should be added is 
some special magic so that if you import std.string, the std.string 
methods are all available as methods of variables/literals of type char[], 
so you would be able to do things like:
j = "This is a test".rfind("is");
Try to write it: "This is a test".rfind("is"); It should run flawlessly. By some accident D allows to do such trick with array parameters.
Even that isn't quite perfect.  It would be nice to be able to do things 
like:
s = "This is a test";
s.removechars("/is/");  //   N.B.:  Note the /'s this should mean
                        //       "interpret this as a pattern"
Notice that the syntax has changed a bit from the current usage as this is 
now a method invocation rather than a function call.
As I mentioned if removechars is declared as void removechars(char[],char[]) then you can call it as s.removechars("/is/"); I wouldn't rely on this behavior though as it is not specified - "D's hidden treasure"
Jul 13 2005
prev sibling parent reply Dejan Lekic <leka entropy.tmok.com> writes:
Nick wrote:

 - No garbage collection
 - Member function pointers (ie. no delegates)
 - Lack of "abstract" and "typeof" keywords
 - No modules, and the namespace system is a hack to try to fix this
 - Memory safety and language safety in general
 - Too many complicated and unecessary language rules
As "many years C++ developer" I can say: 1) IMHO it is a good choice not to give garbage collection to the core language - this way people can use variety of GC implementations, for different purposes... 2) Same as previous - there are thousands of excellent delegate-like libraries, some type-safe, some not - again for all tastes. 3) We (C++) developers do not need an abstract keyword to know that our class is an abstract class. Secondly - there is typeof keyword! 4) If one (developer) writes safe code, follows C++ priciples, basically - disciplined C++ programmer, he'll write more safe program than (IMHO the safest) Modula-3 or ADA programers. 5) Again, You do not need to follow them all - it is UP YOU! :) Kind regards Dejan -- ........... Dejan Lekic http://dejan.lekic.org
Jul 11 2005
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Tue, 12 Jul 2005 00:18:01 +0200, Dejan Lekic <leka entropy.tmok.com>  
wrote:
 Nick wrote:

 - No garbage collection
 - Member function pointers (ie. no delegates)
 - Lack of "abstract" and "typeof" keywords
 - No modules, and the namespace system is a hack to try to fix this
 - Memory safety and language safety in general
 - Too many complicated and unecessary language rules
This is not an attack on C++, nor your defence of it.
 As "many years C++ developer" I can say:

 1) IMHO it is a good choice not to give garbage collection to the core
 language - this way people can use variety of GC implementations, for
 different purposes...
If any GC can be plugged in, or completely disabled you've achieved the same end, in a better way.
 2) Same as previous - there are thousands of excellent delegate-like
 libraries, some type-safe, some not - again for all tastes.
Are any as easy to use as a built in solution can be? How many different ways are there to do delegates? I recall recently someone wanting to copy the stack, ideally any difference in goal like this would be customizable with a built in solution. Ideally the language should be powerful enough to allow you to write a library delegate to achieve any goal not already supported by the built in solution.
 3) We (C++) developers do not need an abstract keyword to know that our
 class is an abstract class. Secondly - there is typeof keyword!
Having a keyword is useful, it clearly states the programmers intent - allowing the compiler to verify that intent and it documents to the next developer the intent, again allowing verification. This is a general statement not specific to any particular keyword.
 4) If one (developer) writes safe code, follows C++ priciples, basically  
 -
 disciplined C++ programmer, he'll write more safe program than (IMHO the
 safest) Modula-3 or ADA programers.
I smell a language war brewing. You could remove the word "C++" from the above, change the part which begins "(IMHO.." to read "otherwise" and it would be a much truer statement IMO, eg. "If one (developer) writes safe code, follows priciples, basically disciplined programmer, he'll write more safe program than otherwise" Sure, each language provides more or less in the way of safety but in the end it's the individual developer that matters.
 5) Again, You do not need to follow them all - it is UP YOU! :)
I assume the word "to" is missing from that last statement? ;) Regan
Jul 11 2005
parent reply Dejan Lekic <leka entropy.tmok.com> writes:
No, I do not defend C++ - If I was so deeply in love in it I would not use

languages from the list)... I just dislike common anti-c++ articles, even
if they make sense, because we, developers, use what we are familiar with,
and what "does the job" (TM). :)

-- 
...........
Dejan Lekic
  http://dejan.lekic.org
  
Jul 11 2005
parent reply Charles Hixson <charleshixsn earthlink.net> writes:
Dejan Lekic wrote:
 No, I do not defend C++ - If I was so deeply in love in it I would not use

 languages from the list)... I just dislike common anti-c++ articles, even
 if they make sense, because we, developers, use what we are familiar with,
 and what "does the job" (TM). :)
 
OTOH, while there are occasions where one wants to disable or replace the garbage collection, they are (or should be) the exceptional cases. As it is most C/C++ programmers have no access to ANY garbage collection. You may say "Well, if they just...", but the answer has to be "They don't". I have heard it seriously asserted that the largest improvement in computer languages over the last 20 years was the common inclusion of garbage collectors. I don't know on what basis this assertion was made, but the person making it was widely respected and definitely believed it. Apparently dangling pointers, invalid array references, etc. were sufficiently common that just getting rid of them was a bigger improvement than either Object oriented programming or even structured programming (but perhaps that was more than 20 years ago?). Of course, it may also have had a bit of hyperbole in it, but don't write off the importance of Garbage Collection just because it's occasionally imperfect.
Jul 13 2005
next sibling parent llothar <llothar_member pathlink.com> writes:
In article <db3slk$u4n$1 digitaldaemon.com>, Charles Hixson says...

OTOH, while there are occasions where one wants to disable or 
replace the garbage collection, they are (or should be) the 
exceptional cases.  As it is most C/C++ programmers have no 
access to ANY garbage collection.  You may say "Well, if they 
I posted a GC question today is is not fully answered but enough to say: Every C/C++ programmer have as much GC at there hand as a D programmer. They just need to link in Boehms GC , then you need just a few lines of code to replace the standart new/delete/delete[] and a one liner for each class that should have a finalizer call (which is not so much typing overhead).
Jul 13 2005
prev sibling parent reply Mike Capp <mike.capp gmail.com> writes:
In article <db3slk$u4n$1 digitaldaemon.com>, Charles Hixson says...
I have heard it 
seriously asserted that the largest improvement in computer 
languages over the last 20 years was the common inclusion of 
garbage collectors. [...] Apparently dangling pointers, invalid 
array references, etc. were sufficiently common that just getting 
rid of them was a bigger improvement than either Object oriented 
programming or even structured programming (but perhaps that was 
more than 20 years ago?).
SP is *way* more than 20 years old. OO is coming up on 40 (since Simula inroduced it in '67). So I'm not sure what improvements the speaker was comparing GC to. STL-style generics, maybe?
don't write off the importance of Garbage 
Collection just because it's occasionally imperfect.
Oh, I don't. There's no question at all about programmer productivity in GC languages, and I'm slowly coming round to accept that for long-lived objects the benefits might outweight the nasty unpredictability drawbacks. I'm still convinced that GC is massive overkill for local-scoped class variables and (to a lesser extent) simple value-like class members. C++'s default stack allocation is a far better story than D on this front.
Jul 13 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Mike Capp" <mike.capp gmail.com> wrote in message
news:db40ld$11b1$1 digitaldaemon.com...
 I'm still convinced that GC is massive overkill for local-scoped class
variables
 and (to a lesser extent) simple value-like class members. C++'s default
stack
 allocation is a far better story than D on this front.
"simple value-like class" object instances in D are called structs and are allocated on the stack.
Jul 14 2005
parent reply Mike Capp <mike.capp gmail.com> writes:
In article <db63at$31dn$3 digitaldaemon.com>, Walter says...
"Mike Capp" <mike.capp gmail.com> wrote 
 GC is massive overkill for local-scoped class variables
 and (to a lesser extent) simple value-like class members. C++'s default
 stack allocation is a far better story than D on this front.
"simple value-like class" object instances in D are called structs and are allocated on the stack.
D structs correspond to C structs or C++ POD types, not to lightweight C++ value types in general. D seems to fall into the same trap as Java in thinking that OO only applies to Big Heavyweight Types, and that lightweight types can't possibly need encapsulation or any of that guff. Take something trivial like a UnitVector3: a vector of three floats with a magnitude of 1. It's smaller than builtins like cdouble, and it's normally going to appear as a temporary, local-scoped variable or member of a larger aggregate type. It's situations like this where GC looks like massive overkill; if you're doing a lot of calculation with these things you're going to get a lot of unnecessary gen0 churn. D structs are no help at all for use cases like this. The interesting part of UnitVector3 is the invariant, and while you can specify an invariant for a D struct, it feels a bit like mocking the poor thing because the struct has no way to establish or preserve that invariant. No constructors, no protection attributes, so what's the point? (Protection atts in structs are accepted by the compiler, and even appear in some doc examples e.g. "Properties", but aren't enforced as of 0.128.) Implementing (and guaranteeing) stack allocation for 'auto' class instances would help a bit, but only a bit, because autos can't be returned or passed around like values. cheers Mike
Jul 14 2005
parent reply "Ben Hinkle" <ben.hinkle gmail.com> writes:
"Mike Capp" <mike.capp gmail.com> wrote in message 
news:db6tl0$m1d$1 digitaldaemon.com...
 In article <db63at$31dn$3 digitaldaemon.com>, Walter says...
"Mike Capp" <mike.capp gmail.com> wrote
 GC is massive overkill for local-scoped class variables
 and (to a lesser extent) simple value-like class members. C++'s default
 stack allocation is a far better story than D on this front.
"simple value-like class" object instances in D are called structs and are allocated on the stack.
D structs correspond to C structs or C++ POD types, not to lightweight C++ value types in general. D seems to fall into the same trap as Java in thinking that OO only applies to Big Heavyweight Types, and that lightweight types can't possibly need encapsulation or any of that guff. Take something trivial like a UnitVector3: a vector of three floats with a magnitude of 1. It's smaller than builtins like cdouble, and it's normally going to appear as a temporary, local-scoped variable or member of a larger aggregate type. It's situations like this where GC looks like massive overkill; if you're doing a lot of calculation with these things you're going to get a lot of unnecessary gen0 churn. D structs are no help at all for use cases like this. The interesting part of UnitVector3 is the invariant, and while you can specify an invariant for a D struct, it feels a bit like mocking the poor thing because the struct has no way to establish or preserve that invariant.
Why not? Make the fields private with no setter.
 No constructors,
easily worked around for your example by specifying a init value where one of the fields is 1 (e.g. x) or using either a top-level function or the "static opCall" hack.
 no protection
 attributes, so what's the point? (Protection atts in structs are accepted 
 by the
 compiler, and even appear in some doc examples e.g. "Properties", but 
 aren't
 enforced as of 0.128.)
A bug in dmd.128 shouldn't make one conclude that structs in D (the language) have "no protection".
 Implementing (and guaranteeing) stack allocation for 'auto' class 
 instances
 would help a bit, but only a bit, because autos can't be returned or 
 passed
 around like values.
I would stick with structs.
Jul 14 2005
next sibling parent reply AJG <AJG_member pathlink.com> writes:
Hi there,

 D structs are no help at all for use cases like this. The interesting part 
 of
 UnitVector3 is the invariant, and while you can specify an invariant for a 
 D
 struct, it feels a bit like mocking the poor thing because the struct has 
 no way
 to establish or preserve that invariant.
Why not? Make the fields private with no setter.
Correct me if I'm wrong, but I believe that the private modifier has no effect on struct variable members. I'm on DMD/Linux 0.127 and I can do this: Foo.d ===== Bar.d ===== They're even on separate files to avoid the annoying default "friend" modifier. I don't know if this is a bug or "feature," but for consistency (at the least), I think private should be enforced. Cheers, --AJG.
Jul 14 2005
next sibling parent "Uwe Salomon" <post uwesalomon.de> writes:
 They're even on separate files to avoid the annoying default "friend"  
 modifier.
 I don't know if this is a bug or "feature," but for consistency (at the  
 least),
 I think private should be enforced.
Huh? I didn't know that. I really want to add a strong "Yes!" to that statement. The Indigo containers, for example, are heavily struct-based (nice example to see how much *is* possible with structs, by the way), and they don't like messing up their guts :) Ciao uwe
Jul 14 2005
prev sibling parent "Ben Hinkle" <ben.hinkle gmail.com> writes:
"AJG" <AJG_member pathlink.com> wrote in message 
news:db7hf0$181k$1 digitaldaemon.com...
 Hi there,

 D structs are no help at all for use cases like this. The interesting 
 part
 of
 UnitVector3 is the invariant, and while you can specify an invariant for 
 a
 D
 struct, it feels a bit like mocking the poor thing because the struct 
 has
 no way
 to establish or preserve that invariant.
Why not? Make the fields private with no setter.
Correct me if I'm wrong, but I believe that the private modifier has no effect on struct variable members. I'm on DMD/Linux 0.127 and I can do this:
That's a bug in dmd that will get fixed (as Mike mentioned, too). Don't worry about it.
Jul 15 2005
prev sibling parent Mike Capp <mike.capp gmail.com> writes:
In article <db74df$qk1$1 digitaldaemon.com>, Ben Hinkle says...
 No constructors,
easily worked around for your example by [...] the "static opCall" hack.
Hmm, that hadn't occurred to me. Thanks. Still some unnecessary copies going on, but the compiler backend can probably optimize those away.
A bug in dmd.128 shouldn't make one conclude that structs in D (the 
language) have "no protection".
It's not just a bug in 0.128; the grammar in the doc page for structs (unlike the one for classes) makes no mention at all of protection. I'd be happy to raise it again as a bug, though, if you think it stands any chance of being "fixed". cheers Mike
Jul 15 2005
prev sibling parent M <M_member pathlink.com> writes:
typeof keyword is not in C++ standard (as far as I know), it is add on in some
compilers like gnu c and gnu c++.

In article <dauqod$27hl$1 digitaldaemon.com>, Dejan Lekic says...
Nick wrote:

 - No garbage collection
 - Member function pointers (ie. no delegates)
 - Lack of "abstract" and "typeof" keywords
 - No modules, and the namespace system is a hack to try to fix this
 - Memory safety and language safety in general
 - Too many complicated and unecessary language rules
As "many years C++ developer" I can say: 1) IMHO it is a good choice not to give garbage collection to the core language - this way people can use variety of GC implementations, for different purposes... 2) Same as previous - there are thousands of excellent delegate-like libraries, some type-safe, some not - again for all tastes. 3) We (C++) developers do not need an abstract keyword to know that our class is an abstract class. Secondly - there is typeof keyword! 4) If one (developer) writes safe code, follows C++ priciples, basically - disciplined C++ programmer, he'll write more safe program than (IMHO the safest) Modula-3 or ADA programers. 5) Again, You do not need to follow them all - it is UP YOU! :) Kind regards Dejan -- ........... Dejan Lekic http://dejan.lekic.org
Jul 12 2005