Not when it's at the cost of readability. The example "better" code fails my readability test horribly. I'd gladly take C's ternary operator over this monstrosity:
> x = 4 if condition() else 5
Not when it's at the cost of readability. The example "better" code fails my readability test horribly. I'd gladly take C's ternary operator over this monstrosity:
> x = 4 if condition() else 5
cssClass = 'selected' if isCurrentTab else 'deselected'Or in pseudocode
if isCurrentTab
cssClass = 'selected'
else
cssClass = 'deselected'
Even ternaries read weird. "css class is current tab HUH?? selected COLON! deselected" x = 5
if condition():
x = 4 (x = 5, condition())
is inconsistent state (using the word "consistent" in the same sense as the C in ACID).It really is clearest and safest to avoid inconsistent state, even if is only transient. There are so many ways programs can be wrong; no need to deliberately create inconsistent state when there's no need to.
Also, your version isn't safe to use with objects (e.g. 'myObject.x = ...'), since the initial assignment could trigger arbitrary code (properties, __setattr__, etc.).
Also, your version isn't safe to use when the right-hand-side has effects, e.g.
x = fetch_config_url() if remote else read_config_file() x = if condition() then 5 else 4
I dislike how the regular order of if is changed when used as an expression. I don't know how you could retrofit that into existing Python tough. Probably a consequence of defining blocks with whitespaces.> Special cases aren't special enough to break the rules.
> There should be one-- and preferably only one --obvious way to do it.
Both are broken by the existance of 2 if syntaxes depending on the context.
Infix "if" conditions just scramble up the order of evaluation from the order of program source code.
If the condition-guarded statement is nontrivial and you remove the assignment, everything stays valid. If otoh you use a ternary or
if x:
y = 1
else:
y = 2
If you now delete the else block or something (like the assignment from a larger else block), a linter can warn you that y is undefined. Otherwise you'd need a test to ensure correctness.Though Ruby’s unless modifier is often slightly better for readability.
int result = condition
? value * 12
: something_else();
and in the case where the condition is sufficiently complex: int result =
(
some_condition()
&& another_condition()
&& yet_another_condition()
)
? value * 12
: something_else();
For me, at least, this is entirely readable. The unfortunate bit is that there is no formatter in existence (yet) that can handle this for C, or really any other language with similar syntax.Python's "Black" formatter actually does the best job here, yet the python ternary syntax is still very verbose and strange IMO.
Prettier does it fine for JS, which uses C-style ternary syntax.
> Python's "Black" formatter actually does the best job here, yet the python ternary syntax is still very verbose and strange IMO.
To me, its quite natural when used sensibly, since if you drop everything after the if it is the normal-case value. Though I would slightly prefer if the ternary form was:
<default-valur> unless <alternative-condition> then <alternative-value>
instead of: <default-value> if <default-condition> else <alternative-value>> Though I would slightly prefer if the ternary form was:
Agreed, I do like that much better too.
I get that it's a "flex" or some sort, but honestly in production code my experience is that it reduces productivity. Programmers need a little more squinting to truly understand what that piece of code is doing.
I find it similar to run-on sentences in books - we don't like that, and in Business Writing courses they explicitly say to not do that. Code should be similarly readable.
So...you should do more per line, since code is all one-liners, its just a choice of how many, so if you don't like them, you should reduce the number?
$user_authenticated = hmac_auth($_get['token']) === true || ldap_check($username, $config['ldap_restrictions']) || verify_credentials($_post['user'], $_post['pass']) === true;
Sorry for the php pseudo code, I'm on mobile. And this is a very friendly example of what I'm trying to get across. It's self documenting code and worth the extra bytes.
I've seen way too many insane conditionals to agree that less code is better.
[ x.attr for x in list if x in someset]
There are languages where this kind of thing would be considered ugly and you’re supposed to use map/filter but in Python they’re the best practice. Every Python programmer is already trained to read expressions like this.if condition(): x=4 else: x=5
I wouldn't mind it so much if I could write it as:
x = 4 unless shenanigans(); then x = 5
Yes, that is a semicolon. Fight me.Makes way more sense to my brain to read:
print unless $x ~ /end$/;
then
print if $x !~ /end$/;
I used to get flack for using not just if expressions as ternaries, but also for using unless. Then I started teaching PERL at my company and drilled it into all the fresh new minds.
my $x = do {
if (foo()) {
4
} else {
5
}
};
(and yes, I know, that example would look fine as a ternary - but this is meant to illustrate the syntax possibility, not where I'd specifically use it - and once the logic within one of the two conditional branches gets more complicated, switching to do+if+else can make for clearer code)Also doing that with if/elsif/elsif/else is often far more readable than nested/chained ternaries.
So you can read both as a sentence. The arguable part is more about "condition and then thing" versus "thing if condition".
For the cost of 4 extra characters, this line tells you exactly what it does even if you've never seen Python in your life.