5 ms·
Operator overloading sure seems to increase the prevalence of foot-guns, security issues, and other gotchas. str.ccClone(4301) # ConCatenate Clones of the sour
by mjevans 4y ago
Operator overloading sure seems to increase the prevalence of foot-guns, security issues, and other gotchas.
str.ccClone(4301) # ConCatenate Clones of the source string N times.
Would even an abbreviated, named, function not be more self documenting and better for human and machine reviews?
- slaymaker1907 4y agoI think how Rust does it is fine, but I agree operators are often a mess. Yesterday I was looking at a memory dump where there was a problem in a destructor (a double free was detected) and it was an absolute mess trying to figure out the exact execution location in source code since it was setting the value of a smart pointer which triggered a decrement of a reference counted value in turn triggering a free. It's junk like that which starts to convince me that Linus was right to avoid C++. Rust obviously also has destructors, but it doesn't have the nightmare that is inheritance+function overloading+implicit casting.
- cma 4y ago> and it was an absolute mess trying to figure out the exact execution location in source code since it was setting the value of a smart pointer which triggered a decrement of a reference counted value in turn triggering a free. Isn't all that context there in the stack trace?
- jlarocco 4y agoYes, probably. Depends on the compiler settings. Stuff can get optimized out and stripped. When writing the code in the first place, though, it's difficult to see problems like that because it's all hidden behind magic calls to copy constructors, move semantics, and destructor calls. Out of sight, out of mind.
- DSMan195276 4y agoI think it's separate from his point but some of those things could potentially be tail calls, meaning the functions actually leading to the free/delete might not be in the stacktrace even if they were called.
- im3w1l 4y agoSuccinct string operations is honestly like half of what I use python for and the great numeric support with bignum by default and powerful libraries with overloads like numpy and tensorflow is the other half.
- proto_lambda 4y agoOther than that being a terrible name (it's almost impossible to be sure what it does without consulting documentation), I personally do prefer fewer implicit/overloaded operations.
- mjevans 4y agoWhat name would you suggest? That was my 5 min of thought version. cc prefix for concatenate because that word is very long and it seemed likely that strings may have a large number of different concatenation focused functions that could all share the prefix. Clone as the type of concatenation operation to perform.
- proto_lambda 4y agoRust uses `repeat()`, which sounds much more descriptive to me. The types in the function signature make the "clone" part of the name redundant.
- mjevans 4y agoOffhand, is repeat(0) an empty string, repeat(1) the input string, etc? If so that's a great name for the function.
- pezezin 4y agoRepeat is an iterator, so you can apply it to any type you want, not just strings. You can chain it with other iterators, or collect it into some data structure. But yes, repeat(0) returns an empty iterator. https://doc.rust-lang.org/std/iter/fn.repeat.html https://doc.rust-lang.org/std/iter/fn.repeat.html
- tialaramex 4y agoThis is wrong, repeat(0) gives you a Repeat which will repeat 0 forever, that's its purpose: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=17c35b3b0e9a84b0195600ebf2080729 https://play.rust-lang.org/?version=stable&mode=debug&editio... This example makes a repeat(0) but asks for just the first 12 things in it, they are, of course, all twelve zeroes. Feel free to adjust it to ask for more if you think maybe there aren't any more, or they stop being zero.
- Gordonjcp 4y ago> Operator overloading sure seems to increase the prevalence of foot-guns, security issues, and other gotchas. How exactly? What would you expect an expression like ('1' * 4301) to give you, and why would you think it would be different from ('caterpillar' * 4301)?
- samatman 4y agoIn Lua, the first is 4301 and the second is a runtime error. ('1' .. 4301) is 14301, the equivalent of the weird thing Python is fixing would be spelled `tonumber(('1'):rep(4301))` which is obviously wrong. To my taste operator overloading is fine, but concatenation isn't addition, so they shouldn't be overloaded because... [gestures vaguely at a half dozen language]
- naniwaduni 4y agoConcatenation is obviously a multiplication! (By extension, string repeat is exponentiation!)
- qayxc 4y agoWell, let's assume that the "expected" behaviour holds, shall we? Let's open up a python REPL and try >>> 'caterpillar' * 2 'caterpillarcaterpillar' OK, now for something different: >>> [1, 2, 3] * 2 [1, 2, 3, 1, 2, 3] Marvellous! How about this then: >>> True * 2 2 Wait, what? Hm. >>> False * 2 0 Whoops! Implicit type conversion takes place... Even worse: >>> 'abc' + 'efg' 'acbefg' >>> 'efg' + 'abc' 'efgabc' Now I'm stumped. Isn't addition supposed to be commutative? So yeah, without contracts in place, operator overloading is BAD. You can never know what the operator does, or what its properties are by just looking at how it's used. There's simply no enforced rules and so no-one's stopping you from doing >>> class Complex: def __init__(self, real, imag): self.real = real self.imag = imag def __add__(self, other): return Complex(self.real - other.real, self.imag - other.imag) def __repr__(self): return f'Complex({self.real}+{self.imag})' >>> x = Complex(1, 2) >>> y = Complex(1, 2) >>> x + y Complex(0+0j) Now this intentionally being malicious of course, but plenty of libraries overload operators in non-intuitive ways so that the operator's properties and behaviour isn't obvious. This is especially true if commutative operators are implemented as being non-commutative (e.g. abusing '+' for concatenation instead of using another symbol like '&' for example) or if the behaviour changes depending on the order of operands.
- UncleEntity 4y agoIt is really useful sugar for: for _ in range(4301): llama.append(‘1’) (there’s probably an easier way to do that but you get the point) where python can see both sides of the operation and optimize it on the C side of things. The issue really has nothing to do with that though, it is converting a string to an int which is the whole point of the security update.