Thread: Re: [GD-General] Eiffel (Page 2)
Brought to you by:
vexxed72
From: J C L. <cl...@ka...> - 2001-12-20 22:08:05
|
On Thu, 20 Dec 2001 16:47:17 -0500 Thatcher Ulrich <tu...@tu...> wrote: > These days emacs knows a lot, straight out of the box. It knows > about RCS and CVS, it knows how to indent and highlight various > languages, how to run a build tool and bring you to the errors, > how to run a source-level debugger, how to auto-complete. It's > got rectangle modes, outline modes, text modes, spell checkers, > yadda yadda. FWLIW those things have been true for at least 6 years, and I think closer to 8. > It can go out to the 'net and edit files via ftp. Use TRAMP (tramp.el) and you can add SSH, rsh, rsync, and various other transports to that, as well as the ability to bounce thru one or more intermediate systems (eg a firewall) to get to the final file. > None of this stuff requires any customization; you just have to > dig a bit in the docs to learn the existence of the feature, and > the keybindings and/or command names. Web searching also helps. There's a very large raft of variously home grown and third party elisp out there that works very nicely. ObNote: I just found align-regexp.el (align regex matches vertically) and dict.el (a dict client) a few months ago, both of which have turned out to be very useful. ftp://ftp.kanga.nu/pub/users/claw/dot/xemacs/ > My general philosophy is to *not* fiddle with my .emacs too much; > instead upgrade my wetware -- learn the default keys & commands, > and only customize if I really have to. Conversely, my approach is to make the tools adapt to me. I'm the human. They're the machines. Machines are there to do things for me, not me for them. I don't always succeed, and I regularly backtrack and pick up the path the tool originally took instead, but those are more issues with how my views and expectations grow rather than of the approach or tools themselves. This partially explains why my .xemacs is almost 14K lines. -- J C Lawrence ---------(*) Satan, oscillate my metallic sonatas. cl...@ka... He lived as a devil, eh? http://www.kanga.nu/~claw/ Evil is a name of a foeman, as I live. |
From: gabor f. <xl...@po...> - 2001-12-20 00:59:26
|
well, i don't have much experience in large-scale development ( i'm still studying ), but i think i'll share my opinions too... warning, this will be long :-) 12/20/2001, 12:54 AM,Thatcher Ulrich wrote: >> And I just find the whole notion of text files that store lines of code >> horribly quaint. It's the new millenium and we're still worrying about >> things like forward declarations and circular dependencies. I find that >> amazing. > I've heard this gripe a few times lately, and I really don't see it. > What's wrong with files, really? Isn't it really C++'s > declare-before-use that's the problem? the problem is that in c++ i'm creating objects. i don't create text-files ( well, i'm creating them because i must, and not because i like them ).. for example c++, templates... because c++ programs are compiled on a per-file basis, the compiler puts the code for vector<int> into every obj-file where i use them.. of course at link time he can remove the redundant ones, but still.. i don't remember but there was a problem with templates because of that per-file-compiling, and the only compiler that had no problems was ibm visualage because he doesn't work with files ( actually i didn't try it, i've read it .. ) so why can't we have in the development tool a database of objects? i don't care about where he is on my hdd, i only want to get my exe :-) the languages i've met: c++: most of time i use this one, and it's good for a lot of things ( the second best language for everything )... but i find it too low-level.. i know that i have to pay the price for speed, but still.. and templates.... they are a great thing for vector<int> and i don't want to touch ever a language without such constructs.. but they are crazy things, and i don't think people will learn to use template-metaprogramming like it is in some books.. yes, they are nice to look at... "wow, you can to THAT with templates", but to write them.... and of course most of compilers don't support everything, and error-messages.... even for a simple vector<string>, if you make a mistake you get a 2000char long error message so simply i think c++ is too big ( i think bloated is the correct term ).. it has too many features and because of that it's hard to create compilers for that... i'm not an expert, but i think the "export" keyword is in the ansi standard and still noone implemented it.. java: when i've begun working with java, it looked so clean... clean i mean i was used to that in every c++ compiler i had to use macros, and all kind of ugly preprocessor directives.. in java there was nothing like that.. i could focus on my objects, if i wanted to use an another object,i simply used it and java found it ( or i had to import it,but it's still better than #include.. i hate #include ) everything ( ok,nearly everything) was an object, i didn't have to write const Vertex& a all the time i could use simply Vertex a, but there were no templates.... i had to cast on every step when i wanted to insert/get something into/from a container...ugly... no operator overloading .... i don't want to read/write constructs like Vertex a,b,c; a = b.add(c.mul(d.sub(a,b),g.xor... c#: it's the same as java, except they support operator overloading and it's more or less microsoft only ( actually at www.go-mono.com, they're trying to create an unix version ) lisp: i've met him at the university :-)... functional programming was very interesting... not so much practical but very interesting.. you had to look at your problems from a completely different point of view... i recommend to everyone to try some functional languages... but i don't think in the near future we'll be creating graphics programs in ocaml.. python: super. python is the kind language i would like to use in the future.... high level... for example dictionaries are a basic data-type.. fully object-oriented... it doesn't have templates,but he doesn't need them, you can write like this: function add(a,b) { return a + b; }, and he checks everything but the best thing was that everything worked as i expected.. i looked at some code and i could tell you what it is doing i'll just stop now and wait for your opinions :-) bye, gabor |
From: Kent Q. <ken...@co...> - 2001-12-19 23:12:49
|
Brian Hook wrote: > (quick note: if you have an interest C++'s weaknesses, please check out > Ian Joyner's fantabulous paper on the subject at: > http://www.elj.com/cppcv3/ ). Thanks for the link. I haven't finished it yet, but what I've read so far is interesting, intelligent and well-reasoned (unlike most rants about C++ or other languages). > I won't bore you folks with my typical rant about how languages kinda > suck, and development environments suck even worse, and how the two > really need to be the same thing (yeah, I know, SmallTalk...), but > instead I'll just ask: anyone here actually use Eiffel relatively > recently for any projects, and if so, what did you think about it? Can I attempt to summarize? Some languages are good at expressing really powerful data abstractions: I'd include most of the OO languages in this space, including C++, Java, Smalltalk, Eiffel. Some languages are good at expressing really powerful programming abstractions, such as template programming, reflection, lambda calculus, and the like. I'd include here C++, Smalltalk, Java, Python, Objective Caml, Haskell. Some languages are supported by a wide range of platforms and compilers. Among these are C, C++, Java, Fortran, Perl, Python, and BASIC (although the different versions of BASIC are so different that code is rarely ported). Some languages are known for good performance, particularly for performance-sensitive environments. Among these are C, C++, Java, and Fortran. Some languages support an extensible, fast turnaround, high-performance development environment. I'm going to define this to mean that if the time from edit to running the edited code is more than a couple of seconds, it's too long. I personally include Java in this list and exclude C++, but YMMV. Some languages have a broad base of support in a particular industry: clearly C++, Java, Perl fit this mold. So the question revolves around choosing a language that can meet your needs for a particular project. The bigger the project, the larger the team, the more likely you are to need such things as performance and broad-based industry support. I'd really rather work in some other language than C++. I spent a while trying to use Smalltalk as a production language, and while I love it, I came to the conclusion that at least at that time, it wasn't an appropriate way to roll out a commercial product. C++ is by no means the perfect language. But it supports large-scale programming, high-end data abstractions, and high-end code abstractions (the STL is sheer brilliance, IMO, and while it's a bit more cumbersome than I'd like, I don't want a language that doesn't support that kind of programming). And I've been looking around to see what else might work. I've used Java for a lot of things recently, and there's a lot to like about it. But it doesn't support the higher-level abstractions. I definitely want to look into OCaml some more. But Eiffel seems a bit too much like a religion -- it's Pascal and Modula-3 taken to the next step, and I have always found that school of language design to be a bit too cumbersome. It's also single-source, isn't it? I wouldn't mind being proven wrong -- but paying $2000-3000 to find out seems a bit steep. Are there multiple implementations of Eiffel? Kent -- ----------------------------------------------------------------------- Kent Quirk | MindRover: "Astonishingly creative." Game Architect | Check it out! ken...@co... | http://www.mindrover.com/ _____________________________|_________________________________________ |
From: Thatcher U. <tu...@tu...> - 2001-12-19 23:27:04
|
On Dec 19, 2001 at 06:09 -0500, Kent Quirk wrote: > But Eiffel seems a bit too much like a religion -- it's Pascal and > Modula-3 taken to the next step, and I have always found that school of > language design to be a bit too cumbersome. It's also single-source, > isn't it? I wouldn't mind being proven wrong -- but paying $2000-3000 to > find out seems a bit steep. Are there multiple implementations of > Eiffel? I just downloaded and compiled SmallEiffel, "The GNU Eiffel Compiler": http://www.loria.fr/projets/SmallEiffel/ -- Thatcher Ulrich <tu...@tu...> http://tulrich.com |
From: Brian H. <bri...@py...> - 2001-12-19 23:31:46
|
> Thanks for the link. I haven't finished it yet, but what I've > read so far is interesting, intelligent and well-reasoned > (unlike most rants about C++ or other languages). I can also highly recommend Joyner's book "Objects Unencapsulated". > So the question revolves around choosing a language that can > meet your needs for a particular project. I sort of disagree -- you need a languager AND an environment. Objective-C is a fine language, but what really puts it over the top is Cocoa and Interface Builder (and the other libraries like Core Foundation and AppKit). Interface Builder is such a seamless integration into the development process (unlike AppWizard) that it pretty much has to be considered part of the language. The best language in the world is worthless (to me) if it doesn't have supporting tools and environments that really target the language's strengths. For example, the notion of a "generic environment" a la Emacs (or Visual Studio) is slowly going to become an arcane notion because separating the language from the build and analysis process will become less tenable. > C++ is by no means the perfect language. But it supports large-scale > programming, high-end data abstractions, and high-end code > abstractions (the STL is sheer brilliance, IMO, and while > it's a bit more cumbersome than I'd like, I don't want a > language that doesn't support that kind of programming). I'll just have to disagree. C++ is fine if you're an expert C++ programmer, and but there are so few TRUE expert C++ programmers out there that this is meaningless. The vast majority of C++ programmers are average, and as such don't understand all the odd rules and workarounds for the language's deficiencies. I'll defer to Joyner's treatise on the subject, but from my point of view C++ is attempting is an answer to a question only Bjarne asked =) > I've used Java for a lot of things recently, and there's a > lot to like about it. But it doesn't support the higher-level > abstractions. Java is clearly superior to C++ as a language, but it really was just an evolutionary step. It removed a lot of the baggage that C++ had due to its near religious belief in "no new keywords" and "maintain C compatibility". But, by the same token, it still wanted > But Eiffel seems a bit too much like a religion -- it's > Pascal and Modula-3 taken to the next step, and I have always > found that school of language design to be a bit too > cumbersome. Well, one reason I'm asking here about Eiffel is because I haven't made the commitment to learn it. On paper, it sounds fantastic. I can't see any glaring holes in it. > It's also single-source, isn't it? I wouldn't > mind being proven wrong -- but paying $2000-3000 to find out > seems a bit steep. Are there multiple implementations of Eiffel? There are at least four major implementations of Eiffel that I'm aware of: ISE's Eiffel Studio (the "official" one from Meyer's company); Object Tools' "Visual Eiffel"; Halstenbach's ISS; and the GNU SmallEiffel implementation which is free. I've yet to see a thorough comparison of the above, but they all offer some type of free/trial/lite version, and the home editions are in the $100-200 range which isn't much. And I don't mind paying $1500 for a development tool (hell, VStudio + MSDN Library is that much almost) if it makes me even 20% more productive. I'm probably going to read Meyer's book before making a decision on the plunge, but after having witnessed the radical productivity gains you can make by changing environments, tools and language, I'm a lot more open minded than I used to be. Brian |
From: Thatcher U. <tu...@tu...> - 2001-12-20 00:42:23
|
On Dec 19, 2001 at 03:32 -0800, Brian Hook wrote: > > I sort of disagree -- you need a languager AND an environment. > Objective-C is a fine language, but what really puts it over the top is > Cocoa and Interface Builder (and the other libraries like Core > Foundation and AppKit). Interface Builder is such a seamless > integration into the development process (unlike AppWizard) that it > pretty much has to be considered part of the language. > > The best language in the world is worthless (to me) if it doesn't have > supporting tools and environments that really target the language's > strengths. For example, the notion of a "generic environment" a la > Emacs (or Visual Studio) is slowly going to become an arcane notion > because separating the language from the build and analysis process will > become less tenable. Well, I think this is another way of expressing Kent's point about the right tool for the job. If you want to make a nice GUI in a hurry, then Cocoa sounds like a really good tool. If you want to glue a webcam to a webpage in a customized way (something I fiddled with the other day), thank god for Perl and various GNU/open-source stuff. If you want to make great-looking browser games, Flash w/ Actionscript looks like a great tool (here's a set of great examples: http://www.ferryhalim.com/orisinal/ ). If you want to write an OS kernel, then it's hard to argue with C. -- Thatcher Ulrich <tu...@tu...> http://tulrich.com |
From: Kent Q. <ken...@co...> - 2001-12-21 07:02:41
|
Back to the original question. I've been reading the critique Brian posted: This critique of C++/Java/Eiffel and others is dated from 1996, so it's a bit old at this point. Some of the things he criticizes have been changed in various ways in all of the languages. The paper could definitely use a fourth revision. (It appears he wrote a book in 1999 by starting from the paper, so you probably have to buy the book to get an update.) My general first take on Eiffel is that it seems awfully wordy and cumbersome. I understand and generally agree with the concept of writing more when coding to save trouble later; I use long variable names for just that reason. But the language has Bertrand Meyer's Pascalish bias all over it, and having been frustrated by coding in Pascal for a number of years, I developed a strong allergy to that style. It's a sort of leather and handcuffs kind of style. I also found this document: http://www.elj.com/eiffel/cpp/cpp-report-pd/ And in there, I found these items among a list of things that piss off C++ programmers -- and they're about the kiss of death as far as my use of Eiffel is concerned: ------- No overloading. Eiffel does not allow a feature to be overloaded on the basis of the types of its arguments. This sometimes leads to rather artificial manual overloading, as found in the standard IO routines (put_string, put_character, put_integer). However, overloading was not omitted by accident. Not only was it considered by Eiffel's designer to be of questionable value and not without costs, but it also would unduly complicate the inheritance mechanism, which relies on unique names to identify each feature of a class. Again, it comes down to favoring readability over writeability and eliminating ambiguity. No nested classes. A class cannot be declared within the scope of another class, nor within a routine. This is not an oversight, but a deliberate decision. Classes are meant to be reusable modules, and if one class is written inside another, then it has such a strong dependency with the enclosing class that it cannot possibly be reused independently. In C++, nested classes are merely a scope issue, rather than a semantic issue. Thus, if C++-style nested classes are desired, they can be achieved merely by prepending the enclosing class' name to that of the nested class, and access to the "enclosing" class' features can be granted through selective export. ---------- I understand the logic behind these decisions -- but to me, it feels like the arguments in favor of them are particularly weak, and evidence of design by someone who hasn't done a lot of large scale programming. Removing overloading removes ambiguity, yes, but it actually increases complexity by forcing the programmer to maintain a mental list of all the different ways to do the same task with different objects. I'd rather have the compiler deal with ambiguity and "undue complications" than force me to deal with it. I spent WAAAAAAY too much time duplicating code to handle different types in the bad old days of Pascal. I don't want to go there again. Regarding nested classes, there are uses for classes in implementation as well as design. Not every class needs to be public or reusable. In fact, one of the things that I love about Java and wish that C++ had was anonymous classes. They provide the only way to deal with the concept of functors in generic algorithms where the functor is defined at the same point as the algorithm is used. In C++ you can put it nearby. In Java you can stick an anonymous class right inline. It's a powerful, useful, and very general mechanism, similar to a lambda notation. Now if Eiffel supports a lambda notation (I haven't found it) and I've missed the fact, I'll take this one back. I'd really like to find a language that makes more sense in a production environment than C++ or Java. C: "You can do whatever you want." C++: "You can do whatever you want, if you can figure out how." Java: "You can do whatever you want that's safe." Perl: "You can do whatever you want any way you want, and preferably not the same way twice." Pascal: "You can't do anything." Eiffel: "You can do whatever we want." Python: "Whatever." Any counterarguments? Kent -- ----------------------------------------------------------------------- Kent Quirk | MindRover: "Astonishingly creative." Game Architect | Check it out! ken...@co... | http://www.mindrover.com/ _____________________________|_________________________________________ |
From: Thatcher U. <tu...@tu...> - 2001-12-21 15:06:12
|
On Dec 21, 2001 at 01:56 -0500, Kent Quirk wrote: > > fact, one of the things that I love about Java and wish that C++ had was > anonymous classes. They provide the only way to deal with the concept of > functors in generic algorithms where the functor is defined at the same > point as the algorithm is used. In C++ you can put it nearby. In Java > you can stick an anonymous class right inline. It's a powerful, useful, > and very general mechanism, similar to a lambda notation. Someone showed me this trick recently: ... struct Function { static void Call(int arg) { // some code. } } Instance; SomeFunctionTakingAFunctionPointer(Function::Call); ... For extra flexibility, define an interface class: struct Functor { virtual void Call(int arg); }; void SomeFunctionTakingAFunctor(Functor* f); ... struct HandleResults : public Functor { vector<int> results; void Call(int arg) { results.push_back(arg); } } Instance; // Call SomeFunction... and collect its results. SomeFunctionTakingAFunctor(&Instance); // Now Instance.results has the args passed to Instance.Call(). You can beef up HandleResults with a constructor and other members to parameterize stuff. I'm still sick of C++ though. The useful modern stuff I want to use is all a huge PITA. Templates stink, (lack of) introspection stinks, header files stink, manual memory management stinks, and pardon me, but IMHO the STL stinks as far as usability goes. -- Thatcher Ulrich <tu...@tu...> http://tulrich.com |
From: Jesse J. <jes...@mi...> - 2001-12-23 00:03:21
|
At 10:08 AM -0500 12/21/01, Thatcher Ulrich wrote: >On Dec 21, 2001 at 01:56 -0500, Kent Quirk wrote: >> >> fact, one of the things that I love about Java and wish that C++ had was >> anonymous classes. They provide the only way to deal with the concept of >> functors in generic algorithms where the functor is defined at the same >> point as the algorithm is used. In C++ you can put it nearby. In Java >> you can stick an anonymous class right inline. It's a powerful, useful, >> and very general mechanism, similar to a lambda notation. > >Someone showed me this trick recently: > > ... > struct Function { > static void Call(int arg) { > // some code. > } > } Instance; > SomeFunctionTakingAFunctionPointer(Function::Call); > ... People have been writing templatized callback classes in C++ for years. Boost has recently adopted one that is pretty darn cool (see the function and bind links at <http://www.boost.org/libs/libraries.htm#Function-objects>). It allows you to write code like this: Editor* editor = ...; boldButton->SetCallback(boost::bind(&Editor::SetStyle, editor, kBold)); italicButton->SetCallback(boost::bind(&Editor::SetStyle, editor, kItalic)); When the button is clicked it calls the callback with the argument provided. The prototypes look like this: void Button:: SetCallback(boost::function& f); void Editor::SetStyle(uint32 style); boost::bind takes a pointer to a free function, member function or functor object with N arguments and returns a boost::function argument that takes fewer arguments. You can even do things like leave the middle argument of a 3-argument function unbound. It's not as nice as a real closure system, but it's enormously useful and it's also efficient and typesafe. >I'm still sick of C++ though. The useful modern stuff I want to use >is all a huge PITA. Templates stink, (lack of) introspection stinks, >header files stink, manual memory management stinks, and pardon me, >but IMHO the STL stinks as far as usability goes. I don't think templates stink. The syntax is awkward and there's not enough support for template meta-programming, but having what amounts to a separate language at compile time is a very powerful feature that lets C++ do stuff that Java, C#, and Eiffel can't touch. The weak support for introspection doesn't bother me as much as the lack of any dynamism in the language. Pascal and Modula-2 were the first real languages I used so I like the concept of compile-time type checking, but a dynamic language really can make some important things simpler. Right now I think a language like Dylan where you can have both types and untyped variables is the way to go, but perhaps I'll change my mind after I get more experience with Ruby. I don't think STL stinks at all from a usability standpoint. Once you wrap your head around the concept of containers, iterators, and algorithms it's really easy to use and very powerful. The only problem are the icky error messages and the truly awful way that Plauger wrote his version of the library. But the biggest problem with C++ might be that it simply requires too much time and study to become proficient in the language and aware of all the pitfalls. Even the stuff published in magazines like C/C++ Users Journal is full of problems. -- Jesse |
From: Thatcher U. <tu...@tu...> - 2001-12-23 04:47:13
|
On Sat, 22 Dec 2001, Jesse Jones wrote: > At 10:08 AM -0500 12/21/01, Thatcher Ulrich wrote: > >On Dec 21, 2001 at 01:56 -0500, Kent Quirk wrote: > >> > >> fact, one of the things that I love about Java and wish that C++ > >> had was anonymous classes. They provide the only way to deal > >> with the concept of functors in generic algorithms where the > >> functor is defined at the same point as the algorithm is > >> used. In C++ you can put it nearby. In Java you can stick an > >> anonymous class right inline. It's a powerful, useful, and very > >> general mechanism, similar to a lambda notation. > > > >Someone showed me this trick recently: > > > > ... > > struct Function { > > static void Call(int arg) { > > // some code. > > } > > } Instance; > > SomeFunctionTakingAFunctionPointer(Function::Call); > > ... > > People have been writing templatized callback classes in C++ for > years. Boost has recently adopted one that is pretty darn cool (see > the function and bind links at > <http://www.boost.org/libs/libraries.htm#Function-objects>). > > It allows you to write code like this: > > Editor* editor = ...; > boldButton->SetCallback(boost::bind(&Editor::SetStyle, editor, > kBold)); > > italicButton->SetCallback(boost::bind(&Editor::SetStyle, > editor, kItalic)); That's nice, but I don't think that addresses Kent's complaint. Let's say you wanted to toggle the bold mode on boldButton.callback; how would you write: struct anon { static Editor* editor; anon(Editor* e) : editor(e) {} static void callback() { int s = editor->GetStyle(); s ^= kBold; editor->SetStyle(s); } } instance(editor); boldButton->SetCallback(instance::callback); I'm not claiming that's great (in fact it stinks :). > >and pardon me, > >but IMHO the STL stinks as far as usability goes. > > I don't think STL stinks at all from a usability standpoint. Once > you wrap your head around the concept of containers, iterators, and > algorithms it's really easy to use and very powerful. An example of how the STL is not "really easy to use": std::hash_map<string, int> my_hash; ... string my_key = something...; int my_value = something...; // I want to see if my_key is in my_hash, and if so, whether // its value matches my_value. std::hash_map<string, int>::iterator it = my_hash.find(my_key); if (it != my_hash.end() && (*it).second == my_value) { // Match. } else { // Mismatch. } I think I got that right. The iterator is just obfuscation. Whereas the way you'd do it in Perl or Lua, the seemingly obvious: if (my_hash[my_key] == my_value) { // Match. } else { // Mismatch. } compiles, and leaks memory! I've seen code like the above, written by professional C++ coders. I probably wrote code like that myself the first half-dozen times I used map or hash_map. A hash container should not define operator[] the way std::hash_map does; it's just programmer abuse. I find that kind of thing is endemic to the STL. The STL was designed (cleverly) as a demonstration of generic programming, rather than as a nice container library. Unfortunately, people use it as a container library, and IMO it stinks for that. -Thatcher |
From: Jesse J. <jes...@mi...> - 2001-12-23 23:56:00
|
At 11:47 PM -0500 12/22/01, Thatcher Ulrich wrote: >On Sat, 22 Dec 2001, Jesse Jones wrote: > > It allows you to write code like this: >> >> Editor* editor = ...; >> boldButton->SetCallback(boost::bind(&Editor::SetStyle, editor, >> kBold)); >> >> italicButton->SetCallback(boost::bind(&Editor::SetStyle, > > editor, kItalic)); > >That's nice, but I don't think that addresses Kent's complaint. Like I said, it's not a replacement for closures. >Let's >say you wanted to toggle the bold mode on boldButton.callback; how >would you write: > > struct anon { > static Editor* editor; > anon(Editor* e) : editor(e) {} > static void callback() { > int s = editor->GetStyle(); > s ^= kBold; > editor->SetStyle(s); > } > } instance(editor); > boldButton->SetCallback(instance::callback); > >I'm not claiming that's great (in fact it stinks :). You can't write it inline like Kent wants to (although you might be able to with the lambda library). In general I think the best approach is to put the logic in a member function and have the callback call that. >An example of how the STL is not "really easy to use": > > std::hash_map<string, int> my_hash; > > ... > string my_key = something...; > int my_value = something...; > > // I want to see if my_key is in my_hash, and if so, whether > // its value matches my_value. > std::hash_map<string, int>::iterator it = my_hash.find(my_key); > if (it != my_hash.end() && (*it).second == my_value) > { > // Match. > } else { > // Mismatch. > } Try: if (my_hash.count(my_key) > 0) // match else // mismatch >I think I got that right. The iterator is just obfuscation. Whereas >the way you'd do it in Perl or Lua, the seemingly obvious: > > if (my_hash[my_key] == my_value) { > // Match. > } else { > // Mismatch. > } > >compiles, and leaks memory! Compiles, but shouldn't leak memory. > I've seen code like the above, written by >professional C++ coders. I probably wrote code like that myself the >first half-dozen times I used map or hash_map. A hash container >should not define operator[] the way std::hash_map does; it's just >programmer abuse. It's not the way I would have written it, but calling it programmer abuse is way too strong. >I find that kind of thing is endemic to the STL. The STL was designed >(cleverly) as a demonstration of generic programming, rather than as a >nice container library. >Unfortunately, people use it as a container >library, and IMO it stinks for that. It's far better than any other container library I've seen... -- Jesse |
From: Thatcher U. <tu...@tu...> - 2001-12-26 03:34:20
|
On Sun, 23 Dec 2001, Jesse Jones wrote: > At 11:47 PM -0500 12/22/01, Thatcher Ulrich wrote: > > >An example of how the STL is not "really easy to use": > > > > std::hash_map<string, int> my_hash; > > > > ... > > string my_key = something...; > > int my_value = something...; > > > > // I want to see if my_key is in my_hash, and if so, whether > > // its value matches my_value. > > std::hash_map<string, int>::iterator it = my_hash.find(my_key); > > if (it != my_hash.end() && (*it).second == my_value) > > { > > // Match. > > } else { > > // Mismatch. > > } > > Try: > if (my_hash.count(my_key) > 0) > // match > else > // mismatch No, that's not the same test -- I want to check the value as well. I don't think it's possible to do w/ STL without either explicity using an iterator, or doing two lookups. > >I think I got that right. The iterator is just obfuscation. Whereas > >the way you'd do it in Perl or Lua, the seemingly obvious: > > > > if (my_hash[my_key] == my_value) { > > // Match. > > } else { > > // Mismatch. > > } > > > >compiles, and leaks memory! > > Compiles, but shouldn't leak memory. It's a leak -- if my_hash[my_key] is not defined, then it allocates memory and there's no way to safely clean it up. The above code is bugged, end of story. -Thatcher |
From: Jesse J. <jes...@mi...> - 2001-12-26 06:44:54
|
At 10:34 PM -0500 12/25/01, Thatcher Ulrich wrote: >On Sun, 23 Dec 2001, Jesse Jones wrote: > >> At 11:47 PM -0500 12/22/01, Thatcher Ulrich wrote: >> >> >An example of how the STL is not "really easy to use": >> > >> > std::hash_map<string, int> my_hash; >> > >> > ... >> > string my_key = something...; >> > int my_value = something...; >> > >> > // I want to see if my_key is in my_hash, and if so, whether >> > // its value matches my_value. >> > std::hash_map<string, int>::iterator it = my_hash.find(my_key); >> > if (it != my_hash.end() && (*it).second == my_value) >> > { >> > // Match. >> > } else { >> > // Mismatch. >> > } >> >> Try: >> if (my_hash.count(my_key) > 0) >> // match >> else >> // mismatch > >No, that's not the same test -- I want to check the value as well. I >don't think it's possible to do w/ STL without either explicity using >an iterator, or doing two lookups. Whoops, you're right of course. I wouldn't consider this a very good example of how STL is hard to use though. It's just different behavior than what you're used to. Sometimes it makes the code slightly more difficult to write, sometimes it makes it easier to write. However I do think this is one of the few places in STL that could have been designed better. As was mentioned earlier good implementations and good designs will try to catch user errors. Having operator[] add a new entry if one isn't already present might sometimes be handy, but if users make a mistake they won't know until sometime later. OTOH if operator[]'s precondition was that the key be present they'll find out right away that there's a problem. > > >I think I got that right. The iterator is just obfuscation. Whereas >> >the way you'd do it in Perl or Lua, the seemingly obvious: >> > >> > if (my_hash[my_key] == my_value) { >> > // Match. >> > } else { >> > // Mismatch. >> > } >> > >> >compiles, and leaks memory! >> >> Compiles, but shouldn't leak memory. > >It's a leak -- if my_hash[my_key] is not defined, then it allocates >memory and there's no way to safely clean it up. The above code is >bugged, end of story. It's not an STL bug though, it's a client bug. And when the hash map is destroyed the memory will be released. -- Jesse |
From: Brian H. <bri...@py...> - 2001-12-23 01:16:48
|
t 04:04 PM 12/22/2001 -0800, Jesse Jones wrote: >I don't think templates stink. The syntax is awkward and there's not >enough support for template meta-programming, but having what amounts to a >separate language at compile time is a very powerful feature that lets C++ >do stuff that Java, C#, and Eiffel can't touch. Oddly enough, after intensely studying programming language design for the past few days (originally sparked by my interest in Eiffel), I'm coming back around to Java as a half-way decent intermediate that's also pseudo-portable (modulo JVM issues). Obj-C still has quite a few features I prefer though. Anyway, back to the point -- how does C++'s templates provide genericity that is better than Eiffel's? After looking at Eiffel, it seems like it supports generic programming in a much more open and friendly fashion and without all the compile time weirdness that C++ jams down our throat. >dynamism in the language. Pascal and Modula-2 were the first real >languages I used so I like the concept of compile-time type checking, but >a dynamic language really can make some important things simpler. This is another aspect of Obj-C I like -- you can have typed or untyped variables. If you send a message to an untyped object ("id") the it works as untyped language. But if you send a message to a typed object then it can do a compile time check for you. That you can send any arbitrary message to any arbitrary object is immensely powerful, especially when it comes to prototyping or using distributed objects. No need to even know the interface, you can test an object to see if it can handle a message, and if it can, send it on through. This is what makes delegation so practical in Obj-C (whereas to achieve the same effect in C++ you have to use MI). >Right now I think a language like Dylan where you can have both types and >untyped variables is the way to go, but perhaps I'll change my mind after >I get more experience with Ruby. My biggest concern with Ruby right now is performance. Looking at the benchmarkst at the GCLS, it looks like Ruby is pretty far behind the other languages, including Lua (which I would guess is Ruby's primary competitor -- Python, Ruby and Lua seem to be accomplishing much the same thing). >But the biggest problem with C++ might be that it simply requires too much >time and study to become proficient in the language and aware of all the >pitfalls. I would put this another way: C++ was trying to be idiom-neutral and provide all the tools for any kind of programming style. Because of this, you can become very proficient in one tiny aspect of C++. I feel I know C++ very well for my purposes, but because I purposefully have avoided templates, exception handling, MI and many other things that I consider more problematic than worthwhile, I can't say I "know" C++. In fact, I'm not sure many people can say they know the whole language since the whole language is overkill for any specific framework design. I would even argue that any framework that uses EVERY element of C++ is probably a disaster. Which goes back to my complaints about STL =) Brian |
From: Patrick M D. <pa...@wa...> - 2001-12-23 21:50:47
|
On Sat, 22 Dec 2001, Brian Hook wrote: > I would put this another way: C++ was trying to be idiom-neutral and > provide all the tools for any kind of programming style. Because of this, > you can become very proficient in one tiny aspect of C++. I feel I know > C++ very well for my purposes, but because I purposefully have avoided > templates, exception handling, MI and many other things that I consider > more problematic than worthwhile, I can't say I "know" C++. In fact, I'm > not sure many people can say they know the whole language since the whole > language is overkill for any specific framework design. There are many kinds of programming styles that C++ fails to implement. It does a decent job with traditional structured programming and object-oriented programming. Generic programming is extremely awkward, as is functional programming. There is no support for logic programming. I feel I can honestly say that I know C++ well - but this knowledge comes from using other languages that are better than C++, and also developing in it for the past 10 years or so. The language is far from overkill - it fails to offer crucial functionality in almost every programming paradigm. Despite some major semantic limitations, there were terrible choices made regarding syntax. As an example, consider a case where some code needs to be made generic. It has a dependency on a particular structure that should now be parameterizable. To make this transition in C++ requires changing almost every line of code. Contrast this with OCaml which requires two lines of code for the implementation and one line of code in the namespace using the new parameterized structure. > I would even argue that any framework that uses EVERY element of C++ is > probably a disaster. Hmm... I'm not aware of any feature of C++ that has not seemed appropriate in some context -- they are there for a reason. The desire for such features does not inherently make the framework a disaster, although bending over backwards to conform to C++ syntax might make the programmer go crazy. Patrick |
From: Jesse J. <jes...@mi...> - 2001-12-23 23:35:08
|
At 5:16 PM -0800 12/22/01, Brian Hook wrote: >Anyway, back to the point -- how does C++'s templates provide >genericity that is better than Eiffel's? After looking at Eiffel, >it seems like it supports generic programming in a much more open >and friendly fashion and without all the compile time weirdness that >C++ jams down our throat. The difference is that templates are a Turing complete compile time language. This is obviously enormously powerful (and awkward because templates were never designed to do this). This lets you do all manner of things. Here are a few: 1) STL knows exactly which types it's dealing with. This means it can switch off the type and use optimized code as appropriate. For example, when a vector resizes it has to copy the old elements into a new block. A good implementation will use memcpy for primitive types (and user types that the user marked as POD) instead of an element by element copy. Another trick that STL implementations use is to use partial specialization so that all pointers share the same code. This cuts way down on bloat if you use a lot of containers of pointers in your code. AFAIK Eiffel's collections don't take advantage of type info like this. 2) Like C++ Eiffel is statically typed. But sometimes you have to store arbitrary data. This has traditionally been done with unions in C++, but templates can provide a cleaner solution. For example, boost::any is a non-template class that contains a templated class. This lets you do things like have heterogeneous containers: std::vector<boost::any> c; c.push_back(1); // int c.push_back(std::string("one")); etc if (int* ip = boost::any_cast<int*>(c[0])) // it's an int, muck around with it else (std::string* ip = boost::any_cast<std::string*>(c[0])) // it's a string I don't think Eiffel can do this because it lacks member templates. 3) There are a number of libraries that really push templates. Blitz++ for example allows you to write matrix code in a natural style (A = B*C + D) but uses expression templates to optimize the code and eliminate temporaries at compile time. This allows them to meet or beat Fortran's performance. Try that in Eiffel. :-) There are also a number of lambda libraries out there for C++. These allow you to write closures in C++. For example: int c[4] = [1, 2, 3, 4]; for_each(c, c+4, cout << arg1 << " "); will execute the expression 'cout << arg1 << "' for each element in the iterator range assigning the element value to "arg1". Some of them even support conditional expressions in the expression. Of course Blitz and the lambda libraries are much more complex and push templates a lot further than STL. It's still not clear that libraries like this will be useable by mortals in production code. >My biggest concern with Ruby right now is performance. Looking at >the benchmarkst at the GCLS, it looks like Ruby is pretty far behind >the other languages, including Lua (which I would guess is Ruby's >primary competitor -- Python, Ruby and Lua seem to be accomplishing >much the same thing). Ruby's pretty darn cool, but I'd have to agree with you. It might be good for protoyping though. BTW there's supposed to be a decent Cocoa wrapper for Ruby although I haven't checked it out yet. >>But the biggest problem with C++ might be that it simply requires >>too much time and study to become proficient in the language and >>aware of all the pitfalls. > >I would put this another way: C++ was trying to be idiom-neutral and >provide all the tools for any kind of programming style. Because of >this, you can become very proficient in one tiny aspect of C++. I >feel I know C++ very well for my purposes, but because I >purposefully have avoided templates, exception handling, MI and many >other things that I consider more problematic than worthwhile, I >can't say I "know" C++. In fact, I'm not sure many people can say >they know the whole language since the whole language is overkill >for any specific framework design. Very very few people know the entire language. I know an awful lot, but there are still plenty of arcane template rules that I haven't bothered to learn. >I would even argue that any framework that uses EVERY element of C++ >is probably a disaster. Which goes back to my complaints about STL >=) This is absolutely not true. Take your earlier list: "templates, exception handling, and MI". Every single one of these is *very* useful in frameworks and I've seen multiple frameworks that used them effectively. I can only think of two C++ features that I avoid: virtual base classes and exception specifiers. Virtual base classes are one of the worst part's of the language and exception specifiers have an unfortunate tendency to abort your program if the wrong exception sneaks through. -- Jesse |
From: Patrick M D. <pa...@wa...> - 2001-12-24 00:46:13
|
On Sun, 23 Dec 2001, Jesse Jones wrote: > The difference is that templates are a Turing complete compile time > language. This is obviously enormously powerful (and awkward because > templates were never designed to do this). This lets you do all > manner of things. Here are a few: Is it true that templates are Turing complete? I've seen a simulation of a turing machine in C++ using templates but I've only been able to make halting programs execute. My compiler (gcc 2.95-2) complains when it evaluates a computation state that has already visited. Maybe gcc doesn't conform to the standard or C++ templates are not Turing complete? Even with limitations on the size of the tape and number of states, it should still be possible to write a (turing) program that does not halt. Patrick |
From: Jesse J. <jes...@mi...> - 2001-12-24 01:21:32
|
At 7:46 PM -0500 12/23/01, Patrick M Doane wrote: >On Sun, 23 Dec 2001, Jesse Jones wrote: > >> The difference is that templates are a Turing complete compile time >> language. This is obviously enormously powerful (and awkward because >> templates were never designed to do this). This lets you do all >> manner of things. Here are a few: > >Is it true that templates are Turing complete? My recollection of Turing machines is a bit rusty, but you can use template meta-programming just like you would use a functional language and you can also write stuff like compile time if statements and loops. Sounds Turing complete to me... -- Jesse |
From: Patrick M D. <pa...@wa...> - 2001-12-24 01:41:24
|
This is getting off-topic, but this discussion has not been focused entirely on gaming, so... On Sun, 23 Dec 2001, Jesse Jones wrote: > My recollection of Turing machines is a bit rusty, but you can use > template meta-programming just like you would use a functional > language and you can also write stuff like compile time if statements > and loops. Sounds Turing complete to me... This kind of meta-programming is certainly possible to do as long as progress is being made (at least in my experience with templates). For example, one can compute factorial numbers using templates because this process terminates. This might be picking on a fine point, but a programming language is Turing-complete if it can simulate the behavior of a turing machine with finite storage capacity. One of the fundamental properties of such machines is that the halting problem is undecidable. In fact, Turing machines were originally formalized to prove this. So the idea of being Turing-complete while ensuring that computation terminates doesn't seem very compatible. Regardless, templates provide an expressive meta-language for static compilation. I'll admit that I don't fully understand the excitement as one can do this in a more powerful (and understandable) fashion by simply generating C++ code. Patrick |
From: Brian H. <bri...@py...> - 2001-12-24 02:48:08
|
At 08:41 PM 12/23/2001 -0500, Patrick M Doane wrote: >This is getting off-topic, but this discussion has not been focused >entirely on gaming, so... Well, this is the one gamedevlists mailing list where OT is kinda hard to determine. But we'll know it when we see it =) GD-Algorithms, Linux, Windows, Design and Console all have very well defined charters, but GD-General is pretty much "Any discussion that might pertain to games but which doesn't fall under any of the other list charters". In fact, this list doesn't need to be limited to programming only (the charter specifically uses the phrase "game development" instead of "game programming"). I think choice of programming language (and why) is very relevant to game development. So long as the discussions don't become flamefests, I think we're cool. I've been pleasantly surprised at the quality of discussion so far. People can actually state why they don't like something (C++, Windows, whatever) without getting shouted down. Brian, co-admin for gamedevlists-* |
From: Jesse J. <jes...@mi...> - 2001-12-24 03:48:09
|
At 8:41 PM -0500 12/23/01, Patrick M Doane wrote: >This is getting off-topic, but this discussion has not been focused >entirely on gaming, so... > >On Sun, 23 Dec 2001, Jesse Jones wrote: > >> My recollection of Turing machines is a bit rusty, but you can use >> template meta-programming just like you would use a functional >> language and you can also write stuff like compile time if statements >> and loops. Sounds Turing complete to me... > >This kind of meta-programming is certainly possible to do as long as >progress is being made (at least in my experience with templates). For >example, one can compute factorial numbers using templates because this >process terminates. > >This might be picking on a fine point, but a programming language is >Turing-complete if it can simulate the behavior of a turing machine with >finite storage capacity. One of the fundamental properties of such >machines is that the halting problem is undecidable. In fact, Turing >machines were originally formalized to prove this. So the idea of being >Turing-complete while ensuring that computation terminates doesn't seem >very compatible. I have a vague recollection of a more practical definition of a Turing complete language. It went something like: a language is Turing complete if it has sequential statements, some form of if statement, and I think one other thing that I can't recall. >Regardless, templates provide an expressive meta-language for static >compilation. I'll admit that I don't fully understand the excitement as >one can do this in a more powerful (and understandable) fashion by simply >generating C++ code. Well, there's a lot of value in being able to generate the code from within C++. It's more portable and convenient than using something like Perl and it's better integrated with the other parts of the language. -- Jesse |
From: Patrick M D. <pa...@wa...> - 2001-12-24 04:45:48
|
On Sun, 23 Dec 2001, Jesse Jones wrote: > I have a vague recollection of a more practical definition of a > Turing complete language. It went something like: a language is > Turing complete if it has sequential statements, some form of if > statement, and I think one other thing that I can't recall. Probably recursion - that should be sufficient to make it Turing-complete. This is a limiting definition though as those behaviors aren't strictly necessary. > >Regardless, templates provide an expressive meta-language for static > >compilation. I'll admit that I don't fully understand the excitement as > >one can do this in a more powerful (and understandable) fashion by simply > >generating C++ code. > > Well, there's a lot of value in being able to generate the code from > within C++. It's more portable and convenient than using something > like Perl and it's better integrated with the other parts of the > language. There other ways to generate code besides Perl--consider a parser generator like Yacc. One could probably implement this using template meta-programming techniques, but I'm sure that Yacc can give much better error messages and provides a syntax that is easier to use than templates. Integration with the language is nice, but it's a pity that it comes at such a high price to the syntax. This becomes especially noticeable when compared with similar systems in Lisp or Camlp4. At least C++ template syntax is not as bad as Unlambda. Patrick |
From: Jesse J. <jes...@mi...> - 2001-12-24 07:55:58
|
At 11:45 PM -0500 12/23/01, Patrick M Doane wrote: >On Sun, 23 Dec 2001, Jesse Jones wrote: > > > Well, there's a lot of value in being able to generate the code from >> within C++. It's more portable and convenient than using something >> like Perl and it's better integrated with the other parts of the >> language. > >There other ways to generate code besides Perl--consider a parser >generator like Yacc. Sure, but none of these are as tightly integrated with C++ as templates. This seems to me to limit their applicability. And, I'd note, that there are many more heavy duty template libraries than code generating systems like Yacc. >One could probably implement this using template >meta-programming techniques, but I'm sure that Yacc can give much better >error messages and provides a syntax that is easier to use than templates. Probably. If you haven't read it you might want to check out a book called "Generative Programming". It has several very interesting chapters including a good chapter on template meta-programming. >Integration with the language is nice, but it's a pity that it comes at >such a high price to the syntax. This becomes especially noticeable when >compared with similar systems in Lisp or Camlp4. Yep, I think part of the problem was that templates were designed for things like containers and algorithms. From what I've read the functional programming aspects came as a surprise. The committee is talking about a few things like typeof that would make meta-programming a bit easier, but AFAICT it's going to remain an activity practiced by only a few people. -- Jesse |
From: Jamie F. <ja...@qu...> - 2002-01-02 14:55:09
|
<Snip> I have a vague recollection of a more practical definition of a Turing complete language. It went something like: a language is Turing complete if it has sequential statements, some form of if statement, and I think one other thing that I can't recall. </Snip> One thing that may be useful, that I studied at uni: a URM (unlimited register machine) is equivalent to a Turing machine. It has 4 instructions: 1. Zero a register 2. Increment a register by 1 3. Set a register to the value of another register 4. If two registers are equal, jump to a program line This is provably equivalent to a UTM, and tends to be somewhat easier for us programmer types to understand and use. So if you can do these things, the language is complete. Jamie -----Original Message----- From: gam...@li... [mailto:gam...@li...]On Behalf Of Jesse Jones Sent: 24 December 2001 03:49 To: Patrick M Doane Cc: gam...@li... Subject: Re: [GD-General] Re: C++ turing complete At 8:41 PM -0500 12/23/01, Patrick M Doane wrote: >This is getting off-topic, but this discussion has not been focused >entirely on gaming, so... > >On Sun, 23 Dec 2001, Jesse Jones wrote: > >> My recollection of Turing machines is a bit rusty, but you can use >> template meta-programming just like you would use a functional >> language and you can also write stuff like compile time if statements >> and loops. Sounds Turing complete to me... > >This kind of meta-programming is certainly possible to do as long as >progress is being made (at least in my experience with templates). For >example, one can compute factorial numbers using templates because this >process terminates. > >This might be picking on a fine point, but a programming language is >Turing-complete if it can simulate the behavior of a turing machine with >finite storage capacity. One of the fundamental properties of such >machines is that the halting problem is undecidable. In fact, Turing >machines were originally formalized to prove this. So the idea of being >Turing-complete while ensuring that computation terminates doesn't seem >very compatible. I have a vague recollection of a more practical definition of a Turing complete language. It went something like: a language is Turing complete if it has sequential statements, some form of if statement, and I think one other thing that I can't recall. >Regardless, templates provide an expressive meta-language for static >compilation. I'll admit that I don't fully understand the excitement as >one can do this in a more powerful (and understandable) fashion by simply >generating C++ code. Well, there's a lot of value in being able to generate the code from within C++. It's more portable and convenient than using something like Perl and it's better integrated with the other parts of the language. -- Jesse _______________________________________________ Gamedevlists-general mailing list Gam...@li... https://lists.sourceforge.net/lists/listinfo/gamedevlists-general |
From: Brian H. <bri...@py...> - 2001-12-22 17:20:12
|
At 10:08 AM 12/21/2001 -0500, Thatcher Ulrich wrote: >but IMHO the STL stinks as far as usability goes. THANK you for saying that. I'm so tired of people going on and on about how great STL is (it's probably the #1 validation of C++ and templates I've seen), when in fact IT'S NOT THAT GOOD. It's convoluted, difficult to debug, has bizarre syntax, takes forever to compile, generates tons of warnings, requires third party implementations for stability. The only reason people dig on it is that they didn't have to write it. Someone should sift through the STL source code some time then come back and tell me it's GOOD. The primary advantage is that if you need a List or a Map you can just use STL without having to reroll it, but since I have that stuff lying around anyway, it doesn't bother me. Brian |