|
|||||||
This is a discussion on "Which is preferred?" in the Top Mud Sites MUD Coding forum : Hey all. I've been interested in teaching myself how to code for awhile now and well, I went and downloaded Cygwin on my comp. I'm also told I need to dl a codebase after that, which will probably be some sort of ROM. Now, my question is this: I want to go out and buy the much-needed coding book. But...what exactly is preferred? C? C+? C++? In terms of wanting to learn to code and possibly write up some snippets for mud's one day, which is suggested?... |
|
You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so please, join our MUD community today! If you have any problems with the registration process or your account login, please contact us. If you are a registered member of the old TMS forums, please click here
|
![]() |
|
|
LinkBack | Thread Tools |
|
|
#1 |
|
Member
|
Hey all.
I've been interested in teaching myself how to code for awhile now and well, I went and downloaded Cygwin on my comp. I'm also told I need to dl a codebase after that, which will probably be some sort of ROM. Now, my question is this: I want to go out and buy the much-needed coding book. But...what exactly is preferred? C? C+? C++? In terms of wanting to learn to code and possibly write up some snippets for mud's one day, which is suggested? |
|
|
|
|
|
#2 |
|
Senior Member
|
Most existing mud codebases have been created using C. So C++ isn't going to help you much if you want to distribute snippets, because some codebases require conversion to be compiled with a C++ compiler. The newer codebases that I see people working on are almost universally written in C++, Java, or a language with greater abstraction possibilities than C.
If you just wish to modify an existing codebase, for example ROM, a book on C would most likely be your best bet. btw, "C+" doesn't exist =). |
|
|
|
|
|
#3 |
|
Member
|
Ahhh...thank you. *grins* And you're right, of course, it doesn't exist, heh...I believe it was "C#" I was trying to think of...
So, that brings up a question of trends: Will the use of "C" eventually fade out...in favor of the newer "C++"...or does the more recent language not really apply to the MUD world? |
|
|
|
|
|
#4 |
|
Senior Member
|
I can only speculate, but I believe existing codebases are going to continue on with C. Most of the newer codebases that I see in development are done in C++, with some in Java and other languages. So it then becomes a question of whether or not the newer codebases will surpass the older ones, and I lack the clairvoyance to know that =). But C++ codebases will definately become more common I predict.
It is probably a good idea for you to start with C anyway, because C++ is very similar and will even compile most C code. There are also several C codebases to use as a reference point (although you should be careful about learning habits from them, as they are rather poorly designed). C is also much less complex than C++, so there are fewer areas to get confused about when you're starting out. |
|
|
|
|
|
#5 |
|
Posts: n/a
|
C++ is not more complex then C imho. However, because it is an object-orientated programming language, it is definitely allot more abstract and harder to grasp because of it. Still though, if you try the basic of C first, C++ will be a piece of cake because some possibilities in C look quite alike objects in C++ (structs anyone?)
As for which language will fade out, neither of them I believe. C is being used as the standard language for Unix and Unix-like operating systems and C++ is more or less a "standard" language used for various reasons/applications. I don't know about speed differences among C and C++, but both are definitely faster then Java, because Java is basically a souped up scripting language instead of a programming language. As for compilers, which can be tricky to find, look around on the net for Borland C++ Builder version 3.1. It's good, easy and not all that complicated. DOS based though, so be prepared to work in a 25x40 res with 32 diff colours if you want to use it. It's quite easy to use, does the job, even though it is not so much very legal to find and download. |
|
|
|
#6 | |||
|
Legend
Join Date: Apr 2002
Name: Richard
Location: München
Home MUD: God Wars II
Posts: 1,782
![]() ![]() |
Quote:
Quote:
Quote:
Regarding which language to learn: If you're only interested in learning so that you can write mud snippets, then I would agree with Unifex and suggest C. In fact I use several (of my own) C snippets in my own C++ codebase - I just encapsulate them in a namespace - even though they were originally designed to work on muds written in C. |
|||
|
|
|
|
|
#7 |
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
If you're just learning a first language, C is a much better choice than C++. The poster who said that C++ isn't more complex than C has obviously never had to tackle virtual inheritance, virtual functions with multiple inheritance, problems with dynamic casting and typecasts changing pointer values, operator overloading...
C++ takes C as a starting point and adds a huge amount of new stuff. It's more complex. Seriously. It contains all of C as a (small) subset. How can it *not* be more complex? You can get away with using fewer of the complicated, nasty C++ features if you only use your own code. But if you ever plan to have another coder on your MUD (you do, right?) you'll have to deal with them. And while everybody seems to agree that C++ is a combination of okay stuff and gross, horrible hacks, nobody seems to agree about which is which. So he'll be using some stuff you consider to be gross, horrible hacks. I believe that C is the clean part of C++, and almost all of the rest is made of gross, horrible hacks :-) |
|
|
|
|
|
#8 |
|
New Member
Join Date: Feb 2003
Location: California, US
Posts: 5
![]() |
angelbob-
Which would you consider cleaner? ---------------------------------------- class IntObject { IntObject &operator +=(int val) {_val += val; return *this;} operator int( ) {return _val;} int _val; }; IntObject i; int v = i += 3; ------------------------------- Or? struct IntObject {int _val;}; IntObject *PlusEqual( IntObject *i, int val) {i->_val += val;} int Value( IntObject *i) {return i->_val;} IntObject i; int v = Value(PlusEqual(&i, 3)); ---------------------------------- To me, the C++ version (first version) is a lot cleaner and more intuitive. I'd have to say that the design details of a program determine which language produces cleaner code (mainly whether the problem is more naturally described as objects (C++), or proceedures ©). In the case of a MUD, the design is CLEARLY object-oriented (Server, Connection, Player, Character, Object, Room, Area). Thus, using a language that has object-oriented capabilities would most likely produce the cleanest code. I'm guessing that you confused the cleanliness of a piece of code with complexity of a language. |
|
|
|
|
|
#9 |
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
First, I note that you're using a complex structure where you should be using an int. Passing a pointer to a structure with a single int makes for ugly C, passing a reference to a structure with an int makes for ugly C++, and passing an int around is pretty clean -- and identical in either language. But I'd say both are quite ugly, and both are about equally ugly, but it's very slightly more obvious what the C version is doing.
Second, by talking about how MUDs are an obvious place to use object-oriented programming I'm assuming you're talking about the objects themselves (like, "physical" in-game objects). I'm with the Skotos folks on this -- data inheritance is appropriate, code inheritance not so much so. Code inheritance is the only kind that C++ provides. Third, if you're talking about inheritance in the "physical" in-game objects, then you're talking about doing it dynamically if you have any OLC facilities. Any modern MUD does. Unless you recompile on the fly (like DGD does -- I'm actually serious, although C++ isn't a good language for this, nor is C), you're going to have to build your own stuff. So you're back to implementing all your own data inheritance. I agree that there are a couple of specific instances where C++'s version of OO is cleaner than doing the same thing in C. User interface code (windowing and whatnot) is the only place I've seen where it's consistently true. And yet GTK+, the windowing toolkit for GNOME, uses C instead of C++. Why? Because C++ is incompatible between compilers, doesn't link object code between multiple compilers, has the usual fragile base class problems and can't inherit and runtime. The fully inheritance-based solution used by GTK+ is done in C and built out of macros. Unlike the C++ solution, it links to a variety of languages, allows implementation of new widgets in a variety of languages, doesn't require RTTI (which doesn't link between different C++ compilers) and works quite happily if you add new stuff at runtime. Fourth: your C solution above is attempting to do operator overloading in C. That's its primary problem. You can do what you're doing relatively cleanly in C, but you can't make it look like C++. Why would you want it to look like C++? |
|
|
|
|
|
#10 |
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Here, lemme make it clearer what I mean about the "using a complex structure instead of an int" and "make it look like C++" bits.
Your example could be less trivial -- vectors and matrices are the cleanest example I know of in C++, and the best example of why operator overloading might not suck. Every other example that I know of is thoroughly horrible, and I absolutely include "cin" and "cout" in that. I mean, c'mon, they're using bit-shift operators for input and output. How clean and intuitive is *that*? It's hard in C and ugly in C++ to pass big complex structures around as though they were regular builtin data types. That's pretty much what you're doing above. You can do the same with matrices and define addition, multiplication and (with some stretching) things like inner products, inversion and solving. Of course, nobody but you will ever guess your operators on the first try for anything except addition and multiplication, and they'll need to check your documentation to see if you're doing real matrix multiplication or just going element-by-element. So instead of something big and nasty and C-like like this: Matrix *A,*B,*C; A = MatrixInit(7,7); MatrixFileLoad(A, "mydatafile.dat"); B = MatrixInit(7,9); MatrixFileLoad(B,"myotherdata.dat"); C = MatrixInit(7,9); MatrixMultiply(C, A, B); You can instead have something smaller and C++-y like this: Matrix A(7,7), B(7,9); A.FileLoad("mydatafile.dat"); B.FileLoad("myotherdata.dat"); C = A * B; Cleaner, smaller, and not much slower if you do it right. The bit of slowness added is because you'll be copying C after that matrix multiply with its copy constructor. You could avoid even that if your compiler is really clever (it's not -- check the code if you use GCC, or the execution time if you use VC++), and the stack space hit doesn't matter in this day and age, at least for MUDs. I used to work for Palm, I notice these things. Anyway. I'll mention in passing that the library implementing this stuff will be much nastier in C++ than in C. But you could point out that you only write the library once and you write code with it many times. You'd be right. Of course, you maintain the library and deal with bugfixes constantly, and the C++ version does a lot more under the covers. For instance, if you had a bug in the copy constructor or one of the operators in the C++ version (for instance -- does A *= B work? Maybe...) you'll have a much nastier time tracking them down and finding all the functions that are called. I'd say a good debugger would help you, but GDB and VC++ both have serious issues with a lot of very standard C++, let alone godawful things like most proprietary Unix debuggers. You can say "but I'd write the library right' or "but I'd debug and test it well". You'd probably be right. Good for you. Now, are you the only one working on your project? I've seen a lot of very bad C++ with very hard-to-find bugs. Much more so even than C, especially if I can use a tool like Purify on both. |
|
|
|
|
|
#11 |
|
Member
Join Date: Mar 2003
Posts: 70
![]() |
If planning to code on an LP Mud (or any older mud) then I recommend C as C++ and C# both have significent differences. A lot depends on the mud you want to code on though - I recommend finding and playing the mud before you decide to code for it. Once you know that then the admin there will be able to tell you what language they are using.
Certainly on Zeb we don't let people become coders until they have played the game (the usual rule being at least one character to legend level) and we feel that they are ready for the responsibility. As a side note C# is basically microsofts bastard cross-breading of C++ and Java. It has some nice features but I don't see it being used much for muds in the immediate future - although I am using it a lot at work. |
|
|
|
|
|
#12 | |||||
|
Senior Member
|
Quote:
Quote:
Quote:
[code] typedef mytype int; void dosomething (mytype &m) { m = 5; }[/quote] When that typedef is changed to IntObject (or something more functional, like my above CheckedIntObject), you would have to go back and insert functions to perform all of the assignments. Quote:
Quote:
|
|||||
|
|
|
|
|
#13 | ||||||||||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
(Quotes here are from Yui Unifex)
Quote:
Of course, if a bug ever happens that doesn't crash your code, you have to debug it. I'm a big fan of knowing when functions are called. C++ experts can generally tell you the order of function calls in, say, this: C *= myType(9,4,"bob") It definitely gets hard to follow, though, especially if (in the example above) you haven't defined your own *= operator and C++ has to wing it. It will, in fact, do so, but the choices it makes for this and for typecasting aren't always intuitive, and a lot of stuff (like typecasting) happens silently in conditions that are just weird. That doesn't address your point, though. Your point is that C++ will fake a builtin data type and make it call arbitrary other functions silently to an extent that C won't. Yep. You're right. And it's a massive debugging headache that it'll do so. Perl does this "right", too. Perl is the only language I know with a worse reputation for syntactic and semantic cleanliness than C++. Coincidence? Quote:
Quote:
Quote:
But seriously -- true. I still argue that C++'s extra complexity isn't generally worth the benefit in any environment with more than one coder. When you say that C and C++ break down to the same thing for a given problem, I argue that that supports my argument. They wind up using essentially the same methods to deal with the problem, but C++ has all the extra nastiness you're not using at the moment. But somebody else on the project may be, and it's allowed to mess you up. Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
But for most things, it's a lot less obvious what + or * represent. Using operator overloading for math is reasonably clean. The vast majority of the time it's not used for math. For instance, have you noticed that cin and cout use the bit-shift operators? Eeeeeeewwwww! And that's just in the standard library! You could argue that it sorta makes sense ("look, they're little arrows. Kinda. And arrows mean input and output. Kinda. And we didn't allow overriding the actual arrow, plus it doesn't come in reverse flavor."). But if you did, I'd laugh at you. I've found that's a better example of the way people choose and overload operators in the real world, which is why I don't touch other people's C++ code any more. There's one exception, but Tom's even pickier than I am about this stuff and he rewrites everything three times to get a clean design. |
||||||||||
|
|
|
|
|
#14 | |||||||||||||
|
Senior Member
|
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
+ operator (Supported by C++) & operator (VB) . operator (PHP) << operator (C++) What operator or method (if it's not using operators) would you suggest be used for stream input? |
|||||||||||||
|
|
|
|
|
#15 | ||||||||||||||||||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
angelbob:
Quote:
Quote:
angelbob: Quote:
Quote:
http://www.skotos.net/articles/TTnT_60.shtml angelbob: Quote:
Quote:
Yui: Quote:
Quote:
Quote:
Templates, though, are a syntactic answer to a semantic problem. Plus they have all the problems I mention in the previous paragraph. And I don't particularly like angle brackets more than stars, just personally :-) angelbob: Quote:
Quote:
There are exceptions, but the way C++ handles those is just *evil*. I'm not saying they can't be done right, but C++ certainly doesn't. They're hard to bolt onto a language after the fact, and C++ barely even tries. angelbob: Quote:
Quote:
Yui: Quote:
Yui: Quote:
Quote:
I draw the line by saying "no C++". That means I never have to deal with a developer saying "yeah, you have to use templates and overloaded operators, but only on the stuff in my module." angelbob: Quote:
Quote:
|
||||||||||||||||||
|
|
|
|
|
#16 | ||||||||||||||||
|
Senior Member
|
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
1) I say that restricting a feature from an entire language because some can do wrong with it is "spoiling the broth". 2) You say that restricting a feature from your own project because some can do wrong with it would have people like me claiming that it is "spoiling the broth". Do you see the fallacy now? There's a staggering difference in scale between a *language design* and your own project's guidelines. You are free to do whatever you'd like in your own project. But the moment that you step out of your bounds and claim that since you have never seen a great use of something, then mandate that it is useless for everybody else is the moment that I cry foul. Quote:
Quote:
reply.output(", you're saying we should not use operator overloading for output streaming?\n"); reply.output("Well, "); reply.output(poster.name()); reply.output(", I guess we disagree.\n"); |
||||||||||||||||
|
|
|
|
|
#17 | ||||||||||||||||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
angelbob:
Quote:
Quote:
Yui: Quote:
So I'm saying: here's what the MUD environment seems to particularly call for. I don't feel it's a good match for C++'s inheritance. I feel that C++'s inheritance is not a good match for this specific problem. Clear? And incidentally, yes, you *can* add language support for it, but the only languages where that would be appropriate are languages for pretty specific applications. MUD scripting languages, for instance. angelbob: Quote:
Quote:
Yui: Quote:
Quote:
Compilers I've used that support namespaces, also a long-standing standard, fully and completely: Um... VC++, maybe? I know there are bugs, but mostly, I think. That haven't: Metrowerks (didn't test templates so I didn't list it above), G++ (fixed now?), SGI C++ compiler, HP C++ compiler, SunOS4 C++ compiler. Didn't test Solaris. Do you know how long it took them to come up with a "standard" Ada compiler after the language was spec'd? Green Hills makes about the only one in existence, and they certainly aren't the only people who've tried, or the only people that want the Department of Defense contracts involved. Standardizing doesn't make it so. Yui: Quote:
I'm aware that they're slow to use, but mainly I'm bothered by the fact that they're *hard* to use, at least correctly and without ugly corner cases. Yui: Quote:
You could make it a function call instead. But then what happened to all your arguments that operator overloading is better than function calls for that kind of thing? Yui: Quote:
If you overload an operator like bit-shift that has a defined meaning in a related domain, you're being worse than arbitrary. You're being specifically misleading. Or to put it another way: cout << "Half the sum is " << sum << 2 << " or at least I hope so.\n"; Can you fix this with parens? Sure. But you're being confusing. The operator is bit-shift and text output in the same expression regardless of how many parentheses you add to it. It's the same problem as using + for string concatenation -- it's inherently confusing when stuck next to + for integer arithmetic. So choosing one of a number of existing symbols with existing meanings (like operators) rather than a richer vocabulary (like words, used for function names) is guaranteeing that you have a lot of unrelated baggage attached to any name you give an operation unless that operation already matches the symbol you're using. As you point out, there is no symbol that matches cin/cout -- they could have used xor (^) or function call with dereference (->) or any of many other operators -- and those would have been confusing, too. angelbob: Quote:
Quote:
So you're saying "but what better matches are there?" and I'm saying "choosing a small fixed number of names with existing different meanings is foolish." If I were going to write a list reversal function I probably *would* call it list_reverse. I'd still say that a language feature that made you choose from those possible names, even if it were very convenient, would be basically misguided. And that's basically what operator overloading makes you do. angelbob: Quote:
Quote:
So when the original poster (remember when we had a topic?) asked "C, or C++?" I said "C". You're right, having a standard will help to prevent whatever subset of C++ you don't like from getting into the project. In practice it rarely works that way since you wind up having to rewrite submissions from people that didn't read the standards, but we'll pretend it always works. Fine. Still, I believe that operator overloading is essentially wrongheaded, and that it should be avoided. I believe that a fine way to avoid it is to use a language that doesn't support it. If there was a variant dialect of C++ that added only features that you hated, would you declare that your project didn't use them, or would you just use the compiler that enforced the set of features you used? Would you police your project standard by using a tool that did so for you, or would you say "well, I shouldn't discriminate against the language" and use the compiler that didn't? I have a guess which one you'd do. And I *know* which one I do. Yui: Quote:
So when I say "you should use C on your project. I do. Here are the features you avoid other people using, and some reasons I dislike them", you say I'm spoiling the broth. Of course, you also claim I'm altering the design of C++ by using C, but I'll ignore that for the moment, shall I? Quote:
cout << "While I agree that your way works better for " << output_code.bold() << output_code.color("green") << "some" << output_code.unbold() << output_code.color("white"); cout << " things, I think there are others that help to"; cout << " counterbalance them.\n"; printf("Right-side formatting, for instance. And tables.\n"); printf("So, %s, I do say that. And yes, %s, we DO " "disagree.", poster_name(), poster_name()); |
||||||||||||||||
|
|
|
|
|
#18 | |||||||||||||||
|
Senior Member
|
Quote:
Quote:
Quote:
[code] typedef mytype int; void dosomething (mytype &m) { m = 5; }[/quote] You would have to go back and insert function calls if you later decided to use a user-defined type. This drastically reduces the genericity of the code. Even though the result may be the same, you have to jump through a lot more hoops to bring it about. Quote:
Yes, g++ 3.x supports namespaces. Can't say for the other compilers, as I haven't used them recently. Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
There are several libraries that solve the attribute problem by overloading operator<< so that one may use format-strings just as you do for printf(). These are immune to the problems I mentioned, though, because one should not insert the actual data using these formatters. Quote:
Quote:
Quote:
Quote:
|
|||||||||||||||
|
|
|
|
|
#19 | ||
|
Senior Member
Join Date: Oct 2002
Posts: 291
![]() |
Quote:
sub Dostuff(MyArray) ... Some code ... for a = 1 to 10 for b = 1 to 10 if MyArray[a,b] = -1 then exit end if next next ... More code ... end sub Two ways to fix this: 1. Place the loop in its own sub and use 'exit sub' in the loop instead (only how do we then return the right value??. 2. Recode the whole thing to not use for-next. Both methods of which are imho silly. However if you could add one bloody goto. Quote:
a = concat("Hello ", b); a = concat(a, " how are you? - "); a = concat(a, c); Though it is less ambiguous to use concat. The same of course goes for using & and getting concat instead of AND. My advice would be try using VBScript to code something that requires a lot of this kind of dual use syntax and see how much more fun it is when the language doesn't even know what 'type' a variable is, until you do something to it. MS design philosophy - "It can always get worse, so lets see how we can make it so." NOTE: Pure VB is also prone to this kind of guessing some times, which is why you should shoot anyone that doesn't correctly type cast their variables in it, to avoid having them breed even more morons. Though it is a good idea to be careful that you don't kill the ones that intentionally defined non-typed variant class variables for a good reason. Had MS used a keyword instead of just making non-typed variables default to variant this would of course not been necessary, but since no one seems to want to take Basic and manhandle it out of the hands of MS so it could be fixed... |
||
|
|
|
|
|
#20 | |
|
Member
|
Quote:
Which just goes to show two things: a) Good programming practices eliminate the majority of "This Is Evil" code snippets. For example, above, you 1) introduce a "magic number", 2. 2) Have more than one side-effect on the same line (you're performing output, and maths) instead of logically separating your code. 3) deliberately using unclear (well, less clear than "sum/2") logic. Two of these three points would have removed the error. b) One should check at least three times when trying to be a smartarse Bottom line: I have to wonder what sort of weight should be given to the argument "Feature X is bad. As an example, I give Bad Code Y". Because it can usually (and certainly in the cases of operator overloading and templates) be stated equally as "Feature X is good. As an example, I give Good Code Z". Kas. |
|
|
|
|
|
|
#21 |
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Your argument (Yui) that every feature is a good feature because it improves the expressivity of the language is interesting. Are you a massive fan of Perl for large projects for that reason?
My problem with C++ in practice has been that the average quality of code I've seen is terrible, even compared to similar projects in C. And the code I'm talking about is actually at professional software companies I've worked at. By "terrible" I mean "prone to crash/deadlock and hard to debug". The problems have been that different people use different subsets of the language, nobody knows the whole language, and you have to debug the code of people that use a different subset of the language than you do. In a programming project that you control, you get to be the autocrat and spend a lot of time tearing misused or "wrong" (i.e. forbidden) features out of code other people submitted. As in a professional software environment, nobody reads the coding standards and nobody follows them, so you still have to go in and fix the results afterward. Fair enough. Goto is a fine example of the same principle. There are specific examples where it's basically acceptable. Palm (the company) used it for about the same purpose you list above, though with a couple more restrictions. Nonetheless, the vast majority of C code I've seen using "goto" is quite bad. Overall, its existence has done far more harm than good for the maintainability of the code I've seen in my professional career. In my private code I don't work on C++ projects with other people so it's a non-issue. I'd like to again draw attention to the phrase I used above, the one that goes "nobody knows the whole language". C is a pretty snappy little language, and a clever fellow can figure out the whole thing and know the vast majority of the subtleties (what does "++bob++" do if "bob" is an integer? Is it legal? Which has higher precedence?) within a couple of years of regular use. I've interviewed with a guy who was on the C++ ANSI standards committee. I've worked professionally in C++ for several years, and I've worked with many people who use it very regularly. I've built C++ parsing code, code to produce it from a template, debugged massive systems and worked under about four different template libraries in it at three different major companies. What I have never done, though, is to meet somebody with a very firm grasp of all the current standard language subtleties and how they work together. By contrast, I've probably met about six people who could say that for C and who actually keep up with all the latest ANSI standards. Perl, like, C++, seems to have no full-on experts. It's simply too big, too varied and too weird. Like you say, we could just rule out big chunks of the language and be an expert on the rest. If you believe that will work, you've worked on very different projects with very different people than I have. At least at the companies I've worked at and on the OSS projects I've worked on, you can't get people to follow the project's coding standards without constant and painful enforcement. Though I suppose, if you had any significant number of contributors, you could just reduce your whole role to "constant and painful enforcement". That's what I've been doing primarily on my project lately -- and I'm using a simpler, cleaner language than C++. |
|
|
|
|
|
#22 | |||||||
|
Senior Member
|
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
|
|||||||
|
|
|
|
|
#23 | ||||||||||||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Yui:
Quote:
One reason I'll call a language "clean" is if no two valid inputs in the language look very similar to each other. That is to say, if any two valid inputs in the language are reasonably easy to disambiguate from each other, especially two inputs which are basically dissimilar. And by "disambiguate", I mean only if you're reading it. A parser, of course, won't have much trouble either way. Quote:
Quote:
That's mainly because they have a really good optimizer, though, and the fact that the whole language is designed with that in mind. Anyway. Sorry. Off-topic. Quote:
That's just one of the many reasons that languages that allow good modularity are so popular. Quote:
The same is essentially true at a professional software house, and nobody wants their job to be enforcing coding standards. Well, okay, John did, but we laid him off and he left for Norway. It's a shame, he was good at it. Quote:
One could imagine a similar scenario where "dd" was aliased to always prompt when you used it on a hardware device (rather than just a file), so it would make you specifically say "yes" before doing something potentially stupid. The DOS "Format" command already does/did that. I consider all of those to be basically good things. Should language designers avoid easily-abusable features in favor of features that tend to produce better code on average? Absolutely. Unquestionably. Should they remove features (like pointers) that can sabotage other people's work silently and without them specifically opting into it? Where possible, yes. Pointers specifically are a great example of a feature which can't be removed without a speed hit. I still try to use languages without them, where possible and appropriate. Would any given lanuage be better if we added a bunch of new features? Maybe. CommonLISP plus pointers, for instance, or Java plus pointers, would be a step back. SML plus pointers would be an abomination -- like C++, it would have sabotaged its greatest asset, though for different reasons. "Sabotaged its greatest asset?" Yeah. Being object-oriented is C++'s greatest asset. That means a real type system. The basis of data protection in a type system (private, protected, static, etc) is enforcement. Private fields aren't private as long as C++ has pointers. Anyway. Sorry. That's a different anti-C++ tirade, and it's not like C has a real type system either -- it just doesn't pretend to. Yui: Quote:
Incidentally, there *are* new languages that focus on having fewer features rather than more, and some of them are very much improved by it. SCHEME is easily embeddable because of it. SML/NJ is possible because of it -- full static type analysis is essentially impossible on most imperative programming languages, and you wouldn't want it anyway. Java is cleaner because of it, having removed some nastiness that C++ added. Quote:
Beyond a certain number of simultaneous features, you're right, you have to have a language that's too complicated to understand. Speaking of which, if C++ has closures then we mean two very different things by "closures" or C++ has added a feature I'm not familiar with. I'm used to closures requiring lambda functions or something like them. Quote:
For common structures (such as lists and hash tables), though, I agree -- complexity at the language level leads to simplicity at the algorithmic level. Though the stuff we were discussing earlier was all simplicity at the syntactic level, which I consider to be a separate issue. More specifically, complexity at the standard library level tends to lead to simplicity at the algorithmic level. Complexity at the language level tends to lead to simplicity at the syntactic level. Quote:
Specialization *restricts* the vocabulary of an individual, and even of a socity -- you see practically nobody that works in clay/glass hybrid objects because those are considered separate specializations so there's little overlap. That wasn't always true. But by restricting the expressiveness of the media involved, we get everything with less labor. Old fabrics, done by hand on a loom made of strings and a rock were more complex than the most impressive stuff we can do on our big modern computer-controlled looms -- and yet our modern stuff produces it at a tiny fraction of the cost, so we're wearing simpler fabrics and not worrying about it. By *restricting* expressiveness, we've reduced total labor. And in the same way, the fact that I use C means I'll never have to debug a code submission that requires me to understand all the stuff that can go wrong with C++ code templates. I've saved myself a couple of months of my life that way, and I'm happy about it. Quote:
And Perl, Python and Java overtake C and C++ while we stand in denial, because there are fifty times more people who can be perfectly adequate programmers than can be brilliant programmers, and fifty adequate guys is worth at least two brilliant guys. More on some problems. Only two? Sure. But that's still twice what the brilliant guy can do. Of course, you could also make sure that the language the only-adequate people use is sufficiently "expressive", and then none of them can debug it. Lamentably, that's why something as awful as Visual Basic is also overtaking C and C++. Quote:
But yes, C++ is cleaner for some specific things. The things you proved it was cleaner for were specific C++ language features (C sucks for operator overloading, I'll grant you), and ones that I feel still shouldn't be used. But in the same way that APL or Fortran absolutely rocks if you need to take the inverse transpose of the product of a 9x7 with a 7x15 matrix, C++ rocks for operator overloading. Incidentally, APL is another long-forgotten example of a write-only language in a very specific domain. It does array processing (thus the name). It has operators for, like, everything you can do to an array. But since nobody remembers what the operators do when they read them, it doesn't matter -- the code's simply not maintainable. Rather like the way some parts of the Perl regexp system work, or some of the finer points of C++ RTTI and typecasting stuff. |
||||||||||||
|
|
|
|
|
#24 |
|
Member
Join Date: Apr 2002
Location: Brisbane Australia
Posts: 74
![]() |
A lot of the arguments being used seem to me to be more about how people use it. If a company has standards that people should be using they should use it. Ihave worked for a couple of companies with different coding standards, and when people have followed the standard it is often simple to maintain/modify other peoples code, the exceptions to this were the "prima donna" programmers who felt they were indispensible and so didn't have to follow the standards, and they produced hard to understand, and difficult to follow code. This is not a problem with the language but with the programmer.
If nothing else a little bit of concise commenting can simplify maintenace a whole lot. just my 2c |
|
|
|
|
|
#25 | |
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Karlan:
Quote:
Even though assembly is capable of things that C is not. Even though using C instead of assembly is compensating for programmers being less brilliant rather than making them work for their good code. Even though the maximum quality of the code is less than for assembly. Even though the arguments for using C are all about how people use assembly, not whether it can be done well. Despite all of those things, I'd still recommend C over assembly. Ditto for C++. And the Future Crew, who did wonderful demos in assembly language, can laugh at me all they like. |
|
|
|
|
|
|
#26 |
|
Member
Join Date: Apr 2002
Location: Brisbane Australia
Posts: 74
![]() |
Are you saying you feel C++ is a step forwards or backwards from C?
|
|
|
|
|
|
#27 | |||||||||||||||
|
Senior Member
|
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
The most ironic thing is that these are all arguments for why C++ should be encouraged: Quote:
Quote:
Quote:
Quote:
To enumerate the covered advantages of C++ (vs. C) in our debate: 1) When you want generic code such that a user of your library can call functions with both user-defined and built-in types. 2) When you want to change the return value of a function used in I/O without having to go back and change all users of that return value. 3) When you want an error-handling system that is not coupled to the return type of functions. 4) When you want natural math operations with user-defined types. 5) When you don't want to write Yet Another Linked List, or Yet Another String Handling System. 6) When you want to use strings with pass-by-value semantics. And for C: 1) When you don't want to deal with other people doing something you don't understand or don't like. (Edit: Added 'or don't like' to C's advantage.) |
|||||||||||||||
|
|
|
|
|
#28 |
|
New Member
Join Date: Feb 2003
Location: California, US
Posts: 5
![]() |
7) When you want error-proof typecasting (polymorphism).
8) When you want error-proof deallocation of internal data of a type (avoid memory leaks that are a pain to find!!! And many more, I don't want to sit here all day. |
|
|
|
|
|
#29 | |
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Karlan:
Quote:
His argument is: C plus more features must be better than C. My argument: C plus features that are frequently misused is generally worse than C. Beyond that, we're just hashing through whether C++'s features are generally a good or bad thing. His argument: the potential upside is greater since you don't have to use bad stuff, or use stuff badly. My argument: this stuff is generally used badly. There's a lot more detail, but you can read through at your leisure, this stuff's probably on the 'net forever. |
|
|
|
|
|
|
#30 | ||||||||||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Quote:
With that said: sure, whatever. Quote:
For instance, I've had a bug where typecasting from one C++ type to another (legally, within the heirarchy, from a parent to a child class, yes) changed the numerical value of the pointer. So the literal value of the pointer was different than if you typecast to a void pointer in between. This is a fine example of a case where the "feature" is so "interesting" that even most people who use it don't know how to debug it. I was lucky -- I distrust C++, so every feature that I use, I understand down to the bitwise level. The other people at the place I worked had to have it extensively explained to them how multiple inheritance might mean that a typecast changes the numerical value of the pointer being typecast. That's because it's not documented anywhere in any of the standard language books. I'm sure it's *somewhere*, but not anywhere that a regular programmer could find it, particularly not from the "symptoms" (apparent data corruption) that it causes. C++ has a lot of rough edges like that. You could say, "don't use multiple inheritance", which is one answer. I think that's a shame since I like OO -- I just don't think that C++ is much of an OO language. Quote:
Quote:
Quote:
The problem doesn't tend to be people wilfully ignoring the standard. It's that the standard isn't usually very complete , programmers don't fully know the language (as we agreed, that's pandemic in C++), and they don't fully remember the project coding guidelines and aren't going to go dig them up before writing more code. It's not maliciousness, just negligence. And I could eventually rule out all the bits of C++ that are nasty ("don't use operator overloading for things without established mathematical domains; don't use function inlining, even automatically and without the keyword, for large functions that are called more than once; don't use templates except for basic data structures, and preferably not then; don't use RTTI for anything that will EVER need to be portable; don't use any compiler other than the one I use -- they don't link against each other; etc, etc, etc). But nobody would follow it. Why? They wouldn't remember, or wouldn't agree, or wouldn't check before coding, or wouldn't realize that the standard covered that. And they'd agree with you -- if the language has a feature, why not use it? Answer: because they're not good enough to fully debug what they submit within the context of the full project, and I don't want to debug stuff I don't fully understand (like large-scale template stuff or relatively subtle RTTI bugs). Since they can't debug what they submit, and I can't debug what they submit, they shouldn't submit it. You ever try to tell somebody that? It doesn't work. You have to go in and rewrite it or tear it out later when it doesn't work. The hybrid code you get this way is beyond hideous. Quote:
class myclass { private: int bob; int sam; public: void playwithbobandsam(void); } /* Nasty code: */ myclass victim; ((int*)victim)[0] = 7; /* Set bob to 7 */ ((int*)victim)[1] = 9; /* Set sam to 9 */ Where's your strong typing now? Destroyed by pointers. And the fact that C++ still typecasts wontonly and without being asked (yes, just like C) means that strong typing doesn't buy you much in practice. Languages with serious type systems (CommonLISP/CLOS, Smalltalk, Dylan) or runtime type systems (Perl, Python, CommonLISP/CLOS, Dylan, LPC) both tend to do better in this respect since they don't have a static type system that can be easily messed with. You could say above that what I did to myclass isn't guaranteed to work. Actually, it is if you know that myclass isn't virtual because C++ makes a lot of the bit-layout stuff part of the standard. Crazy, huh? Quote:
Quote:
Quote:
In assembly or (on some platforms) C/C++, you can take a pointer to a chunk of physical memory and directly write to it, as with the video memory. More "abstract" languages (Jave, Perl, Python, CommonLISP, Eiffel, Haskell, Dylan, LPC, SML/NJ, etc) won't let you do this. Your vocabulary is restricted from it. Linguists begin by restricting a language to the spoken parts. Can they still talk about the other bits? Well, not to other linguists. Non-linguists don't tackle it because the linguists already are. Linguists don't tackle it because they claim it's not linguistics. So you're saying that, because a specialty doesn't remove words from the language, it restricts nothing. I argue that because it causes certain areas of human experience to no longer be usefully expressable, it does. We're again back to the same argument as with C and C++ (yay, we're still on topic! Let's say that we have a (natural) language which is English plus Swahili, the full union of the two. Both are complex, and both have a pretty substantial vocabulary. An average speaker is now *less* likely to understand another average speaker, and will be far more likely to need a dictionary to accomplish anything. Speech is now more difficult, comprehension rarer and the whole thing is less effort. But between two fully omniscient speakers (which you agree are effectively impossible as the language grows more complex), it'll be a truly impressively expressive language. Yup. Useless, but very expressive. Now substitute writing code for speaking, and maintaining and debugging for reading. Quote:
1) New verb forms 2) New vocabulary for all sorts of things, especially those found in tropical climates 3) More expressive ways to swear, to congratulate and to wish good cheer 4) More words for use in songs and poetry, with correspondingly greater expressiveness there [etc] And of English over Swahili-plus-English: 1) When you don't want to deal with other people saying something you don't understand or don't like. See the parallel? You continue to argue that language designers shouldn't avoid features just because they can be misused, or are usually misused (see "goto", above). But you're ignoring the fact that a very broad language with a vast array of features is harder to comprehend, harder to debug and harder for other people to get up to speed on or contribute to. You're welcome to say that that's a problem with my coding style (actually, the coding style of my former professors and coworkers, I don't start projects in C++). Or that the people that would otherwise be extra developers are just too stupid (mediocrity versus brilliance, as you say). But you know what? I've found that in a pretty simple language, mediocre programmers produce decent, maintainable stuff that does what it's supposed to. In C++, my experience is that they produce absolute horrors. So should geniuses use C++ and mediocrities stick to Visual Basic? Maybe. But then the geniuses had better get used to never working on a project too large for four people. |
||||||||||
|
|
|
![]() |
| Thread Tools | |
Which is preferred? - Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Preferred Role Playing Level | enigma@zebedee | Advertising for Players | 27 | 04-23-2003 07:01 AM |
|
|