|
On July 09 2012 10:53 sluggaslamoo wrote:Show nested quote +On July 09 2012 06:26 NicolBolas wrote:On July 05 2012 00:43 CecilSunkure wrote:On July 04 2012 17:29 Tobberoth wrote: Cool and all, but I'm surprised you say that writing console based games is a good start for beginners because they don't have to use black box libraries, yet the point of your post is to talk about your black box library, AsciiEngine. I mean, in the same sense that AsciiEngine sets up a lot of boring stuff for you so you can focus on making the game, so does SDL, difference being that SDL supports "proper graphics". I would think most beginner developers would get more benefit, and have more fun, makind SDL games over Ascii games. That does make sense, but since this is open source if someone wanted, they could use it simply as a reference point for starting their own project. That's the point I was trying to make, if that makes any sense. There are plenty of open source engines out there. AsciiEngine is not special in this regard. Personally, I've never understood why modern games would bother with this. There is no functional difference between so-called ASCII art and a regular tile-map. It's ultimately the same thing: draw a series of images of fixed size in grid locations. If you really want your tiles to be text glyphs, then put text glyphs in your tilemap. At least then, you'll have reasonable freedom to pick a good font that serves your needs. Dwarf Fortress is a pretty good game Which can be played tile-based just as good as it can ascii based... and it looks way better to boot.
|
On July 09 2012 10:51 sluggaslamoo wrote: My qualms are pretty much exclusively about syntax. Its just so inconsistent, its as if Strousup had never heard of POLS. You could even start with how creating abstract classes requires an = 0 on the end of your methods, and you can have a static method that has a static block, which the compiler needs to cascade that "permission" down. Now think about how the sometimes the compiler requires you to use a static block for no reason (or at least not a very good one) and you got yourself a pile of supposedly more maintainable (because its OO) but actually un-maintainable code. You could spend 10 years learning C++ and still learn some new things about it. This causes mayhem when you are with a team of developers.
I have no idea what you're talking about here with the "static block" and "permission" thing. What do you mean by "static block", and what does that have to do with pure virtual syntax? And where does the compiler start forcing you to use these "static blocks" "for no reason"?
As for the Principle of Least Surprise (which I assume is what you're talking about with POLS. It's a good idea to spell the acronym out the first time), you seem to forget that Stroustrup (that's how his named is spelled) was not creating a language from scratch. The value semantics issue and the need for temporaries and such are all derived from the fact that C has value semantics and implicit object copying.
|
Indeed, C++ language needed to be back compatible with standard C and therefore a lot of problems arised.
I'm not saying that the syntax is perfect... mainly because of the template maddness(the boost library serves well as an example). But the language comes with handy stuff that many modern languages cut down on:
- Over C, simply it's object oriented - thus makes your code more readable, intuitive; must have for big projects
- Operator overloading(even assigning, copy constructing, new...)
- Control over copy constructing(cloning) and pointer assignment
- Multi-class inheritance and friend class membership
- Destructors, smart pointers(while garbage collector is cool, if you make your program well using destuctors it will make your program performance much more predictable)
- Although const can be a double edged sword, if you used it correctly it can make you program better - it's really impossible to make a read-only collection or class(or nested) in Java or C#
Many companies(even those I've worked in) make their own Standard libraries and utilities usually based on stl which makes programming in C++ really neat and sweet
|
On July 10 2012 02:44 NicolBolas wrote:Show nested quote +On July 09 2012 10:51 sluggaslamoo wrote: My qualms are pretty much exclusively about syntax. Its just so inconsistent, its as if Strousup had never heard of POLS. You could even start with how creating abstract classes requires an = 0 on the end of your methods, and you can have a static method that has a static block, which the compiler needs to cascade that "permission" down. Now think about how the sometimes the compiler requires you to use a static block for no reason (or at least not a very good one) and you got yourself a pile of supposedly more maintainable (because its OO) but actually un-maintainable code. You could spend 10 years learning C++ and still learn some new things about it. This causes mayhem when you are with a team of developers. I have no idea what you're talking about here with the "static block" and "permission" thing. What do you mean by "static block", and what does that have to do with pure virtual syntax? And where does the compiler start forcing you to use these "static blocks" "for no reason"? As for the Principle of Least Surprise (which I assume is what you're talking about with POLS. It's a good idea to spell the acronym out the first time), you seem to forget that Stroustrup (that's how his named is spelled) was not creating a language from scratch. The value semantics issue and the need for temporaries and such are all derived from the fact that C has value semantics and implicit object copying.
As this is starting to detract from the actual topic I'm gonna chuck this in a spoiler
+ Show Spoiler +As with most of my posts I rush them out and make silly mistakes, I always spell stroustrup strousup when I'm not thinking, no need to get pedantic about spelling. Just because it was built on top of C, doesn't mean he couldn't change some things, the changes he did make, just made it messy. Why do we use iostream and cout? What's the point? Pure virtual methods require an = 0 on the end. Not a huge issue, but it is just one of the many inconsistencies within syntax. Its unnecessary. When you are doing some complex OO designs or use some OO libraries eventually you may come across this issue. (sorry I meant const not static). Here is an example method in a trivial C++ battleships game I did a really really long time ago. public: const Cell& Board::operator [] (const Coordinate& c) const; In the "Liskov branch" of OOP I am required to make things as abstracted/encapsulated/type-safe as possible, in order to add maintainability, by reducing fear of side-effects. Thus const is used for everything that should be immutable, leading to large amount of the modifiers used above, regardless of how pragmatic or inelegant it is in real life. Declaring the same thing in another language requires half the verbosity, so I blame C++ for how ugly this looks. What's worse is someone can use the "mutable" keyword to "un-const" it. 1. Two const keywords in the one method declaration (excluding parameters), the behaviour is differentiated by the position of the keyword const in the definition, syntactically this is awful design. const before the block implies an immutable block, but what it really means is that `self` is immutable within that block. (I forgot the real term for "const block" its been many years so cut me some slack here ) 2. const Coordinate&. I get that type safety is a big deal, but we have 4 ways of declaring almost exactly the same thing. We could have Coordinate, Coordinate*, Coordinate&, const Coordinate*, const Coordinate&, and const Coordinate. They all have their slight nuances, but it doesn't really matter, it is really the same parameter. The fact that C++ requires you to match that parameter perfectly causes mayhem, it is just like having a goto statement, instead of forcing people to just declare things with a single entry and exit point. If you really (really REALLY) want to duplicate a data structure in memory via way of passing an argument, then just duplicate the friggin data structure before you pass it in, and for the rest of them, assume an immutable reference or immutable pointer to a mutable object. And if you REALLY want an immutable pointer, then assign a new pointer before passing the argument. Sure its derived from C, but C wasn't designed to be OO, so it didn't matter (as much). Why can't we just have one way of declaring the requirement of an immutable object, so programmers won't get pedantic about mitigating side-effects and causing all sorts of problems. Indeed other languages did just that. 3. Usage of operator and [], why can't it just be Board::[]? 4. Why do nest classes inside a namespace block, but I don't nest method implementations inside a class block, but I nest method implementations inside the class block in the header, but I don't nest public methods inside public block? Why does the public keyword automatically nest methods under it, and why does it have a ":" on the end? Why doesn't it follow standard C convention? About the compiler forcing me to use const "const block" creates an annoying permission problem because of the way C++ handles immutability and type-safety. I haven't used C++ in a long time, but iirc if you declare a "const block", often the compiler will force you to declare other methods "const" that use it. When you have a bunch of these, it actually becomes almost impossible to implement methods that are re-usable, or even do anything useful, because you try to modify `self` and the compiler cracks it because you are required to use this const block. Also One cannot simply avoid using ‘const’ on class methods because ‘const’ is infectious. An object which has been made ‘const’, for example by being passed as a parameter in the ‘const &’ way, can only have those of its methods that are explicitly declared ‘const’ called (because C++’s calling system is too simple to work out which methods not explicitly declared ‘const’ don’t actually change anything). Therefore class methods that don’t change the object are best declared ‘const’ so that they are not prevented from being called when an object of the class has somehow acquired ‘const’ status. In later versions of C++, an object or variable which has been declared ‘const’ can be converted to changeable by use of ‘const_cast’ which is a similar bodge to ‘mutable’ and using it likewise renders ‘const’ virtually useless. I just found this, he explains it way better than I do. http://duramecho.com/ComputerInformation/WhyHowCppConst.htmlAlso I just fail to see how the OO capabilities of C++ lead to the goals of OO. OO is largely about reducing costs and overhead through maintainability and re-usability. Because of the clunkiness and inconsistency, you often find yourself breaking things down into non-reuseable methods. So your code base often just doesn't end up any more maintable than a regular C program. Add onto this the amount of verbosity in C++, often I can implement an OO program using ADT's in C and have a smaller, more maintable, more readable code-base than C++. Hope I explained things a little better this time.
|
Const block? Do you mean constant methods? In this regard the compiler only enforces one thing: const methods must not call non-const methods. The reason for this is extremely obvious XD
|
On July 10 2012 23:41 LastWish wrote:Indeed, C++ language needed to be back compatible with standard C and therefore a lot of problems arised. I'm not saying that the syntax is perfect... mainly because of the template maddness(the boost library serves well as an example). But the language comes with handy stuff that many modern languages cut down on: - Over C, simply it's object oriented - thus makes your code more readable, intuitive; must have for big projects
- Operator overloading(even assigning, copy constructing, new...)
- Control over copy constructing(cloning) and pointer assignment
- Multi-class inheritance and friend class membership
- Destructors, smart pointers(while garbage collector is cool, if you make your program well using destuctors it will make your program performance much more predictable)
- Although const can be a double edged sword, if you used it correctly it can make you program better - it's really impossible to make a read-only collection or class(or nested) in Java or C#
Many companies(even those I've worked in) make their own Standard libraries and utilities usually based on stl which makes programming in C++ really neat and sweet
I just want to go over your list. I'm not directing this at you, I just think these are invalid reasons that people hype up about C++.
1. Unlike Java, I rarely see people use the OO functionaliy of C++ like polymorphism to the fullest extent simply because of how clunky it is and how many problems it causes. Usage of ADT's in C often look and work better than the use of objects in C++, its kind of sad.
2. Operator overloading exists in every language . I think you mean operator overriding? I don't know what's worse, adding some quirky functionality instead of just plain reducing the verbosity of the language, or the fact that you can actually override an operator in a performance focused language. "Sup Array, why you so slow? And why is my Integer not adding?"
3. Another thing I have to think about, because apparently its really hard to just create a method and call it copy().
4. a) friend = omfg r u srs? really? b) Diamond problem, not saying multiple implementation inheritance is bad, but in C++ its done really badly.
5. Ok fine
6. See above
|
On July 11 2012 16:18 Mstring wrote: Const block? Do you mean constant methods? In this regard the compiler only enforces one thing: const methods must not call non-const methods. The reason for this is extremely obvious XD
Hey its been a while ok xD
That's right, I remember now. And yeah the reason IS obvious when you remember how to do it . Anyway my stance on it still stands, it causes un-reusability of code.
|
C++ is the only tool that works for my purposes so I don't complain :D
I've seen some production C++ code; I can understand how some practices might cause problems in a team environment. Luckily I'm a one man team. Code reusability? XD
|
On July 11 2012 16:20 sluggaslamoo wrote:Show nested quote +On July 10 2012 23:41 LastWish wrote:Indeed, C++ language needed to be back compatible with standard C and therefore a lot of problems arised. I'm not saying that the syntax is perfect... mainly because of the template maddness(the boost library serves well as an example). But the language comes with handy stuff that many modern languages cut down on: - Over C, simply it's object oriented - thus makes your code more readable, intuitive; must have for big projects
- Operator overloading(even assigning, copy constructing, new...)
- Control over copy constructing(cloning) and pointer assignment
- Multi-class inheritance and friend class membership
- Destructors, smart pointers(while garbage collector is cool, if you make your program well using destuctors it will make your program performance much more predictable)
- Although const can be a double edged sword, if you used it correctly it can make you program better - it's really impossible to make a read-only collection or class(or nested) in Java or C#
Many companies(even those I've worked in) make their own Standard libraries and utilities usually based on stl which makes programming in C++ really neat and sweet I just want to go over your list. I'm not directing this at you, I just think these are invalid reasons that people hype up about C++. 1. Unlike Java, I rarely see people use the OO functionaliy of C++ like polymorphism to the fullest extent simply because of how clunky it is and how many problems it causes. Usage of ADT's in C often look and work better than the use of objects in C++, its kind of sad. 2. Operator overloading exists in every language . I think you mean operator overriding? I don't know what's worse, adding some quirky functionality instead of just plain reducing the verbosity of the language, or the fact that you can actually override an operator in a performance focused language. "Sup Array, why you so slow? And why is my Integer not adding?" 3. Another thing I have to think about, because apparently its really hard to just create a method and call it copy(). 4. a) friend = omfg r u srs? really? b) Diamond problem, not saying multiple implementation inheritance is bad, but in C++ its done really badly. 5. Ok fine 6. See above
Many of the things you address(overall in this thread) are connected to bad programming habits/inexperience. It's like you would argue that StarCraft allows many strategies/build orders but many of them simply don't work on professional level. Blame the people not the language.
Back to the list:
- 1. I don't know what you are talking about, only problem you really have to worry about are virtual destructors, other than that your inheritance works just like in Java.
- 2. Operator overloading is not present in Java. That's why I prefer C# over Java because I can never construct a pretty intuitive class:
Take for example Complex or Vector class: It will always be: resultVector = baseVector.mul(vector1.add(vector2)); Instead of: resultVector = baseVector * (vector1 + vector2); The more complex expression you write the more messy it gets. C# does have operator overloading for many operators, but still you still can't for example overload assigment(=) or "new" keword. While this will not be the every day use, one day you will find use for it: a) assigment(=): for example a class that stores it's history values. Simply you overload assigment and upon execution store the previous value to an array of some sort. b) new keyword: for example you want to make a class that for some reason needs to be a pool(like is used very frequently in large arrays and is small by itself). You can overload the new keyword to do work for you and you don't have to give a shit for the rest of the program.
- 3. It's just impractical to create copy() or Clone() method on every occasion for every class. I tried to solve this problem in C# by using reflection - guess what reflection is a slow dirty pig.
- 4. Yeah diamond problem mainly and it's really common, I agree that the syntactic solution for this was not very pleasant. However you can do it! And it's not really that hard, by the way I don't know any other compilable language that you could deal with this... and using some form of proxy classing instead is a headache.
Friend classes are just nice and sometimes they come handy. It's not really that big of a problem, but if you need them and don't have them again you have to use ugly proxy class pattern.
- 6. Take for example C# language:
We have some kind of class "Item" which has publicly settable/gettable properties(or fields or whatever) Cost and Type. Now you have them in a collection for example a List<Item>. You want to pass them this list to a function TotalCost that would compute the total cost. There is no way you can make the members of this collection not editable. Even if you use some form of ReadOnlyList<Item>, once you can get the Item you can set the Cost at will. In C++ however you simple use make: int TotalCost(const vector<Item> &items); What you were addressing were pointer const problems: const char *arr const; Now these are really ugly and unintuitive, however in C++ you try to avoid using pointers or pointer arrays as much as you can. Class function const: class Calculator{ ... int TotalCost(const vector<Item> &items) const; }; Now many of these const functions of the class are a pain and could be auto-detected by a compiler(one day perhaps): TotalCost impl{ func1 func2 func3 } -> func1, func2, func3 all do const operations on class Calculator therefore auto-const. Pretty easy to imagine, probably a little harder to implement... Function const parameter maddness: In C++ 95% of time you will be using just: const type ¶meter and type ¶meter; obviously some primitive types(int) don't need to use &. No big deal just some good practices that make you programming life easy and fun.
Once again I think there are many bad programmers in the world.. hence I may be one of them and not know it! Blame the people not the language.
|
+ Show Spoiler +On July 11 2012 18:13 LastWish wrote:Show nested quote +On July 11 2012 16:20 sluggaslamoo wrote:On July 10 2012 23:41 LastWish wrote:Indeed, C++ language needed to be back compatible with standard C and therefore a lot of problems arised. I'm not saying that the syntax is perfect... mainly because of the template maddness(the boost library serves well as an example). But the language comes with handy stuff that many modern languages cut down on: - Over C, simply it's object oriented - thus makes your code more readable, intuitive; must have for big projects
- Operator overloading(even assigning, copy constructing, new...)
- Control over copy constructing(cloning) and pointer assignment
- Multi-class inheritance and friend class membership
- Destructors, smart pointers(while garbage collector is cool, if you make your program well using destuctors it will make your program performance much more predictable)
- Although const can be a double edged sword, if you used it correctly it can make you program better - it's really impossible to make a read-only collection or class(or nested) in Java or C#
Many companies(even those I've worked in) make their own Standard libraries and utilities usually based on stl which makes programming in C++ really neat and sweet I just want to go over your list. I'm not directing this at you, I just think these are invalid reasons that people hype up about C++. 1. Unlike Java, I rarely see people use the OO functionaliy of C++ like polymorphism to the fullest extent simply because of how clunky it is and how many problems it causes. Usage of ADT's in C often look and work better than the use of objects in C++, its kind of sad. 2. Operator overloading exists in every language . I think you mean operator overriding? I don't know what's worse, adding some quirky functionality instead of just plain reducing the verbosity of the language, or the fact that you can actually override an operator in a performance focused language. "Sup Array, why you so slow? And why is my Integer not adding?" 3. Another thing I have to think about, because apparently its really hard to just create a method and call it copy(). 4. a) friend = omfg r u srs? really? b) Diamond problem, not saying multiple implementation inheritance is bad, but in C++ its done really badly. 5. Ok fine 6. See above Many of the things you address(overall in this thread) are connected to bad programming habits/inexperience. It's like you would argue that StarCraft allows many strategies/build orders but many of them simply don't work on professional level. Blame the people not the language. Back to the list: - 1. I don't know what you are talking about, only problem you really have to worry about are virtual destructors, other than that your inheritance works just like in Java.
- 2. Operator overloading is not present in Java. That's why I prefer C# over Java because I can never construct a pretty intuitive class:
Take for example Complex or Vector class: It will always be: resultVector = baseVector.mul(vector1.add(vector2)); Instead of: resultVector = baseVector * (vector1 + vector2); The more complex expression you write the more messy it gets. C# does have operator overloading for many operators, but still you still can't for example overload assigment(=) or "new" keword. While this will not be the every day use, one day you will find use for it: a) assigment(=): for example a class that stores it's history values. Simply you overload assigment and upon execution store the previous value to an array of some sort. b) new keyword: for example you want to make a class that for some reason needs to be a pool(like is used very frequently in large arrays and is small by itself). You can overload the new keyword to do work for you and you don't have to give a shit for the rest of the program.
- 3. It's just impractical to create copy() or Clone() method on every occasion for every class. I tried to solve this problem in C# by using reflection - guess what reflection is a slow dirty pig.
- 4. Yeah diamond problem mainly and it's really common, I agree that the syntactic solution for this was not very pleasant. However you can do it! And it's not really that hard, by the way I don't know any other compilable language that you could deal with this... and using some form of proxy classing instead is a headache.
Friend classes are just nice and sometimes they come handy. It's not really that big of a problem, but if you need them and don't have them again you have to use ugly proxy class pattern.
- 6. Take for example C# language:
We have some kind of class "Item" which has publicly settable/gettable properties(or fields or whatever) Cost and Type. Now you have them in a collection for example a List<Item>. You want to pass them this list to a function TotalCost that would compute the total cost. There is no way you can make the members of this collection not editable. Even if you use some form of ReadOnlyList<Item>, once you can get the Item you can set the Cost at will. In C++ however you simple use make: int TotalCost(const vector<Item> &items); What you were addressing were pointer const problems: const char *arr const; Now these are really ugly and unintuitive, however in C++ you try to avoid using pointers or pointer arrays as much as you can. Class function const: class Calculator{ ... int TotalCost(const vector<Item> &items) const; }; Now many of these const functions of the class are a pain and could be auto-detected by a compiler(one day perhaps): TotalCost impl{ func1 func2 func3 } -> func1, func2, func3 all do const operations on class Calculator therefore auto-const. Pretty easy to imagine, probably a little harder to implement... Function const parameter maddness: In C++ 95% of time you will be using just: const type ¶meter and type ¶meter; obviously some primitive types(int) don't need to use &. No big deal just some good practices that make you programming life easy and fun.
Once again I think there are many bad programmers in the world.. hence I may be one of them and not know it! Blame the people not the language.
Once again I think there are many bad programmers in the world.. hence I may be one of them and not know it!
Now you know! :D
+ Show Spoiler +kidding. but cmon man its ok to argue C++ because I don't use it a lot and haven't used it for years maybe ill slip up like i did in my first post, but now you are arguing pure OOP with someone who lives and breathes OOP
|
Just because it was built on top of C, doesn't mean he couldn't change some things, the changes he did make, just made it messy. Why do we use iostream and cout? What's the point?
He (Stroustrup) didn't invent std::iostreams. It's important to differentiate between the language and the language's standard library.
Indeed, iostreams violate one of Stroustrup's basic ideas with C++: you only pay for what you use. iostreams have a lot of tools for extensibility, character and encoding conversions, etc. But if you just want to format a floating-point value into a string, you're still paying for all of the cost of those points of extensibility (namely, the virtual function overhead for writing characters to streams).
3. Usage of operator and [], why can't it just be Board::[]?
Because it makes the parser much easier to write. And it makes it clear to the reader of the code that you're overloading an operator.
4. Why do nest classes inside a namespace block, but I don't nest method implementations inside a class block, but I nest method implementations inside the class block in the header, but I don't nest public methods inside public block?
Why does the public keyword automatically nest methods under it, and why does it have a ":" on the end? Why doesn't it follow standard C convention?
... what?
Public doesn't define a block. That's why it ends in a `:`. It's use is much more like the `case` statement, which also doesn't define a block. The public specification continues until another specification statement is reached. There is no block or scope involved.
It's funny that you say that C++ is more verbose, then you say that it's not verbose enough in that you should have to explicitly scope `public` methods or otherwise use `public` with every method definition.
Also, C++ has the `using` directive if you want to import a name into a namespace.
"const block" creates an annoying permission problem because of the way C++ handles immutability and type-safety. I haven't used C++ in a long time, but iirc if you declare a "const block", often the compiler will force you to declare other methods "const" that use it.
When you have a bunch of these, it actually becomes almost impossible to implement methods that are re-usable, or even do anything useful, because you try to modify `self` and the compiler cracks it because you are required to use this const block.
First of all, there's no "const block". I have no idea what you're talking about. The `const` you put at the end of a member declaration/definition defines how this is accessed. Think of a method as:
ReturnType MemberName(Parameters paramName) this {}
Except that `this` isn't explicit because it's a member.
When you use `const`, you're saying this:
ReturnType MemberName(Parameters paramName) const this {}
This making all uses of `this` const. That is not a "const block"; that's a "const member function". The `const` is part of the function signature, not a modifier to the "block".
Second, if you're having problems maintaining const correctness, that's your fault. If you call a `const` member, that function shouldn't need to modify the object it is a member of. If it did, then it wouldn't be `const`. So if you run into this problem, it's because your design is wonky.
Don't blame the tool for your own design errors.
Unlike Java, I rarely see people use the OO functionaliy of C++ like polymorphism to the fullest extent simply because of how clunky it is and how many problems it causes. Usage of ADT's in C often look and work better than the use of objects in C++, its kind of sad.
So?
OOP (by which I mean the use of derived classes in place of base classes through virtual functions) is one mechanism of allowing old code to call new code. That's one way to handle this sort of thing. C++ offers this, but it also offers templates, which is another mechanism for allowing old code to call new code.
Java has only one mechanism; C++ has two. So obviously, you're going to see less OOP-style derived classes when you have viable alternatives you could use instead.
Has it occurred to you that maybe they don't use OOP derived classes as much in C++ because there are better ways to reuse old code in many cases? That a template function which can work on any type, even those not explicitly defined to use it, is better than OOP? Or that maybe the OOP class model isn't the most flexible model in the world?
OOP is not God; don't worship it.
Also, I have never seen abstract data types in C that support easy virtual function overriding by outside parties. In general, if overriding happens, it's all done within the library. If you're an outside user, the best you get is a callback here and there.
ADTs are fine for exposing an object to the user. But they generally don't allow the user to customize that object with their own functions or alter the behavior of other functions that use that object.
|
On July 12 2012 05:13 NicolBolas wrote: Also, I have never seen abstract data types in C that support easy virtual function overriding by outside parties. In general, if overriding happens, it's all done within the library. If you're an outside user, the best you get is a callback here and there. Really? Why not? I'd think of it as simple as a pointer swap, and as long as you keep the interface constant it shouldn't be super hard (unless perhaps internal like the data definitions were hidden).
|
Also, I have never seen abstract data types in C that support easy virtual function overriding by outside parties. In general, if overriding happens, it's all done within the library. If you're an outside user, the best you get is a callback here and there.
ADTs are fine for exposing an object to the user. But they generally don't allow the user to customize that object with their own functions or alter the behavior of other functions that use that object
And all of those features are necessary because?
Virtual function overriding has nothing to do with OO and causes fragility within a program, the exact opposite of what OO is trying to achieve.
Has it occurred to you that maybe they don't use OOP derived classes as much in C++ because there are better ways to reuse old code in many cases? That a template function which can work on any type, even those not explicitly defined to use it, is better than OOP? Or that maybe the OOP class model isn't the most flexible model in the world?
OOP is not God; don't worship it.
Did you learn OOP from C++? If that's the case I can end this right here. Stroustrup invented this funky clunky paradigm and labelled it "OOP" when it really isn't, instead lets call it "Stroustrup-Liskov programming". OOP was invented by Alan Kay, guess what, he had no input on C++. They also hate each other, but its funny that Stroustrup tried to create an OOP language without any input from the guy who actually invented OOP.
Its also interesting how biology came up with a much more elegant solution to OO than mathematics did.
It doesn't even make sense from a pure OO paradigm sense, so it's no wonder you don't think its good. If you understand OOP from C++, you don't understand OOP at all.
First of all, there's no "const block". I have no idea what you're talking about. The `const` you put at the end of a member declaration/definition defines how this is accessed. Think of a method as:
...
This making all uses of `this` const. That is not a "const block"; that's a "const member function". The `const` is part of the function signature, not a modifier to the "block".
Yeah, but it looks like a modifier to the block.
Like I said, I forgot the term because it's been 4 years. Big deal, it seems you knew exactly what I was talking about, even though you said you don't know what I'm talking about.
My point is... what's the point of it? If I define a const member function, I can only use const member functions. Its stupid. There are sooo many better ways of doing this, that would also enable me to re-use more code.
Second, if you're having problems maintaining const correctness, that's your fault. If you call a `const` member, that function shouldn't need to modify the object it is a member of. If it did, then it wouldn't be `const`. So if you run into this problem, it's because your design is wonky.
I blame the tool for forcing me to use a wonky design (read the link in my last post). Just like Java forces me to use interfaces because implementation inheritance causes fragility, instead of just having duck-typing, traits, mixins.
I don't have problems maintaining const correctness, I have problems with const correctness making things impossible to read. Like I said previously, you don't need 4 ways of defining the almost exact same parameter when you can just use an immutable object, and there are 6 different ways you could ask for that parameter, those 4 different ways mean that you need to waste time manipulating your arguments to fit that signature.
In Object Oriented Programming, calling a ‘method’ (the Object Oriented name for a function) of an object gives an extra complication. As well as the variables in the parameter list, the method has access to the member variables of the object itself which are always passed directly not as copies. For example a trivial class, ‘Class1’, defined as
class Class1 { void Method1(); int MemberVariable1;} has no explicit parameters at all to ‘Method1’ but calling it in an object in this class might alter ‘MemberVariable1’ of that object if ‘Method1’ happened to be, for example,
void Class1::Method1() { MemberVariable1=MemberVariable1+1;} The solution to that is to put ‘const’ after the parameter list like
class Class2 { void Method1() const; int MemberVariable1;} which will ban Method1 in Class2 from being anything which can attempt to alter any member variables in the object.
Of course one sometimes needs to combine some of these different uses of ‘const’ which can get confusing as in
const int*const Method3(const int*const&)const;
where the 5 uses ‘const’ respectively mean that the variable pointed to by the returned pointer & the returned pointer itself won’t be alterable and that the method does not alter the variable pointed to by the given pointer, the given pointer itself & the object of which it is a method!.
Because it makes the parser much easier to write. And it makes it clear to the reader of the code that you're overloading an operator.
Overriding, not overloading.
I think its pretty clear from Board::[] that its an operator override. Second of all that's how other languages do it. Thirdly, writing language parsers is incredibly easy, just a little bit time consuming. It's pretty easy to parse anything.
Java has only one mechanism; C++ has two. So obviously, you're going to see less OOP-style derived classes when you have viable alternatives you could use instead.
Guess what? Java sucks too! This isn't a C++ vs Java debate.
... what?
Public doesn't define a block. That's why it ends in a `:`. It's use is much more like the `case` statement, which also doesn't define a block. The public specification continues until another specification statement is reached. There is no block or scope involved.
It's funny that you say that C++ is more verbose, then you say that it's not verbose enough in that you should have to explicitly scope `public` methods or otherwise use `public` with every method definition.
duhhhh, that's exactly what I mean. Yes, case is inconsistent too!
I think I made that pretty clear, public should precede a block {}. It takes ONE extra character, omfg. When C++ is not being verbose, its being inconsistent, it's almost never concise and consistent at the same time.
namespace foo { class Bar {
public: <<< wtf? method } }
It should be.
namespace foo { class Bar {
public { method }
} }
OR
namespace blah:
class Blah:
public: method
He (Stroustrup) didn't invent std::iostreams. It's important to differentiate between the language and the language's standard library.
Umm... yes he did.
The original iostream library was written to challenge the claim that a terse, type safe I/O system needed special language support. [1] It was developed at Bell Labs by Bjarne Stroustrup and shipped with the original C++ compiler, CFront and described in the first edition of Stroustrup's The C++ Programming Language.
Omg, no wonder its fucking terrible!
Although I thought I had made it pretty clear how C++ is inconsistent, and its added features are pretty near useless, in my previous post. Honestly, I think Stroustrup was on crack when he designed this language.
A C++ programmer may still be learning new things about the language after 10 years (which is bad). Why is this bad? have fun working in a large team of C++ developers. I listed 4 problems for a single line of code, that don't exist in other languages, you haven't really covered them.
|
Great Post! I dig the ASCII and opensource vibe. Although I'm not what I would call a programmer, I know my way around a command line (bash) and games that can run without a graphical environment always turn me on. =]
That said I'd like to address this vvv
On July 09 2012 19:56 Tobberoth wrote:Show nested quote +On July 09 2012 10:53 sluggaslamoo wrote:On July 09 2012 06:26 NicolBolas wrote:On July 05 2012 00:43 CecilSunkure wrote:On July 04 2012 17:29 Tobberoth wrote: Cool and all, but I'm surprised you say that writing console based games is a good start for beginners because they don't have to use black box libraries, yet the point of your post is to talk about your black box library, AsciiEngine. I mean, in the same sense that AsciiEngine sets up a lot of boring stuff for you so you can focus on making the game, so does SDL, difference being that SDL supports "proper graphics". I would think most beginner developers would get more benefit, and have more fun, makind SDL games over Ascii games. That does make sense, but since this is open source if someone wanted, they could use it simply as a reference point for starting their own project. That's the point I was trying to make, if that makes any sense. There are plenty of open source engines out there. AsciiEngine is not special in this regard. Personally, I've never understood why modern games would bother with this. There is no functional difference between so-called ASCII art and a regular tile-map. It's ultimately the same thing: draw a series of images of fixed size in grid locations. If you really want your tiles to be text glyphs, then put text glyphs in your tilemap. At least then, you'll have reasonable freedom to pick a good font that serves your needs. Dwarf Fortress is a pretty good game Which can be played tile-based just as good as it can ascii based... and it looks way better to boot.
A) Many people (like myself) find inherent beauty in the 'graphics' that were available before modern 'graphics'. Not unlike Brood War it's beauty lies in it's clearly understood limits, and when an artist navigates within those limits, but in a way that has never been seen before it more clearly shows the skill of the artist. B) Headless systems (without a monitor) sometimes need games too. These systems are usually logged into from a text-based interface which cannot display graphics that are not made up of ASCII characters. Admittedly this is more common among *nix computers I believe it can apply to windows as well.
|
On July 13 2012 01:48 DJXR wrote:Great Post! I dig the ASCII and opensource vibe. Although I'm not what I would call a programmer, I know my way around a command line (bash) and games that can run without a graphical environment always turn me on. =] That said I'd like to address this vvv Show nested quote +On July 09 2012 19:56 Tobberoth wrote:On July 09 2012 10:53 sluggaslamoo wrote:On July 09 2012 06:26 NicolBolas wrote:On July 05 2012 00:43 CecilSunkure wrote:On July 04 2012 17:29 Tobberoth wrote: Cool and all, but I'm surprised you say that writing console based games is a good start for beginners because they don't have to use black box libraries, yet the point of your post is to talk about your black box library, AsciiEngine. I mean, in the same sense that AsciiEngine sets up a lot of boring stuff for you so you can focus on making the game, so does SDL, difference being that SDL supports "proper graphics". I would think most beginner developers would get more benefit, and have more fun, makind SDL games over Ascii games. That does make sense, but since this is open source if someone wanted, they could use it simply as a reference point for starting their own project. That's the point I was trying to make, if that makes any sense. There are plenty of open source engines out there. AsciiEngine is not special in this regard. Personally, I've never understood why modern games would bother with this. There is no functional difference between so-called ASCII art and a regular tile-map. It's ultimately the same thing: draw a series of images of fixed size in grid locations. If you really want your tiles to be text glyphs, then put text glyphs in your tilemap. At least then, you'll have reasonable freedom to pick a good font that serves your needs. Dwarf Fortress is a pretty good game Which can be played tile-based just as good as it can ascii based... and it looks way better to boot. A) Many people (like myself) find inherent beauty in the 'graphics' that were available before modern 'graphics'. Not unlike Brood War it's beauty lies in it's clearly understood limits, and when an artist navigates within those limits, but in a way that has never been seen before it more clearly shows the skill of the artist. B) Headless systems (without a monitor) sometimes need games too. These systems are usually logged into from a text-based interface which cannot display graphics that are not made up of ASCII characters. Admittedly this is more common among *nix computers I believe it can apply to windows as well.
Man, given a few minor changes bash would make an awesome scripting language for games (espec text based ones), its so freaking fast but still feels similar to many of the modern dynamic languages. I actually created a grammar for a language inspired by bash, but I never got around to converting the resulting AST into another language.
On a side note, the best way to know if your language is good or not, is to leave it alone for a few months and come back to it. If you can't read it, you need to go back to the drawing board. I thought my language was so awesome when i wrote it, then I looked back at the examples 3 months later and no idea what it did, hah. Maybe ill finish it some day.
|
Bjarne only wrote streams, which laid a lot of the foundation but didn't have a lot of stuff that was in the initial version of iostream. Also it's considered rude to source a material from gamedev (who did sourced material to an interpretation of the C++ book) and not give credit >_>
On the other hand, here's the direct quote from the book itself:
"The stream library as described in the first edition of this book was designed and implemented by me. Jerry Schwarz transformed it into the iostreams library (Chapter 21) using Andrew Koenig's manipulator technique (sec21.4.6) and other ideas. The iostreams library was further refined during standardization, when the bulk of the work was done by Jerry Schwarz, Nathan Myers, and Norihiro Kumagai."
- The C++ Programming Language, Bjarne Stroustrup Page 11
Further discussion of the evolution of iostream:
C++ View: Jerry Schwarz reviewed the history of IOStream in the preface of the book Standard C++ IOStream and Locales. I guess that there must be many interesting stories in the process of transiting from classic stream into the standard IOStream. Can you tell us some?
Bjarne Stroustrup: I do not want to try to add to Jerry's description of the transition from my streams to the current iostreams. Instead, I'd like to emphasize that the original streams library was a very simple and very efficient library. I designed and built it in a couple of months.
The key decisions was to separate formatting from buffering, and to use the type-safe expression syntax (relying on operators << and >>). I made these decisions after discussions with my colleague Doug McIlroy at AT&T Bell Labs. I chose << and >> after experiments showed alternatives, such as < and >, comma, and = not to work well. The type safety allowed compile-time resolution of some things that C-style libraries resolve at run-time, thus giving excellent performance. Very soon after I started to use streams, Dave Presotto transparently replaced the whole buffering part of my implementation with a better one. I didn't even notice he'd done that until he later told me!
The current iostreams library will never be small, but I believe that aggressive optimization techniques will allow us to regain the efficiency of the original in the many common cases where the full generality of iostreams is not used. Note that much of the complexity in iostreams exist to serve needs that my original iostreams didn't address. For example, standard iostreams with locales can handle Chinese characters and strings in ways that are beyond the scope of my original streams. http://www2.research.att.com/~bs/01chinese.html (it's down for me but http://webcache.googleusercontent.com/search?q=cache:http://www2.research.att.com/~bs/01chinese.html worked)
Tbh I can't believe you're still posting things suggesting that C++ code is unmaintainable. I think it must be your goal on this forum to come in to Cecil's posts and start C vs. C++ wars.
Why not start your own blog post targeting it with first party sourced material and go from there?
|
|
|
|