Implication for C++ [pdf]
open-std.org
open-std.org
[1] https://stackoverflow.com/questions/1642028/what-is-the-oper...
x => x + y
instead of [&](auto &&x) { return x + y; }Programs must be maintained. This means that a programmer must be able to read a program and understand it. Forcing the programmer to understand implication makes no sense.
We do give up understandability already with templates. Templates can be a source of non-understanding, but also there is no replacement for templates. Implications don't need a new feature since ?: already solves this.
Compare this proposal to another weird C feature:
char \*a;
...
17[a] = 'b';
where, although the array operator is associative, it simply isn't used that way in code because it offers no useful feature. Therefore it is an insane feature which is harmless. The implication proposal is not harmless.Anyone came up with some enlightening examples?
assert(someObj => someObj.data);
The cannonical way to write that currently would likely be something like:
if (someObj) assert(someObj.data);
assert(!someObj || someObj.data);
Which seems fine as it is.
I don’t know you, but I guess that’s because of familiarity from years of seeing this kind of thing.
I think “=>” is clearer because it is what (AFAIK) people learn at school.
You might learn "x => y" in school (I didn't!) but if you did it was probably in the context of making implication (modus ponens). You are told p=>q, and then later you also find that p is true, so you can deduce that q is true. That's easy enough.
But figuring out whether p=>q is true is tricker (intuitively). Say someObj is falsey - is "someObj => someObj.data" true? Well, it is, because an implication p=>q is always true if p is not true e.g. "if normal dice rolls a 7 then the weather is rainy" is true because a normal dice never rolls a 7. Is that intuitively obvious for everyone? I can't believe it.
Is "!someObj || someObj.data" true if someObj is falsey? That is really easy in comparison - maybe not everyone will just see it at a glance, but you just check the two subexpressions one at a time, and immediately notice that "!someObj" is true. (What about if it's truethy? Also easy - the first subexpression is false, so you move on to the second one - it's only true if "someObj.data" is truethy.)
assert(someObj && someObj.data);
So it’s !P || Q. Or P=>Q as the author proposes.
If(bValidate => IsValid()) { /* runs if either validation was unnecessary or passed */ }
And that would be equivalent to (!bValidate || IsValid()).
I think it’s not an April Fool’s joke, but this looks awfully confusable with >=.
!(a) || (b)
It’s a very obvious spelling :)I agree with the other commenter that => would be better used for lambdas.
I run `pdfinfo` and found out it was created with LaTeX...I need its settings so bad...I adore good looking, elegant PDF files!
For example, BMI1 ISA extension defines bitwise and not instruction, available in C++ as `_andn_u32()` or `_andn_u64()` intrinsics. That’s a rare operation most programmers are unfamiliar with, but it’s trivial to search internets for `_andn_u32`. It gonna be hard to find anything good searching for `=>`
But !a() || b() does that. So it seems that the proposal isn't needed. a implies b should just be written !a || b.
This is the paradox. Simple languages push complexity to the user. Complex languages on the other hand simplify the user's tasks.
You're way more productive using the container-agnostic `std::find()` than rolling your own version of it, as you might in other languages.
BUT I wouldn't say simpler. Do you slather `noexcept` on every method you write and turn every `const` to `constexpr`? :p Some advocate for that, and the have-a-new-keyword-for-something-that-should-actually-be-the-default-(but-of-course-the-defaults-will-never-not-be-backwards-here-because-we-got-them-wrong-way-back-and-too-much-existing-code-will-break-if-we-change-them) game is getting a little crazy for me.
You have an example? Cause I don't see how this is true.
I don't think this captures the uniquely awful combination of "object oriented" + "low level (manual memory management)" that C++ chose. I think that's the most inherently complex dyad of traits you can choose for a programming language, and I think it's why C++ is the most complex programming language that's ever existed. They even tried hiding the complexity in shame with implicit behavior, like the compiler synthesizing the "rule of 5" functions for you, meaning you have to go out of your way and mark them as "deleted" to tell it not to do that when you know it'll do it wrong and leak memory and you have to memorize what the "rule of 5" is. (The only other language I can think of that went down the same route is D, but I don't know how complex it is in comparison to other languages. Maybe Walter Bright can argue it's a counterexample to my argument cause it's waaay simpler than C++. But then I'll counter-counter argue that it has garbage collection. But then again that's optional. My brain hurts.)
However people that assert that, usually never went through PL/I, ALGOL 68, Ada, Common Lisp standards, nor have realized how JVM/Java, CLR/C#, Python/StdLib have changed during the circa 30 years of their existence.
I replaced the table "raining? umbrella? faithful?" with "raining? umbrella? dry?".
Then made sense in my head only if I write something like this:
dry = umbrella || !raining
If I use my umbrella. I'm don't care it rains. Otherwise I will be dry only if it does not rain.