if (you.religion = GOD_XOM) {
This actually made it to the live test server, where player save files are automatically upgraded to the most recent build, so anyone logging in immediately found themselves infallibly worshiping the god of chaos, every single tick of in-game time (renouncement is futile). Chaos indeed!In languages where accidental assignment is possible (i.e. writing if(a=b) when you meant if(a==b) ), configure the compiler or linter to emit a warning in this situation.
For example in C, GCC will complain about this when compiling with -Wall, which you should be using anyway.
> The assignment operator is =. I was dubious about this, but decided to try it and see if I got used to it. It turns out to work well, even in prefix. Stripes stand out, which is why they get used on warning signs and poisonous animals.
(if (= whatever whatever-else) (you-got-burned))
Arc code written by people used to Lisp dialects where = is a pure comparison function, or Arc code converted from other Lisp dialects, has to be carefully reviewed against this.If I put this into a Lisp dialect, I would make the code walker issue a warning whenever the value of a (= ...) assignment is used, and provide an alternative assignment operator which doesn't have that warning.
In fact, it's not easy to have this kind of bug on your language. C just has it because people wanted to write stuff like `int a = b = 0`.
Programmers using equals for assignment is a bit of a misunderstanding of what the mathematical idiom "let x = 5" means. The assignment is signaled by "let", not by "=". In fact, several programming languages use "let" exactly for this purpose too.
use strict;
use warnings;
sub one { 1 }
if ( my $one = one() ) {
say $one; # prints 1
}
say $one; # compilation error, "Global symbol "$one" requires explicit package name"
This case is trivial, but when you want a temporary variable and don't want to clutter your scope, it can be useful.That's not to say assignment and equivalence might not be better off with different operators, as noted by others here.
Yes, that's what I was trying to get at by saying definition, but not very clearly. It's one of the reasons I prefer languages to require and clearly indicate variable declaration in most cases.
You have to take bits of concision where you can find them in Java.
Do do this if the coding standards for the language/framework you're working in require it. Like WordPress.
I'd rather it be done by people who care than those that don't.
Also it's slightly awkward to read, as mentioned by others already.
Re: awkwardness, it doesn't feel awkward at all to me; given that Erlang and Elixir use assignment for destructuring and pattern-matching, Yoda conditionals feel very natural to me in comparison.
For example, this is valid Elixir code:
foo = {1, 2}
bar = if {baz, 2} = foo do
525600
end
IO.inspect foo # prints {1,2}
IO.inspect bar # prints 525600
IO.inspect baz # prints 1You can't force everyone who edits your code to have linters and warnings turned on. Not everyone follows bests practices.
It's OK if your tools absolutely can't diagnose accidental if(a = b), but it should be the last resort.
mString != null && mString.equals("test")
or "test".equals(mString)
They do the same, but the second one adds hidden `defensive programming` to prevent NPE in `equals`. Saves time AND code.Intended usage of if(a=b) should be written as if((a=b)). Don't know what tool you use at work or at home, but most static code analysers will point you that. Try SonarQube at least.
I feel as if that can rephrased "Don't do it because it is not done." A left-hand side constant is a convention that can have practical benefits in limited cases. Which at least should merit consideration.
if ((a = b) != NULL) ...
I think Rust has a happy medium, where assignment evaluates to (), not the variable (important as this means you don't have an implicit borrow), but the idiom expressed here is usually replaced by: if let Some(thing) = fn_that_returns_option_thing() ...Take this example:
function handle_request($http){
if("OPTIONS" === $http.request.method){
...
}else if("GET" === $http.request.method){
...
}else if("PUT" === $http.request.method){
...
}else if($http.request.method === "POST"){
...
}
...
}
Did you read $http.request.method four times? I bet not. Some of you may have read it the first time; I wouldn't have. But to know that the fourth block handled POST requests I made you read to the end of the line. That makes it harder to scan the code looking for the section that you want to change. In production code that I've seen, the predictable side of a comparison is often quite long.What's especially bizarre to me is the reason people give when advocating writing in the last style. Yes, it verbalizes nicely as "Otherwise, if the http request method post, then..." But who internally translates their code to English to understand it? COBOL was designed to read like natural language. Do you enjoy programming in COBOL? If English-like syntax is desirable for code readability, why don't modern programming languages prioritize English-like syntax, too?
Greek mathematics got stuck because it remained a verbal, pictorial activity, Moslem "algebra", after a timid attempt at symbolism, died when it returned to the rhetoric style, and the modern civilized world could only emerge —for better or for worse— ... thanks to the carefully, or at least consciously designed formal symbolisms that we owe to people like Vieta, Descartes, Leibniz, and (later) Boole.
-- Dijkstra,
if ($value = getSomeValue()) {
// Safely use value
}
Yoda Conditions defend nicely against accidents when '=' and '==' can be used legally this way and honestly you get used to reading them pretty quick.C++, for instance however has language syntax to prevent confusion when using this idiom – declarations inside conditionals:
if (auto val = getval())
foo(val); // executed only if getval() returned something that evaluates to true
// in a boolean context
Considering that PHP already has the useless var keyword, they might just adopt something similar in the future if (var $val = getval()) {}They're also a false sense of security as they won't catch:
if $(value = $someOthervalue) ... if( booleanVariable == true )
{
...
}
else if( booleanVariable == false )
{
...
}
else
{
// Typically, this section would include an exact copy
// of one of the above sections, as it was 3 years ago,
// presumably to pad out the SLoC metrics.
}
That place had its head so far up its own ass....Equivalence is commutative. Please never complain about the order of its operands as "confusing" or "less readable". It just tells me that you're an ass, trying to enforce a coding convention that has no objective reason to exist.
if "start" == argv[1]:
....
else if "stop" == argv[1]:
....
else if "reload":
....
else if "status" == argv[1]:
....
I think it'd be harder to make this mistake with the conditions the right way around. (Also, never mind that the equality bug isn't even possible in Python.) {'start': fn_start,
'stop': fn_stop,
}.get(
argv[1] if len(argv) > 1 else None,
fn_undefined
)(*args, **kwargs)
I used this in a demonstration terminal nibbles/worms video game clone, https://github.com/jquast/blessed/blob/master/bin/worms.py#L...Ex:
Foo SOME_CONSTANT = <something-not-null>;
Foo userSuppliedInput = <some-user-input-possibly-null>;
// This can raise an null pointer exception
if (userSuppliedInput.isEquals(SOME_CONSTANT) {
// ...
}
// This can't raise a null pointer exception (assuming isEquals handles nulls properly):
if (SOME_CONSTANT.isEquals(userSuppliedInput) {
// ...
} if([userSuppliedInput isEqual: SOME_CONSTANT]) { ...
If userSuppliedInput is nil, the isEqual: returns false, and it works.It gets really fun when both might be nil:
if([a isEqual: b]) { ...
If a and b are both nil, then they're conceptually equal, but isEqual: still returns false because it's a mindless "always return 0 for messages to nil" thing that doesn't even look at any parameters passed in. NULL = NULL
It's not true or false, ... it's NULL!After having done Swift for a while, I'm a big fan of using an option type so that "reference to object" is a different static type altogether from "reference to object, or nil."
if x > 0:
y += x
versus y += x if x > 0 save if valid
rather than if valid
save
end
but what I see 9 times out of 10 is things.do each |thing|
foo
bar
baz
end if valid
orreally.long.thing.that.i.try.to.parse.in.my.head if acutally_almost_never_happens
which is harder to read since I read top to bottom / left to right, but the flow is bottom to top and right to left
# Not allowed
for ( 1 .. 10 ) {
say $_;
} if 1;
# Allowed
map { say $_ } ( 1 .. 10 ) if 1;
The idea seems to be that a post-conditional should be simple and obvious by the time you've parsed the statement. A block makes it confusing, as does mixing post control structuresPost-loop structures have the same limitation:
# Not allowed
{ say "foo"; say $_ } for ( 1 .. 10 );
# Allowed
say $_ for ( 1 .. 10 );
When used correctly, these can become very succinct and clear. my %data = get_data_record_hash("foo");
$data{$_} = update_field(data{$_}) for ('field1','field4',other_field');
# Compare to map, which normally you expect to return values
map { $data{$_} = update_field(data{$_}) } ('field1','field4',other_field');
The single statement limitation keeps you from going wild in ways that are probably not useful to future readers of the code (including you).In Perl:
if ($x > 0) { $y += $x }
versus: $y += $x if $x > 0; $days = 28 if $month eq "February";Example: plantArrowhead, plantGuzmania, plantMarmo vs. arrowheadPlant, guzmaniaPlant, marmoPlant.