Michel Fortin wrote:
On 2009-12-07 23:52:04 -0500, Andrei Alexandrescu
<[email protected]> said:
Michel Fortin wrote:
On 2009-12-07 01:29:14 -0500, Andrei Alexandrescu
<[email protected]> said:
Using double negation !!x throughout, there are only advantages and
no disadvantage. I hit that design with Pacquiao punches over the
past week or so, and couldn't find any shortcoming. It's consistent
across positive and negated uses, easy to understand, easy to
define, consistent with built-in types, and Walter likes it.
I'm not sure that's a great idea. What if you define your own
FuzzyBool type (containing some sort of probability) and
FuzzyBool.opUnary!("!") returns an inverted FuzzyBool (with 1 -
original probability) instead of a regular bool, you'd have an
infinite loop trying to evaluate !!myBoolValue.
Yeah, I thought about that liability and decided to discount it as a
design mistake of the user. If a type decides to return non-bool from
"!", they are bound to unpleasantly surprise its user in more ways
than one. You can define a negate for FuzzyBool - just don't dress it
as the "!" operator.
To me, its using "!" to transform something to a bool that looks like a
hack. Surely there's a more explicit and intuitive way to define it that
doesn't tie it to a specific operator.
Actually this is quite what happens with built-in types. A common
misconception (I'm sure not yours) is that "if" works with Booleans. In
fact it works with Booleans, numbers, pointers, arrays, and class
references. In a very palpable way "if" is special-cased for each of these.
Then, the common misconception goes, all of those have a sort of
conversion to Boolean that "if" taps into. Not quite, because if you try
to assign a bool from an array or even an integer, it won't work.
What does work is operator "!". Operator "!" accept _all_ of Booleans,
numbers, pointers, arrays, and class references - i.e., exactly the set
of "if"-testable entities. And it uniformly yields bool. So it is an
excellent device for hooking user-defined types into "if". I'd say it is
not a hack at all, although it may look so at first sight. It really
holds water.
opTest perhaps?
opTest was on the bench for a short while, but Walter threw his hands.
"How many operators are you going to define?" And he's right - I'd do
with fewer rather than more redundant operators. We (will) have a method
for defining unary operators. I don't see why make an exception of "!",
or, worse, allow both operator "!" and opTest.
And if you think "!" should always return a bool, then it should just
not be overridable and should be defined as returning the negation of
opTest (or whatever the name). I don't feel restricting unary "!" to
return a bool is sound when all other unary ops can be defined to return
anything.
It's possible to require opTest and then say that "!a" is always
rewritten into !a.opTest. But then consider this fragment:
"For all unary operators except "!", the expression
<op> a
is rewritten as
a.opUnary!"<op>"()
However,
!a
is rewritten as
!a.opTest()"
Would you like to see something like that in TDPL?
Andrei