Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

This comes down to "Make Invalid States Unrepresentable"

Notably Go's choice here is instead "Make Representable States Valid". So for example in Go it's not possible for a type not to have a default value - every type must have a value you get by default, you could name this unwanted default value FUCK_OFF or DO_NOT_USE if you like, but in a larger system (where Go is supposed to thrive) you can be certain you'll find FUCK_OFF and DO_NOT_USE values in the wild.

This is one of the few things the C++ type system almost gets right. You really can say for your C++ type no, it doesn't have a default. Unfortunately exception safety means we can easily end up in a place where too bad it's in some state anyway, but if we turn off exceptions or discount them we can live without nonsensical defaults.



> This is one of the few things the C++ type system almost gets right. You really can say for your C++ type no, it doesn't have a default.

Rust does even better here, I think, for fairly subtle reasons:

- Exceptions are replaced by Result, with explicitly-marked return points. They're far less magic. ("panic!" is still magic, but it's allowed to be a call to "abort", so you only use it when the world is burning.)

- "Move semantics" by default makes a lot of edge cases cleaner. If you move out of an object by default, it gets consumed, not set to a default value. Similarly, moving values into a newly-constructed object can't fail, because it's just memmove.

- Object construction is atomic from the programmer's perspective.

- Default initialization only works if you implement "Default". Which is actually just a normal trait with no magic.

- If you discover that you have a state machine, you can switch to discriminated unions ("enum") to make your states mutually exclusive and clearly represented.

This whole area is one of the better parts of Rust's design.


> Default initialization only works if you implement "Default".

And -- and I think this is important -- even then, you have to explicitly assign the default value[0]. You won't just somehow magically get a default value.

[0] E.g.:

    let foo: SomeType = Default::default();


Maybe something like CppFront can allow metaprogramming such that the default constructor is deleted by default on all types and becomes opt-in.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: