4 ms·
Well it seems you don't understand exceptions. They eliminate erroneous states entirely, since the objects just don't get created if an error occurs. The alter
by mgaunard 4y ago
Well it seems you don't understand exceptions. They eliminate erroneous states entirely, since the objects just don't get created if an error occurs.
The alternative that the parent said was making all of your state be a union with some kind of error, and making sure all accesses handle the fact the variable might be in a erroneous state. That is a huge explosion of possible states in your program, and essentially making every invariant weak everywhere.
Then FFI, I suppose you mean interfacing with C. Problems that arise when interfacing with other programming languages are orthogonal to a language's ability to be used for system programming. Obviously you wouldn't let an exception propagate through some C code, that's forbidden.
- zozbot234 4y agoYou don't need exceptions for constructors. You can just use static factory functions with an error return as Rust does, and dispense with constructors altogether.
- mgaunard 4y agoEnjoy your combinatorial explosion of states. It's not equivalent at all.
- Yoric 4y agoCould you elaborate? Rust manages pretty well without constructors and I'm nearly certain that it doesn't have any kind of combinatorial explosion of states. Same for ML-family languages.
- jcelerier 4y agoCan you enforce at compile-time that only such a static factory can ever be used for creating the object in Rust? This is the whole point of constructors, they cannot not be used. Otherwise you're just one commit away of creating an object that will not respect the invariants - will you even remember to call this specific factory function in 6 months?
- jstimpfle 4y agoTo me, constructors are mostly a convenience thing for the simple cases where I declare a quick container on the stack or similar, and don't want to waste keypresses to have it constructed. And to me it's a question of, what does the language want to be -- maybe this kind of code is better served by languages like C#. There are various practices that handle the problem of having to call a specific function to get an object in a specific state, without requiring language support. You can make the function that should be used stand out in an obvious way. You can hide the definition of a structure, which very If it is the whole point of constructors to guarantee that the object is in the right state, it could be the best argument why Rust does not have constructors. Programming is chock-full of "this must be called only by that or in this or that context..." and practically speaking, only a part of them can be handled by language objects and construct/deconstruct semantics. Plus, C++ gives enough escape hatches to get not-constructed objects or to un-construct objects without them going out of scope. These guarantees that C++ provides (but not really), they require a ton of baggage like ridiculous initializer lists or 17 different kinds of constructors (to the point where it's sometimes almost impossible to tell which will be called), or requiring an out-of-band mechanism (exceptions) to signal construction failure.... that's not worth it in my book.
- zozbot234 4y agoYou get this by default for any object with non-public fields.
- ginsider_oaks 4y agoSure, just make the fields of the struct private and you can make a public constructor: https://doc.rust-lang.org/rust-by-example/mod/struct_visibility.html https://doc.rust-lang.org/rust-by-example/mod/struct_visibil...
- masklinn 4y ago> Well it seems you don't understand exceptions. They eliminate erroneous states entirely, since the objects just don't get created if an error occurs. Error sum types do the exact same thing. > The alternative that the parent said was making all of your state be a union with some kind of error, and making sure all accesses handle the fact the variable might be in a erroneous state. Which is a non-issue as it is lifted to the type system. The type system will not let you forget about that. > That is a huge explosion of possible states in your program, and essentially making every invariant weak everywhere. You get an error state added to a given value, which you also get via exceptions, except implicitly and without notification of the additional state. Type-safe error values also provide simpler error handling and recovery in many case, because they don't require split-path handling. > Then FFI, I suppose you mean interfacing with C. Problems that arise when interfacing with other programming languages are orthogonal to a language's ability to be used for system programming. It very much isn't, part of the system programming workload is to provide reusable components. > Obviously you wouldn't let an exception propagate through some C code, that's forbidden. And rarely if every checkable statically, hence unsafe.
- mgaunard 4y agoThe problem is not "forgetting about it", it's that it increases the possible values of your working set. If you have 3 variables, each of which can be in 10 states, that's 10^3 states your program can be in. If instead you have 11 states because all your variables are actually unions with an error, that's 11^3 states (assuming all error states are equivalent to a single state). Now in practice it's even worse since what you care about isn't the possible states of your values, but rather how many different paths you have in your control flow to handle them. Then you're comparing 1 (none of my values are in an erroneous state) with 2^3=8 (any of my values can be in an erroneous state or not). What exceptions do is enforcing that your working set does not have to encode any erroneous states, preventing the combinatorial explosion of states, which of course is a net win, there isn't really any valid argument that can be made against it. Where people are debating is that sometimes you do want errors to be part of your working set, in which case you shouldn't use exceptions. But choice is difficult for some, especially those seeking absolute doctrines. > It very much isn't, part of the system programming workload is to provide reusable components. That's already somewhat dubious, since a lot of system programming tasks are really purpose-built for a usecase or for specific hardware, and regardless, there is nothing about that which has anything to do with interfacing with C. I do a lot of system programming and I write it all in C++, which has a lot of advantages over C beyond exceptions.
- mike_hock 4y ago> They eliminate erroneous states entirely, since the objects just don't get created if an error occurs. EPIPE Erroneous states can arise outside of your control at any time.