digitalmars.D - First D project - some observations
- Mike (108/108) Feb 10 2006 Hi!
- Derek Parnell (28/60) Feb 10 2006 Welcome!
- Søren J. Løvborg (11/19) Feb 11 2006 That really shouldn't matter.
- Derek Parnell (19/42) Feb 11 2006 I agree with you that it shouldn't matter, but it does and all I did was...
- Jarrett Billingsley (30/32) Feb 11 2006 Not quite. In a = a + 1, "a" is evaluated twice. In a += 1, "a" is
- Nick (25/39) Feb 10 2006 Hi and welcome to the world of D! We're always glad to see someone's fre...
- Hasan Aljudy (7/165) Feb 10 2006 The same reasons I came to D :) except I don't have that long of an
- Unknown W. Brackets (7/19) Feb 10 2006 That's very strange. Were you compiling it with -release or something
- Georg Wrede (9/169) Feb 20 2006 There's nothing as valuable as these first-time experiences with D!!!
Hi! I wanted to share some observations of an experienced C++ programmer who has now spent his first 10-12 hours with D. First a little history on my project: I'm currently building a small vm (nothing fancy) for a little hobby project I'm doing. The vm is already running in C++, I just need to build a little, C-ish script parser around that thing. Anyway, I have a little declaration problem in C++. It's not the first time I have exactly this problem, and I solved it numerous times, but I'm getting tired of it, and more frustrated every time I have something like this. class Block; class Instruction { .. Block *MyScope; }; class Block : public Instruction { .. List<Instruction> MyInstructions; List<Symbol> MyLocalSymbols; Block *MyParent; }; Instruction needs to call Block to get it's symbols, Block has it's local symbols and gets undefined symbols from it's parent. If parent is NULL, this is the global block. Symbols can be variables or (nested) functions. That's the idea. But Instruction can't call Block's member functions, because Block is just a declarations. I stopped coding at that point, since I was frustrated, seeing myself AGAIN wasting hours with moving code around, inside and outside the class declaration to get that thing to compile. Ok, I could create a "symboltable" class and derive "block" from both "instruction" and "symboltable". But why? Why another class if it's just needed in one place anyhow? And: No wonder C++ needs multiple inheritance! So I decided to finally try out D. Downloaded latest versions of akIDE and DMD, and after about 30-45 minutes converting my ~500 lines C++ code to ~350 lines D code it ran exactly like before! Nice, I thought. So I've worked on that project yesterday and today and it went really well, so I feel the urge now to summarize my impressions so far: On the plus side: + No forward declarations/No header files I think that's the singlemost important thing to me about D. I hate those forward declarations, really. I hate them more than header files, which I hate a great deal, after numerous hours of playing solitaire while recompiling, because I had to add a new member to a base class. (And no more #incldue typos! :-) + Case "string", == for strings In that particular case of writing a parser this is a godsend, but I imagine this will come in handy in other areas as well. No more !strcmp. + The ~ operator Never again this: char buf[200]; sprintf(buf, "Error in blabla function (dbg: x = %i)", x); throw new exception(buf); Nice! + No ; after class definition This feels just natural. + this/super Great! Never again this: Long, descriptive class name with one hard to see typo, copy paste for three constructors and one descructor, compile, find out you made a typo. And makes it easier to change a class name, too. And I found this to be quite natural from the start, I never accidentally wrote a constructor the C++ way. + member initialization with =, rather than with initializer lists Another great thing, especially for me. I can't remember how many times I actually tried to initialize members via the D syntax, just to find out - d'oh, C++ can't do that. Forgot that again! Fits much better into the overall feel of a C-ish language than those initializer lists. + Dynamic Arrays Yes! + Garbage Collection Yes! Yes! Yes! On the - side: - Hard to find odd crashes I had some trouble, until I figured out that my program seemed to crash/exit immediatly whenever an exception was not caught. Couldn't the compiler catch errors like that? That was really annoying. The problems was that I had no idea about where the crash happened and it took quite some time to find it. Another thing was that on of my functions (defined as bit) accidentally had one path out of it without a return statement. Immediate crash when calling that function, again no error from the compiler. Every C++-compiler (iirc) catched things like that. These crashes are hard to find, really. Especially when you're not used to looking for something like THAT. - .length property can't be lvalue MyIntArray.length++; Why not? - class instantiation is a bit confusing, at least for c++ programmers I intuitively expect something like HelloWorldClass writehello; writehello.doIt(); NOT to crash the program. But, well, that's something I can life with :-) - no "bool" Can't there be an "alias bool bit;" built in? Summary: -------- I think I will start porting my C++ project over to D, since it's just a hobby project, so I have time to do that. And D is nearly the language that I wish C++ to be, honestly (add bool and it is :-). The crashes I mentioned make me wonder, since it wouldn't be too hard to find them at compile time, anyhow, maybe it's just me, I haven't found the time to play with the compiler settings. The things I brought up aren't really acedemic, but I like to get dirty while programming, change my design constantly because I just had that other idea that I NEED to try out. For that D seems to be just the right language. Very practical, I like that. Add to that about 7-8 years of frustration with C++ header files, forward declarations, externs, pointers to pointers and stuff, and I just have to say: D puts the fun back in programming! Thanks! So, wish you guys a nice day and be sure to watch BSG tonight :-) -Mike
Feb 10 2006
On Sat, 11 Feb 2006 02:59:24 +1100, Mike <Mike_member pathlink.com> wrote:Hi! I wanted to share some observations of an experienced C++ programmer who has now spent his first 10-12 hours with D.Welcome! [snip]On the - side: - Hard to find odd crashes I had some trouble, until I figured out that my program seemed to crash/exit immediatly whenever an exception was not caught. Couldn't the compiler catch errors like that? That was really annoying. The problems was that I had no idea about where the crash happened and it took quite some time to find it.The 'official' response is to use a debugger to locate the line that is crashing. And if you are using a Windows platform you have to use an old unsupported debugger that you can buy from DigitalMars.Another thing was that on of my functions (defined as bit) accidentally had one path out of it without a return statement. Immediate crash when calling that function, again no error from the compiler. Every C++-compiler (iirc) catched things like that. These crashes are hard to find, really. Especially when you're not used to looking for something like THAT.Try using the "-w" switch when compiling. I think it warns about these errors.- .length property can't be lvalue MyIntArray.length++; Why not?Because .length is not a (pseudo-)field, it is actually a (pseudo-)method. MyIntArray.length++; is equivalent to ... MyIntArray.length()++; which has no effect so is not allowed. MyIntArray.length = MyIntArray.length + 1; is equivalent to ... MyIntArray.length(MyIntArray.length() + 1);- class instantiation is a bit confusing, at least for c++ programmers I intuitively expect something like HelloWorldClass writehello; writehello.doIt(); NOT to crash the program. But, well, that's something I can life with :-)Yes, this is definitely a D thing. The rationale (I think) is that because class instances live on the heap, they must be explicitly constructed.- no "bool" Can't there be an "alias bool bit;" built in?Yes there is. I use it all the time. What happens when you try this ... import std.stdio; void main() { bool foo = 1; writefln(foo); } -- Derek Parnell Melbourne, Australia
Feb 10 2006
Mike <Mike_member pathlink.com> wrote:- .length property can't be lvalue MyIntArray.length++; Why not?"Derek Parnell" <derek psych.ward> wrote:Because .length is not a (pseudo-)field, it is actually a (pseudo-)method. MyIntArray.length++; is equivalent to ... MyIntArray.length()++; which has no effect so is not allowed.That really shouldn't matter. MyIntArray.length() = 5; is obviously not right, but that doesn't prevent MyIntArray.length = 5; from being the way to do it. Anywhere a = a + 1 works, a += 1 and a++ should work (or ++a, I guess), since they're semantically equivalent. Søren J. Løvborg web kwi.dk
Feb 11 2006
On Sun, 12 Feb 2006 07:43:45 +1100, Søren J. Løvborg <web kwi.dk> wrote:Mike <Mike_member pathlink.com> wrote:I agree with you that it shouldn't matter, but it does and all I did was to explain why. Look at the D 'property' functionality. Its the same deal there. class Foo { void Bar(int) { . . . } int Bar() { . . . } } Foo a = new Foo; a.Bar = 1; // calls a.Bar(1); x = a.Bar; // calls a.Bar(); You can't do a.Bar++ either because it sees this as a.Bar()++. You have to do a.Bar = a.Bar + 1; which it sees as a.Bar(a.Bar() + 1); I hope that one day the compiler can be made sophisticated enough to pick up on this anomaly. -- Derek Parnell Melbourne, Australia- .length property can't be lvalue MyIntArray.length++; Why not?"Derek Parnell" <derek psych.ward> wrote:Because .length is not a (pseudo-)field, it is actually a (pseudo-)method. MyIntArray.length++; is equivalent to ... MyIntArray.length()++; which has no effect so is not allowed.That really shouldn't matter. MyIntArray.length() = 5; is obviously not right, but that doesn't prevent MyIntArray.length = 5; from being the way to do it. Anywhere a = a + 1 works, a += 1 and a++ should work (or ++a, I guess), since they're semantically equivalent.
Feb 11 2006
"Søren J. Løvborg" <web kwi.dk> wrote in message news:dsli97$2osl$1 digitaldaemon.com...Anywhere a = a + 1 works, a += 1 and a++ should work (or ++a, I guess), since they're semantically equivalent.Not quite. In a = a + 1, "a" is evaluated twice. In a += 1, "a" is evaluated only once. The problem is that with basic types, like int, it's easy to determine where to get the value and where to put it back; it's just a memory location. But you can't do the same with properties; there are separate "get" and "set" functions, which the compiler has to figure out, and it may not be possible for the compiler to determine the matching "set" for a "get" or vice versa. class A { private int mSomeProp; public int someProp { get { return mSomeProp; } set(int value) { return mSomeProp = value; } } } finding the corresponding get/set would be trivial, and A a = new A(); a.someProp += 5; Would be really easy to do. But Walter doesn't like this syntax. I forget what his argument is. It was something flimsy, IIRC.
Feb 11 2006
Hi and welcome to the world of D! We're always glad to see someone's fresh opinions of the language, especially when they are so positive as yours :-) Below I have a few comments to some of your points:+ No forward declarations/No header filesForward declarations - wow, I had actually forgotten about those. Whenever I go back to coding C++ (mostly on other people's projects at my uni), I always discover a bunch of things about the language I have quite simply forgotten, and I used to be quite fluent.(And no more #incldue typos! :-)But you get the "improt" ones instead ;-)+ Case "string", == for stringsAnother mistake I keep doing in C++ now.Another thing was that on of my functions (defined as bit) accidentally had one path out of it without a return statement. Immediate crash when calling that function, again no error from the compiler. Every C++-compiler (iirc) catched things like that. These crashes are hard to find, really. Especially when you're not used to looking for something like THAT.We've had looong discussions about this one. As it is now, DMD basically inserts an assert(0); at the end of every non-void function. But the error messages have line numbers, so they shouldn't really be that hard to find? There are some cases in which every path ends up with a return statement, but none of the paths run to the end of the function (ie. in a switch statement), and in those cases it is damn near impossible for the compiler to know whether or not there should be a return at the end. It might depend on parameter values, etc. I basically see the "assert(0)" as a If-my-algorithm-is-correct-I-should- never-reach-this-point check.MyIntArray.length++; Why not?Seconded.HelloWorldClass writehello; writehello.doIt();Since there is a fundamental difference between how C++ and D handles the problem (writehello is just a reference in D, not the object instance itself), it would cause MORE confusion if the syntax was kept, since C++ programmers would also expect it to _mean_ the same if it looks the same.- no "bool" Can't there be an "alias bool bit;" built in?There is ;-) Nick
Feb 10 2006
The same reasons I came to D :) except I don't have that long of an experience with C++ recently I had to come back to c++ for university assignments .. and man .. C++ really really sucks!!!!!!!!!!! I wish there was a D -> C++ convertor, so I can write my assignments in D then convert them to C++ :D Mike wrote:Hi! I wanted to share some observations of an experienced C++ programmer who has now spent his first 10-12 hours with D. First a little history on my project: I'm currently building a small vm (nothing fancy) for a little hobby project I'm doing. The vm is already running in C++, I just need to build a little, C-ish script parser around that thing. Anyway, I have a little declaration problem in C++. It's not the first time I have exactly this problem, and I solved it numerous times, but I'm getting tired of it, and more frustrated every time I have something like this. class Block; class Instruction { .. Block *MyScope; }; class Block : public Instruction { .. List<Instruction> MyInstructions; List<Symbol> MyLocalSymbols; Block *MyParent; }; Instruction needs to call Block to get it's symbols, Block has it's local symbols and gets undefined symbols from it's parent. If parent is NULL, this is the global block. Symbols can be variables or (nested) functions. That's the idea. But Instruction can't call Block's member functions, because Block is just a declarations. I stopped coding at that point, since I was frustrated, seeing myself AGAIN wasting hours with moving code around, inside and outside the class declaration to get that thing to compile. Ok, I could create a "symboltable" class and derive "block" from both "instruction" and "symboltable". But why? Why another class if it's just needed in one place anyhow? And: No wonder C++ needs multiple inheritance! So I decided to finally try out D. Downloaded latest versions of akIDE and DMD, and after about 30-45 minutes converting my ~500 lines C++ code to ~350 lines D code it ran exactly like before! Nice, I thought. So I've worked on that project yesterday and today and it went really well, so I feel the urge now to summarize my impressions so far: On the plus side: + No forward declarations/No header files I think that's the singlemost important thing to me about D. I hate those forward declarations, really. I hate them more than header files, which I hate a great deal, after numerous hours of playing solitaire while recompiling, because I had to add a new member to a base class. (And no more #incldue typos! :-) + Case "string", == for strings In that particular case of writing a parser this is a godsend, but I imagine this will come in handy in other areas as well. No more !strcmp. + The ~ operator Never again this: char buf[200]; sprintf(buf, "Error in blabla function (dbg: x = %i)", x); throw new exception(buf); Nice! + No ; after class definition This feels just natural. + this/super Great! Never again this: Long, descriptive class name with one hard to see typo, copy paste for three constructors and one descructor, compile, find out you made a typo. And makes it easier to change a class name, too. And I found this to be quite natural from the start, I never accidentally wrote a constructor the C++ way. + member initialization with =, rather than with initializer lists Another great thing, especially for me. I can't remember how many times I actually tried to initialize members via the D syntax, just to find out - d'oh, C++ can't do that. Forgot that again! Fits much better into the overall feel of a C-ish language than those initializer lists. + Dynamic Arrays Yes! + Garbage Collection Yes! Yes! Yes! On the - side: - Hard to find odd crashes I had some trouble, until I figured out that my program seemed to crash/exit immediatly whenever an exception was not caught. Couldn't the compiler catch errors like that? That was really annoying. The problems was that I had no idea about where the crash happened and it took quite some time to find it. Another thing was that on of my functions (defined as bit) accidentally had one path out of it without a return statement. Immediate crash when calling that function, again no error from the compiler. Every C++-compiler (iirc) catched things like that. These crashes are hard to find, really. Especially when you're not used to looking for something like THAT. - .length property can't be lvalue MyIntArray.length++; Why not? - class instantiation is a bit confusing, at least for c++ programmers I intuitively expect something like HelloWorldClass writehello; writehello.doIt(); NOT to crash the program. But, well, that's something I can life with :-) - no "bool" Can't there be an "alias bool bit;" built in? Summary: -------- I think I will start porting my C++ project over to D, since it's just a hobby project, so I have time to do that. And D is nearly the language that I wish C++ to be, honestly (add bool and it is :-). The crashes I mentioned make me wonder, since it wouldn't be too hard to find them at compile time, anyhow, maybe it's just me, I haven't found the time to play with the compiler settings. The things I brought up aren't really acedemic, but I like to get dirty while programming, change my design constantly because I just had that other idea that I NEED to try out. For that D seems to be just the right language. Very practical, I like that. Add to that about 7-8 years of frustration with C++ header files, forward declarations, externs, pointers to pointers and stuff, and I just have to say: D puts the fun back in programming! Thanks! So, wish you guys a nice day and be sure to watch BSG tonight :-) -Mike
Feb 10 2006
That's very strange. Were you compiling it with -release or something silly like that? In that case, it will immediately crash. However, that is not the recommended way to develop code; instead, simply leave it off an asserts (and array bounds checking, etc.) will be enabled. If you didn't use -release, you should have seen asserts, thrown exceptions and other such things. -[Unknown]- Hard to find odd crashes I had some trouble, until I figured out that my program seemed to crash/exit immediatly whenever an exception was not caught. Couldn't the compiler catch errors like that? That was really annoying. The problems was that I had no idea about where the crash happened and it took quite some time to find it. Another thing was that on of my functions (defined as bit) accidentally had one path out of it without a return statement. Immediate crash when calling that function, again no error from the compiler. Every C++-compiler (iirc) catched things like that. These crashes are hard to find, really. Especially when you're not used to looking for something like THAT.
Feb 10 2006
There's nothing as valuable as these first-time experiences with D!!! We in this newsgroup are just too familiar with all dos don'ts of D, to ever imagine what it looks like to new people. Now that we (as always?) are approaching 1.0, stuff like this should be examined with a _microscope_ to find all the things that put off new users. For everyone that bothers to write here there has to be a thousand who get the same feelings, and who broadcast them around in the office, and over beer. Mike wrote:Hi! I wanted to share some observations of an experienced C++ programmer who has now spent his first 10-12 hours with D. First a little history on my project: I'm currently building a small vm (nothing fancy) for a little hobby project I'm doing. The vm is already running in C++, I just need to build a little, C-ish script parser around that thing. Anyway, I have a little declaration problem in C++. It's not the first time I have exactly this problem, and I solved it numerous times, but I'm getting tired of it, and more frustrated every time I have something like this. class Block; class Instruction { .. Block *MyScope; }; class Block : public Instruction { .. List<Instruction> MyInstructions; List<Symbol> MyLocalSymbols; Block *MyParent; }; Instruction needs to call Block to get it's symbols, Block has it's local symbols and gets undefined symbols from it's parent. If parent is NULL, this is the global block. Symbols can be variables or (nested) functions. That's the idea. But Instruction can't call Block's member functions, because Block is forward declarations. I stopped coding at that point, since I was frustrated, seeing myself AGAIN wasting hours with moving code around, inside and outside the class declaration to get that thing to compile. Ok, I could create a "symboltable" class and derive "block" from both "instruction" and "symboltable". But why? Why another class if it's just needed in one place anyhow? And: No wonder C++ needs multiple inheritance! So I decided to finally try out D. Downloaded latest versions of akIDE and DMD, and after about 30-45 minutes converting my ~500 lines C++ code to ~350 lines D code it ran exactly like before! Nice, I thought. So I've worked on that project yesterday and today and it went really well, so I feel the urge now to summarize my impressions so far: On the plus side: + No forward declarations/No header files I think that's the singlemost important thing to me about D. I hate those forward declarations, really. I hate them more than header files, which I hate a great deal, after numerous hours of playing solitaire while recompiling, because I had to add a new member to a base class. (And no more #incldue typos! :-) + Case "string", == for strings In that particular case of writing a parser this is a godsend, but I imagine this will come in handy in other areas as well. No more !strcmp. + The ~ operator Never again this: char buf[200]; sprintf(buf, "Error in blabla function (dbg: x = %i)", x); throw new exception(buf); Nice! + No ; after class definition This feels just natural. + this/super Great! Never again this: Long, descriptive class name with one hard to see typo, copy paste for three constructors and one descructor, compile, find out you made a typo. And makes it easier to change a class name, too. And I found this to be quite natural from the start, I never accidentally wrote a constructor the C++ way. + member initialization with =, rather than with initializer lists Another great thing, especially for me. I can't remember how many times I actually tried to initialize members via the D syntax, just to find out - d'oh, C++ can't do that. Forgot that again! Fits much better into the overall feel of a C-ish language than those initializer lists. + Dynamic Arrays Yes! + Garbage Collection Yes! Yes! Yes! On the - side: - Hard to find odd crashes I had some trouble, until I figured out that my program seemed to crash/exit immediatly whenever an exception was not caught. Couldn't the compiler catch errors like that? That was really annoying. The problems was that I had no idea about where the crash happened and it took quite some time to find it. Another thing was that on of my functions (defined as bit) accidentally had one path out of it without a return statement. Immediate crash when calling that function, again no error from the compiler. Every C++-compiler (iirc) catched things like that. These crashes are hard to find, really. Especially when you're not used to looking for something like THAT. - .length property can't be lvalue MyIntArray.length++; Why not? - class instantiation is a bit confusing, at least for c++ programmers I intuitively expect something like HelloWorldClass writehello; writehello.doIt(); NOT to crash the program. But, well, that's something I can life with :-) - no "bool" Can't there be an "alias bool bit;" built in? Summary: -------- I think I will start porting my C++ project over to D, since it's just a hobby project, so I have time to do that. And D is nearly the language that I wish C++ to be, honestly (add bool and it is :-). The crashes I mentioned make me wonder, since it wouldn't be too hard to find them at compile time, anyhow, maybe it's just me, I haven't found the time to play with the compiler settings. The things I brought up aren't really acedemic, but I like to get dirty while programming, change my design constantly because I just had that other idea that I NEED to try out. For that D seems to be just the right language. Very practical, I like that. Add to that about 7-8 years of frustration with C++ header files, forward declarations, externs, pointers to pointers and stuff, and I just have to say: D puts the fun back in programming! Thanks! So, wish you guys a nice day and be sure to watch BSG tonight :-) -Mike
Feb 20 2006