4 ms·
> C++'s C heritage Well, at this point it's more like C++'s C++ heritage. > const correctness It certainly exists in plenty of other languages, but in a non-
by epsylon 13y ago
> C++'s C heritage
Well, at this point it's more like C++'s C++ heritage.
> const correctness
It certainly exists in plenty of other languages, but in a non-broken way. C++'s const correctness model is mostly broken, by the way [1]. D's model is a bit more sane [2]. Languages like Haskell or Clojure (AFAIK) make immutability a default. This kind of functional style is a good thing for C++ developers overall, as emphasized by John Carmack [3].
[1] Once again, the C++ FQA has plenty of wisdom to share: http://yosefk.com/c++fqa/const.html http://yosefk.com/c++fqa/const.html
[2] http://en.wikipedia.org/wiki/Const-correctness#const_and_immutable_in_D http://en.wikipedia.org/wiki/Const-correctness#const_and_imm...
[3] http://www.altdevblogaday.com/2012/04/26/functional-programming-in-c/ http://www.altdevblogaday.com/2012/04/26/functional-programm...
> RAII didn't catch in other languages
That's because most other languages are garbage collected. (Not that RAII is a bad thing, it's just not needed.)
- fhd2 13y ago> It certainly exists in plenty of other languages, but in a non-broken way. C++'s const correctness model is mostly broken, by the way [1]. D's model is a bit more sane [2]. Languages like Haskell or Clojure (AFAIK) make immutability a default. What in particular is broken about const correctness in C++? That things are not const by default? I agree, they should be, but I wouldn't really call that broken. I put const wherever I can, just like Carmack. So I sort of pretend it's the default :) I don't think it makes sense to compare const correctness in C++ to immutability in Clojure. In Clojure, you don't have objects that encapsulate internal state. const in C++ allows you to say which methods do change internal state and which don't. If you pass a const reference, the receiver can only call const methods. I just learned from you that D has this, wasn't aware of any other OOP language that has it. Not even Scala :( > That's because most other languages are garbage collected. (Not that RAII is a bad thing, it's just not needed.) RAII is about more than just memory, it's about any kind of resource. That includes stuff like file handles, Java's try {} finally {} is IMO a weird workaround. In C++, stream's can just close themselves when they go out of scope.
- epsylon 13y ago> What in particular is broken about const correctness in C++? The lack of transitivity for one. Const pointers shouldn't be able to modify the pointed objects (that's the default in the D language). The fact that working with non-const-correct libraries is a nightmare (prepare to const_cast a lot!). There are plenty of other things that make this a real PITA to work with on sizable projects with legacy or outside code. > RAII is about more than just memory, it's about any kind of resource. That's true, yeah, though most of the time it's about memory (with smart pointers). But you're absolutely right on that point. As far as I know, Common Lisp users have some kind of RAII with macros, but I'm not familiar enough to compare it to C++. Of course, D also has support for this idiom.
- fhd2 13y ago> The lack of transitivity for one. Const pointers shouldn't be able to modify the pointed objects Are they? I either misunderstand or disagree. The syntax gets a bit silly with pointers, because you can have const pointers and pointers to const (and const pointers to const of course): const Foo* foo; // Cannot change *foo, but can change the pointer (e.g. foo = 0) Foo* const foo; // Can change *foo, but cannot change the pointer const Foo* const foo; // Cannot change *foo or the pointer > The fact that working with non-const-correct libraries is a nightmare (prepare to const_cast a lot!). Agreed! > As far as I know, Common Lisp users have some kind of RAII with macros, but I'm not familiar enough to compare it to C++. In my experience, the kind of problem RAII is useful for is far less common in Lisps (can only really speak for Clojure). One tends to not encapsulate resource management in any way, so handling it explicitly in the caller is fine. And you can use macros to do something when the scope is excited. So in Clojure e.g., you can use with-open to do something with a file: (with-open [writer (io/writer "foo.txt")] (write writer "Hello"))) with-open ensures that the reader is properly closed when the scope is exited or when an exception occurs. In C++ (or any OOP language I guess), you'd want something like this: File foo("foo.txt"); foo.write("Hello"); So I suppose it depends on the philosophy. For OOP languages, RAII makes a lot of sense IMO.