|
That Turkey Story posted:So what? Hypothetically, if && and || didn't short-circuit in C++ (as is the case for logical or and logical and in plenty of other languages), then would you consider these to be acceptable overloads? I don't see how that matters at all in theory nor in practice. When you see || and && in places that don't deal with bool you don't freak out about short-circuiting. It simply doesn't apply to those types. That said, those that think the entire point of && and || is short-circuiting are in way too narrow of a mindset.
|
# ? May 7, 2013 20:51 |
|
|
# ? May 30, 2024 06:45 |
|
That Turkey Story posted:Hypothetically, if && and || didn't short-circuit in C++ (as is the case for logical or and logical and in plenty of other languages), then would you consider these to be acceptable overloads? Yes. That Turkey Story posted:I don't see how that matters at all in theory nor in practice. It matters in practice because people will use them expecting them to short-circuit, and there are plenty of fine alternatives to overloading && and || that have less probability of fuckups. That Turkey Story posted:When you see || and && in places that don't deal with bool you don't freak out about short-circuiting. You don't necessarily know what the types are by looking at the code, and somebody coming in trying to fix your code, or read your code, might expect the operator to short-circuit. This increases the probability of bugs.
|
# ? May 7, 2013 20:56 |
|
That Turkey Story posted:It's exactly as acceptable as it is for overloading of functions in general. Perhaps, though, you think that general function overloading isn't a good idea because it "makes something do something else." All an operator is is a function with a fancy name/syntax. It is from your black womb that all coding horrors clawed their way into the light, screaming.
|
# ? May 7, 2013 20:58 |
|
yaoi prophet posted:You shouldn't operate + for strings because strings don't form a group under concatenation I've overloaded - for strings before now. If ABCD + EF = ABCDEF, then obviously ABCDEF - EF = ABCD, right?
|
# ? May 7, 2013 21:05 |
|
qntm posted:I've overloaded - for strings before now. If ABCD + EF = ABCDEF, then obviously ABCDEF - EF = ABCD, right? In the case of string A minus string B, do you throw an exception if B is not a suffix to A or only if B does not appear in A at all?
|
# ? May 7, 2013 21:11 |
|
Otto Skorzeny posted:In the case of string A minus string B, do you throw an exception if B is not a suffix to A or only if B does not appear in A at all? The former.
|
# ? May 7, 2013 21:13 |
|
shrughes posted:It matters in practice because people will use them expecting them to short-circuit... shrughes posted:You don't necessarily know what the types are by looking at the code, and somebody coming in trying to fix your code, or read your code, might expect the operator to short-circuit. This increases the probability of bugs. E: To stress this -- if you don't know what the operands to the && and || are doing in the code that you are editing, how on earth would you be able to make proper changes to begin with? Short-circuiting or no short-circuiting you're completely missing what the problem is here... That Turkey Story fucked around with this message at 21:33 on May 7, 2013 |
# ? May 7, 2013 21:25 |
|
That Turkey Story posted:Again, you could say the exact same thing about overloading of any function, not just operators. Functions and other operators don't short circuit, so I don't see how you could say the same thing of them. That Turkey Story posted:No, it doesn't. "Short-ciruiting" doesn't even mean anything in most of these domains. "Don't do the second part when the first part is true" doesn't apply when the left-hand operand isn't a "true" or "false" value. You seem to be under the misapprehension that I somehow didn't understand this. That Turkey Story posted:What would you even expect short-circuiting to mean there? The fact that you haven't produced a single example of where it is confusing is indicative of how weak your argument is. You're bad at reasoning if you need an example. I'm pretty sure you don't believe the probability of bugs by overloading && is less than alternatives. Therefore it must be greater. If you want to know what people expect short-circuiting to mean, well, it depends on the situation. People might just look at the code scanning for something other than its meaning, maybe looking for possible kinds of side effects they hope it avoids, and find themselves facing difficulty or confusion when coming across some && with the bad side effect on the right hand side. Suddenly they need to know the types of the expressions, the existence of some overload somewhere, in code they aren't familiar with. There's a reason why security researchers have a harder time auditing C++ code than C code, and that reason is people like you. That Turkey Story posted:The only "example" so far is of somebody making an arbitrary "foo" type without any semantics nor a reason why he would expect short-circuiting or why he didn't use "bool" instead of his TrueBool type. Never in my life have I seen someone confused about short-circuiting behavior of an overloaded && or ||. You could use it for constructing queries that get evaluated on a different machine than the one you're on. The product I work on does that. I've seen people confusedly expect short-circuiting behavior even when we overloaded the bitwise operators instead of the logical operators.
|
# ? May 7, 2013 21:39 |
|
I might argue that if a type has a well-known cast-to-bool operator with very "expected" semantics for that type, then it should not also have overloads for the short-circuiting operators, because when reading code that used them I would be expecting it to act like a bool and might be surprised that my control flow isn't what I expect. That said, I don't see anything wrong with using operator overloads for && and || if your type doesn't pretend to be a bool at all. The confusion goes away completely. Also, now I want C++14 to give me something like "int &&&i" as a parameter which produces a thunk for lazy evaluation.
|
# ? May 7, 2013 21:40 |
|
ShoulderDaemon posted:That said, I don't see anything wrong with using operator overloads for && and || if your type doesn't pretend to be a bool at all. The confusion goes away completely. If your type doesn't have an intuitive interpretation as a true or false value than it's a lot harder to justify the overloads in the first place.
|
# ? May 7, 2013 21:59 |
|
shrughes posted:You could use it for constructing queries that get evaluated on a different machine than the one you're on. The product I work on does that. I've seen people confusedly expect short-circuiting behavior even when we overloaded the bitwise operators instead of the logical operators. They'd be confused by the behavior of the built in types too; see the entire C programmers don't know what malloc/free do discussion from before.
|
# ? May 7, 2013 22:03 |
|
That Turkey Story posted:The fact that you haven't produced a single example of where it is confusing is indicative of how weak your argument is. The only "example" so far is of somebody making an arbitrary "foo" type without any specified semantics nor a reason why he would expect short-circuiting or why he didn't use "bool" instead of his TrueBool type. The real problem here is the way you think about things. There's something broken with your thought processes if you go around thinking "there are no ways this could go wrong, I can't think of any" instead of "the benefits of overloading these operators outweigh the probable damage". Any time a software developer says "This won't lead to bugs", they are talking complete nonsense. Two approaches to doing something will alway have a not convincingly negligibly different expected amount of bugginess, unless in both cases it's very very close to zero.
|
# ? May 7, 2013 22:08 |
|
shrughes posted:Functions and other operators don't short circuit, so I don't see how you could say the same thing of them. shrughes posted:You're bad at reasoning if you need an example. I'm pretty sure you don't believe the probability of bugs by overloading && is less than alternatives. Therefore it must be greater. shrughes posted:You could use it for constructing queries that get evaluated on a different machine than the one you're on. The product I work on does that. I've seen people confusedly expect short-circuiting behavior even when we overloaded the bitwise operators instead of the logical operators. ShoulderDaemon posted:I might argue that if a type has a well-known cast-to-bool operator with very "expected" semantics for that type, then it should not also have overloads for the short-circuiting operators, because when reading code that used them I would be expecting it to act like a bool and might be surprised that my control flow isn't what I expect. Exactly, exactly, exactly. And examples of where, in practice, && and || are overloaded perfectly fine are lambda EDSLs like Boost.Phoenix. I think I'm aware of your stance on expression templates, though, so I assume I'm talking to a wall at this point.
|
# ? May 7, 2013 22:08 |
|
That Turkey Story posted:Code example, please. I don't immediately see how using bool operands wouldn't fix the "problem." All I see is a poorly designed API, not a flawed language feature. As I said, expressions evaluated on a different machine. You can't use bool operands because they would have to be evaluated on your machine.
|
# ? May 7, 2013 22:12 |
|
shrughes posted:The real problem here is the way you think about things. There's something broken with your thought processes if you go around thinking "there are no ways this could go wrong, I can't think of any" instead of "the benefits of overloading these operators outweigh the probable damage".
|
# ? May 7, 2013 22:13 |
|
shrughes posted:As I said, expressions evaluated on a different machine. You can't use bool operands because they would have to be evaluated on your machine. If that's the case, then why aren't your operands lazy???
|
# ? May 7, 2013 22:13 |
|
Overloaded functions and operators should share similar semantics-- principle of least surprise. operator&& forces you to have different semantics than the normal operator&&, which can cause confusion. Confusion leads to inaccurate mental models, which leads to more bugs being produced.
|
# ? May 7, 2013 22:24 |
|
That Turkey Story posted:And examples of where, in practice, && and || are overloaded perfectly fine are lambda EDSLs like Boost.Phoenix. I think I'm aware of your stance on expression templates, though, so I assume I'm talking to a wall at this point.
|
# ? May 7, 2013 22:37 |
|
Victor posted:Perhaps this is ok explicitly because the Boost folks reconstruct the short-circuiting behavior? Search for 'short-circuit' in operators.hpp. The expression that constructs the argument to && isn't short-circuited, though. It might be okay because nobody in their right mind would use that library anyway.
|
# ? May 7, 2013 22:44 |
|
Van Kraken posted:It's settled, we're using * for string concatenation now. If strings don't form an abelian group they sure as gently caress don't form a ring. Don't you know anything about programming?
|
# ? May 7, 2013 22:49 |
|
Clearly we should use the whitespace operator for string concatenation.
|
# ? May 7, 2013 22:50 |
|
shrughes posted:Clearly we should use the whitespace operator for string concatenation. http://codepad.org/gte6Qoby
|
# ? May 7, 2013 22:58 |
|
Victor posted:Perhaps this is ok explicitly because the Boost folks reconstruct the short-circuiting behavior? Search for 'short-circuit' in operators.hpp. shrughes posted:The expression that constructs the argument to && isn't short-circuited, though. It might be okay because nobody in their right mind would use that library anyway.
|
# ? May 7, 2013 23:07 |
|
That Turkey Story posted:Yes, let's just entirely disregard a useful library because it uses a technique you ideologically oppose. That's not the reason to disregard it. (Why did you believe it was? Weird thoughts that have nothing to do with reality just keep popping out of your mouth [1]!) [1] hands
|
# ? May 7, 2013 23:08 |
|
AlsoD posted:If strings don't form an abelian group they sure as gently caress don't form a ring. Don't you know anything about programming? Well clearly the best way is to fix this is to redefine the string class to commute.
|
# ? May 7, 2013 23:08 |
|
shrughes posted:That's not the reason to disregard it. So what do you have against functional programming? shrughes posted:That's not the reason to disregard it. So do you hate functional programming or EDSLs in general or what?
|
# ? May 7, 2013 23:12 |
|
shrughes posted:That's not the reason to disregard it. Because I seem to remember you making pretty broad, negative claims about expression templates in the past. If you don't have a problem with expression templates, then whatever. Edit: Functional programming libraries are also one of the most fundamental libraries you can develop with expression templates. If you're not against expression templates, just what is it that makes you say that no one in their right mind would use Boost.Phoenix? That Turkey Story fucked around with this message at 23:38 on May 7, 2013 |
# ? May 7, 2013 23:15 |
|
facepalmolive posted:Well clearly the best way is to fix this is to redefine the string class to commute. Nah, group elements need an inverse too which strings can't* have. Depending on how picky you are about semantics, strings could be considered to form a monoid however and wouldn't you know it, Haskell has those!** code:
*: shouldn't **: yes I know this isn't the exact definition but it's close enough gonadic io fucked around with this message at 23:34 on May 7, 2013 |
# ? May 7, 2013 23:17 |
|
hobbesmaster posted:So what do you have against functional programming? Oh, come on. e: To be a little more constructive: You really can't think of a reason that someone might recommend against using Boost.Phoenix other than a problem with functional programming? I'm sure even TTS could come up with something someone might say, even if he strenuously disagrees with it. raminasi fucked around with this message at 23:39 on May 7, 2013 |
# ? May 7, 2013 23:26 |
|
seiken posted:I stumbled across this thread on another forum that's from a year and a half ago so it's kind of old, but it's too good not to share. Holy loving poo poo this is . Poor person guy. If you missed it from few pages back its worth a read.
|
# ? May 7, 2013 23:40 |
|
That Turkey Story posted:It's only doing short-circuiting of the deferred operation, as you would except. The actual operands aren't short-circuited, nor would the term "short-circuiting" on the top-level really make any sense in this context, as is often the case when overloading these operators.
|
# ? May 7, 2013 23:41 |
|
This has been a great flamewar interspersed with math jokes, guys. PS - shrughes, I like to think of it as the double double quote operator, not the whitespace operator.
|
# ? May 7, 2013 23:41 |
|
I don't program C++ (but have dabbled) and a big reason for that is that there are so many ways a codebase can alter the semantics of something innocent-looking. The excuse that you should be able to alter the semantics of basic operators because all you need to do is be cautious and aware of the consequences is an awful excuse and an ignorant one. There's more to programming than abstraction or analogies to similar structures. There's also maintainability. it is important to avoid cognitive overload, and not have to learn a different sort-of-DSL for each codebase you examine, or worse, learn one that is very nearly identical to another, but different. When ObjectWithOverload && foo is different from booleanExpression && foo in both short-circuiting and laziness semantics, you have the same token signifying two very different operations with very different semantics. Given how common logical operators are, in any codebase of reasonable size or developer participation, this will cause confusion if used as such. Period. Confusion leads to an incomplete mental model leads to bugs. Period. If it's going to act like a method, just write and call a method instead, for everyone else's sake. When you overload an operator to make it mean something different, you are changing it for yourself but you're also loving with the expectations of newbie programmer looking at your code. It is a monumentally bad practice to surprise developers like that and if you disagree you are a programmer I would hate to be on a team with, no matter how otherwise talented you may be.
|
# ? May 7, 2013 23:41 |
|
GrumpyDoctor posted:e: To be a little more constructive: You really can't think of a reason that someone might recommend against using Boost.Phoenix other than a problem with functional programming? I'm sure even TTS could come up with something someone might say, even if he strenuously disagrees with it. Compile times and error messages are the big ones, although prior to lamdas being in the language, you didn't really have any better alternative, and even now the library approach can be more capable than the language approach in some respects (sadly). The next standard will fix at least a little of that, though. The point is, regardless of these issues, sane people really do use these libraries and the result is very concise and easy to read. It's a trade-off like anything else. You are not insane for using it. Victor posted:Wait a second, so if I take a bunch of code and switch it to the deferred execution model, it silently switches from short-circuiting to not short-circuiting? How is this anything but bad? How many people are going to realize, "oh, since this is a lazy evaluation library, && and || are no longer short-circuited"? Edit: An example: code:
That Turkey Story fucked around with this message at 23:55 on May 7, 2013 |
# ? May 7, 2013 23:46 |
|
Doctor w-rw-rw- posted:and not have to learn a different sort-of-DSL for each codebase you examine I strongly agree with this sentiment. Operator overloading is a way of making little half-DSLs. E.g. the operator= guy did it all over the place: http://en.sfml-dev.org/forums/index.php?topic=5792.0 C++ is already peppered with the use of operator overloading to create little half-DSLs but just because it's in the STL and boost doesn't mean it's a good idea to do it in your code too.
|
# ? May 7, 2013 23:49 |
|
Doctor w-rw-rw- posted:When ObjectWithOverload && foo is different from booleanExpression && foo in both short-circuiting and laziness semantics, you have the same token signifying two very different operations with very different semantics. Given how common logical operators are, in any codebase of reasonable size or developer participation, this will cause confusion if used as such. Period. Don't be ridiculous, such an absolute statement has no chance of being correct -- there are positives to overloading the short-circuiting operators, and what if you're in a situation where there are no negatives? [1] It's a trade-off between convenience 'n lookin' good and understandability [2]. Suppose your library has already overloaded & and | for something. And it's overloaded * and / and + and - and % and ^ and, I don't know, the comma operator (lol). And operator[] and operator(). Then all you gots left is the short-circuiting and operator (&&), the short-circuiting or operator (||), and the short-circuiting xor operator (^^). You have to overload those, because what are you going to do, write a function call? I've written things in terms of regular old functions when making embedded expression grammar libraries and trust me, it's slightly inconvenient. Imagine having to write alt(foo, bar, baz) instead of foo || bar || baz. That would be terrible, because then anybody could grep your code! [1] For example, suppose nobody wants to maintain your code, so they always rewrite it. [2] Treat "'n" as a higher-precedence conjunction than "and".
|
# ? May 7, 2013 23:53 |
|
shrughes posted:and the short-circuiting xor operator (^^) Is this a thing? I'm quite sure you have to always evaluate both sides for XOR.
|
# ? May 8, 2013 00:00 |
|
That Turkey Story posted:Compile times and error messages are the big ones, although prior to lamdas being in the language, you didn't really have any better alternative, and even now the library approach can be more capable than the language approach in some respects (sadly).
|
# ? May 8, 2013 00:01 |
|
Suspicious Dish posted:Is this a thing? I'm quite sure you have to always evaluate both sides for XOR.
|
# ? May 8, 2013 00:01 |
|
|
# ? May 30, 2024 06:45 |
|
shrughes posted:Don't be ridiculous, such an absolute statement has no chance of being correct -- there are positives to overloading the short-circuiting operators, and what if you're in a situation where there are no negatives? [1] So what you're saying is that if your library has already overloaded lots of operators, it's not a big deal to modify two more? I would agree with that, because at that point you've already implemented a mini-DSL and an expectation for weirdness (that is hopefully consistent within itself, at least) is already in place, and newbie confusion (followed by the requisite training) is already a matter of course. Now, I would still avoid it, but if it fits, it fits.
|
# ? May 8, 2013 00:05 |