3 ms·
The footgun argument is not applied very consistently here. In other languages, it's an argument against constructors. You might do things that are bad like ha
by adrianmonk 7y ago
The footgun argument is not applied very consistently here.
In other languages, it's an argument against constructors. You might do things that are bad like have members with default values or call methods on an object that isn't ready. You could avoid doing those things by establishing conventions.
For example, the default values thing can be avoided in C++ by using member initialization lists. Or in Java, use final fields and definite assignment (https://docs.oracle.com/javase/specs/jls/se10/html/jls-16.html https://docs.oracle.com/javase/specs/jls/se10/html/jls-16.ht...) will protect you from default values.
But the requirement to maintain those conventions is an unreasonable burden when it comes to constructors.
However, when it comes to maintaining conventions to avoid other issues, Rust then gets a free pass:
> A perceived downside of this approach is that any code can create a struct, so there’s no the single place, like the constructor, to enforce invariants. In practice, this is easily solved by privacy: if struct’s fields are private it can only be created inside its declaring module. Within a single module, it’s not at all hard to maintain a convention like "all construction must go via the new method".
And it even goes on to say "One can even imagine a language extension" for Rust. Fair enough, but in languages that use constructors, one could imagine language extensions too. Default values for fields could be an explicit opt-in thing. Or calling methods on a not-fully-built-yet object could be banned or could require an explicit syntax.
- fluffything 7y agoFWIW I disagree with the author in that, within the module that declares a struct you must follow a convention in Rust. You don't. You have full access to the struct private implementation details and can do whatever you want. If you care about privacy, you'd just keep your modules small.
- matklad 7y agoSorry if the post sounds like I am trying to argue that one approach is inherently better than the other. It is not my goal. Rather, I want to show the amount of language level machinery (extensive static checks, or runtime nullability) that is required if the language has constructors.
- adrianmonk 7y agoOK, that's very reasonable. I think you make some good points that constructors can be problematic. Maybe they need to be reinvented or something. Just ditching them entirely as Rust does seems like an honest attempt at moving things forward, though I don't really see it as the long term solution because neither approach is all that great when you consider all the weaknesses that have been pointed out with both.
- couchand 7y agoI doubt there will ever be a language that doesn't have its own conventions and patterns. The practical question here is the risk when the convention is missed. In Rust, the object cannot be half-initialized when the pattern is missed. And not using public fields is rightly the default mode in all three...