3 ms·
To me the anti-pattern is lots of redundant, trivial, verbose getters and setters. If I see a source file with tens or hundreds of lines of trivial method def
by haberman 4y ago
To me the anti-pattern is lots of redundant, trivial, verbose getters and setters. If I see a source file with tens or hundreds of lines of trivial method definitions, I think something has gone wrong.
Properties help avoid this anti-pattern by making it possible to transparently swap in a computed property for what used to be a plain field. This removes the incentive to proactively create trivial getters and setters "just in case."
- WalterBright 4y ago> a source file with tens or hundreds of lines of trivial method definitions Something has indeed gone wrong. The struct has succumbed to being a "kitchen sink".
- tialaramex 4y agoLet's take something like C++ std::vector / Rust's Vec / Zig ArrayList Although there's some serious meat in a few places (e.g the growth amortization and associated mechanisms) many of the methods defined for these types are trivial. In C++ they don't look trivial because of layers of pre-processor cruft, terrible lack of language hygiene, and the perverse insistence that today's code should compile correctly with a compiler that's as old as Shrek (the movie that is). But they are, ultimately, still trivial, even if writing a *= 2; takes sixteen lines of macros and a dozen structure tricks to ensure that compiler doesn't think we meant the global variable a, or the structural type a, or the function named a, or a dozen other things we couldn't possibly know about because this language is very, very stupid. Here's Vec's implementation of a commonly used method: pub fn is_empty(&self) -> bool { self.len() == 0 } Here's Zig's implementation of another commonly used method: pub fn pop(self: *Self) T { const val = self.items[self.items.len - 1]; self.items.len -= 1; return val; } I expect if I poke around in D I'll find similar, although the last time I did that I found a bug, and the experience wasn't fun so I think I'll pass.
- WalterBright 4y agoIn D it is often as simple as: T front() => array[index]; void popFront() => ++index; bool empty() => index == length;
- tialaramex 4y agoBut your claim was that if we see this: > Something has indeed gone wrong. The struct has succumbed to being a "kitchen sink".
- WalterBright 4y agoThat was in reference to having 10s or 100s of members.
- tialaramex 4y agoBut you wrote it in reply to a description of 10s or 100s of lines of trivial members. Maybe D doesn't have such a thing, as I said I don't plan to go look, but all the other languages I used as examples certainly do. Rust's Vec has almost 50 public associated functions, a few are non-trivial, but many are, and of course they take up hundreds of lines. https://github.com/microsoft/STL/blob/main/stl/inc/vector https://github.com/microsoft/STL/blob/main/stl/inc/vector is almost 4000 lines. As I said, C++ makes even a trivial function into a horrible mess like this: _CONSTEXPR20 void shrink_to_fit() { // reduce capacity to size, provide strong guarantee auto& _My_data = _Mypair._Myval2; const pointer _Oldlast = _My_data._Mylast; if (_Oldlast != _My_data._Myend) { // something to do const pointer _Oldfirst = _My_data._Myfirst; if (_Oldfirst == _Oldlast) { _Tidy(); } else { _Reallocate_exactly(static_cast<size_type>(_Oldlast - _Oldfirst)); } } }
- hota_mazi 4y ago> void popFront() => ++index; So in D, `popFront()` not only returns... nothing (void) but then returns... an index? No wonder nobody uses this language.
- hota_mazi 4y ago> Properties help avoid this anti-pattern by making it possible to transparently swap in a computed property for what used to be a plain field. Java's getters and setters *are* properties. Just with more syntactic sugar than languages that natively support properties, but the semantic is exactly the same.