ID:446866
 
Keywords: , and, design, logic, operator, program
So we learned today in my Program Logic and Design that you can increase your programs speed by putting the expression that is least true FIRST in an && statement. For example:

if(src.level==10&&src.kills>=5)


We'll say in this game you can easily get 5 kills as a level 1, so I put src.level==10 because it's less likely for them to be level 10.

Does anyone really see a true purpose in this? I mean yeah, I understand how it could work and help, but is it necessary? What do you guys think?
What you're referring to is commonly called "short circuiting", where only some of the statements need to be computed to determine the final result. For simple variable comparisons, you won't see any speed improvement. However, if the statements called more complex processes to get their values (such as searching for a value in a list, or a graph) it makes sense to avoid that overhead whenever possible.
Essentially,
if(boolean && super_slow_proc())

where 'boolean' is just that, and
super_slow_proc() is something that eventually returns a boolean value, but takes a significant amount of CPU to get that result.
&& works in a way that it checks from left to right and stops at the first value that doesn't work. If 'boolean' is false, the whole thing stops and super_slow_proc() is never called. If 'boolean' is true, super_slow_proc() is called.

In Lummox JR's source of Runt, he uses a curious form of this syntax.
// example (not from the source)
mob
var hp = 10

proc
take_damage(damage)
hp -= damage
hp <= 0 && die()

// It could have been written:
if(hp <= 0)
die()

die() is called whenever hp is less than or equal to 0. die() itself doesn't need to return a value to be evaluated in the statement, it's just called.
Interesting. So it'd be useful in situations like:

if(usr.isSpy==1&&usr.victim in worldPlayers)


I'll look through my code then and see if I can find out anything. I always thought this class was just gonna be everything I knew, but it turns out I did learn something after all!
In response to Ganing
You'll want to put 'usr.victim in worldPlayers' in parentheses, or else the order of operations will cause a bug by reading it as "(usr.isSpy==1&&usr.victim) in worldPlayers", or "[boolean] in worldPlayers".
if(usr.isSpy && (usr.victim in worldPlayers))
Gotcha. Thanks for that. It's those little things that take me hours to figure out when I come across a bug.
Yes, in Runt I had to pull out all the stops to compress that code to 4K. The && trick helps in a number of places.

One handy usage of || and && in DM is that the result of the expression is always the last value evaluated. That is, "a" || 2 will always be "a", but null || 2 is 2. Likewise "a" && 2 should be 2, and null && 2 should be null. The || trick is useful when you want to assign a default value and you don't have to account for 0 or "" (which are also false) as valid choices.
In response to Lummox JR
Sometimes I think a ||= or &&= operator would be kinda useful.
var blah = get_blah()
...
// some crazy situation that wouldn't let me just do
var blah = get_blah() || 42
...
blah ||= 42
// A ||= B
// Shorthand for A = A || B
if(blah == (get_blah() || 42))
if(A == (B || C))


Of course, you probably can do

var blah = pick(get_blah(), 42)
In response to Kyle2120
pick() is random. The operators check in a certain order.

|| goes from left to to right, evaluating as it goes, and "returns" the first true value it finds, or the last of a series of false values.

&& goes from left to right, evaluating as it goes, and "returns" the first false value it finds, or the last of a series of true values.
In response to Kyle2120
Kyle2120 wrote:
if(blah == (get_blah() || 42))
if(A == (B || C))

Of course, you probably can do

var blah = pick(get_blah(), 42)

The above isn't actually equivalent to checking if blah is either get_blah() or 42. That would be like so:

if(blah == 42 || blah == get_blah())

Your code is actually equivalent to saying if get_blah() is a false value, use 42 as a default instead, and compare the result to blah. Likewise, your second line is equivalent to saying that if B is false, C will be compared to A instead.
In response to Lummox JR
Lummox JR wrote:
One handy usage of || and && in DM is that the result of the expression is always the last value evaluated. That is, "a" || 2 will always be "a", but null || 2 is 2. Likewise "a" && 2 should be 2, and null && 2 should be null. The || trick is useful when you want to assign a default value and you don't have to account for 0 or "" (which are also false) as valid choices.

Me likey. =)
// Keep atom coordinates and list indices valid.
// Pardon my paranoid parentheses. ;)
#define WrapMin1(Val,Max) ( (Val<0) ? ((Val%Max)+Max) : ((Val%Max) || Max) )