You are viewing an older version of the site. Click here to view
the latest version of this page. (This may be a dead link, if so, try the root page of the docs
here.)
Many times you want to use a bit of basic logic to determine what to do. Usually you want to compare
two values to see if some relationship between them is true. Based on the result of this comparison,
you want to do one thing or another. This is where the logic operators come in handy. There are several
functions that all act relatively the same in the BasicLogic class. Essentially, they compare certain
values, then return a boolean.
''Note: The examples in this tutorial primarily use operators, see the page on [[Operators|Operators]]''
''for a refresher, if the operators are unclear.''
==Basic Usage==
Let's take the {{function|lt}} function into consideration (
Copy Code
All the functions in the [[API#BasicLogic|BasicLogic class]] return a
boolean based on certain conditions. You should be familiar with the lt (less than
Copy Code
Copy Code
Copy Code
Copy Code
For convenience, there are also the nand, nor, xnor functions, which are equivalent respectively to not(and()), not(or()), and not(xor()).
==Bitwise Functions==
The three bitwise functions bit_and, bit_or, and bit_not work similarly to
Copy Code
Bitwise operations are useful for storing many boolean values as a single integer, among other uses.
It may be useful to note that integers are stored as 64 bit two's compliment values.
Copy Code
==if()==
Now that we have established that some conditions are true or not, we may want to do different
things depending. This is where the
Copy Code
The condition and code to run if true are required, but the code to run if false ("else") is optional.
If it is left off, and the condition is false, void is returned. Only one branch of code is executed here.
If condition resolves to true (which may itself contain more complex code), then the second argument is
evaluated and returned, otherwise the third argument is evaluated and returned. Note that the other
code branch is not even evaluated, that is, it is skipped entirely.
Copy Code
The "old style" of if was a fully functional syntax, though that syntax is still useful for ''ternary statements''.
In most languages, this is the ''condition ? true : false'' syntax.
Copy Code
If the @condition is true, then 1 is assigned to @var, otherwise 2 is.
===Truth value testing===
The following are considered to evaluate to true:
* The keyword and boolean value
Copy Code
In this usage, the
Copy Code
In this usage, we can imagine a "default" case. If at least one of the
Copy Code
As you can see, it's a bit less code using the switch statement, but the results can be achieved either way.
Sometimes you may want to do a different type of comparison, other than equals, so you have to use if/else if/else chains.
As with if/else if/else chains, a "default" condition can be stated, in the event none of the given conditions are satisfied.
When possible, however, switch statements should be used, as they can be better optimized by the compiler.
Sometimes you may want to run some code given that the value equals one of any number of values.
In this case, you may specify multiple cases, and if the value equals any
of the values specified, the corresponding code is run.
Copy Code
Though you can technically use non-string and non-integer values as the comparison types, it is not recommended,
and in fact, arrays may not be used at all. When writing code, you should only use integers and strings whenever possible.
Slices may also be used, and if so, if the test value falls within the range of the slice, that code block is run.
Copy Code
Unlike many other languages, no {{function|break}} is strictly necessary. Code blocks are run starting with the case statement,
running until the next case. Only if a case should be ignored must you use break(), otherwise code will merge with the following case.
For instance, say we want nothing to happen should the value = 2.
Copy Code
Had we left the break() out, case 2 and the default case would have merged together. In all other cases, break() is optional.
{{TakeNote|text=While break() is in fact optional, it is still recommended that you use it when applicable.}}
Using break() is still recommended however, even though it is technically optional. Consider the following example.
Copy Code
In this example, if @v is 1, we msg out 1, and if @v is 2, we message out 2. Consider however, if we comment out line 3,
Copy Code
Now, if we comment out
<
operator).
lt returns true if the value on the left is less than the value on the right. In a typical
algebra class, when comparing two numbers, you would write something like this:
x < yAssuming x is 3 and y is 4, this statement is true. However, if we swap the values, and make x 4 and y 3, the statement is false. Written in code, it would look like this:
@x < @y

1 @x < @y
<
),
lte (less than or equals to <=
), gt (greater than >
),
gte (greater than or equals >=
) functions
from a basic algebra class that covers inequalities.
==Boolean logic==
Some of the functions you may not have seen before if you haven't taken a logic or programming class
are the boolean logic operators. For a full discussion of boolean logic, you may wish to read up
[http://en.wikipedia.org/wiki/Boolean_logic on wikipedia] for more information, however a basic
treatment is covered below.
The three main operators: and (&&
), or (||
), and not (!
)
are the building blocks for more complicated logic statements.
These functions deal with the overall truth value of a construct, not individual bits (see the
bit_and and bit_or functions).
and()
(&&
) returns true if '''all''' the parameters resolve to true:
(true && true && true && true) # returns true
(true && true && false && true) # returns false

1 ({{keyword|true}} && {{keyword|true}} && {{keyword|true}} && {{keyword|true}}) # returns true
2
3 ({{keyword|true}} && {{keyword|true}} && {{keyword|false}} && {{keyword|true}}) # returns false
or()
(||
) returns true if '''any''' of the parameters are true
(true || false || false || false) # returns true
(false || false || false || false) # returns false

1 ({{keyword|true}} || {{keyword|false}} || {{keyword|false}} || {{keyword|false}}) # returns true
2
3 ({{keyword|false}} || {{keyword|false}} || {{keyword|false}} || {{keyword|false}}) # returns false
not()
(!
) returns the opposite truth value of the parameter:
(!true) # returns false
(!false) # returns true

1 (!{{keyword|true}}) # returns false
2
3 (!{{keyword|false}}) # returns true
xor()
returns true if both parameters are different
xor(true, true) # returns false
xor(false, false) # returns false
xor(true, false) # returns true
xor(false, true) # returns true

1 {{function|xor}}({{keyword|true}}, {{keyword|true}}) # returns false
2
3 {{function|xor}}({{keyword|false}}, {{keyword|false}}) # returns false
4
5 {{function|xor}}({{keyword|true}}, {{keyword|false}}) # returns true
6
7 {{function|xor}}({{keyword|false}}, {{keyword|true}}) # returns true
and
,
or
and not
, but they only work with integers, and they work on a
binary level to determine the bitwise equivalent of two or more integers, and return that integer.
Again, a full discussion of how bitwise operations work is beyond the scope of this article, but some examples are below:
bit_and(4, 7) # binary equivalent: (100, 111) returns 100 = 4
bit_and(7, 5) # binary equivalent: (111, 101) returns 101 = 5
bit_and(1, 4) # binary equivalent: (001, 100) returns 000 = 0
bit_or(1, 3) # binary equivalent: (001, 011) returns 011 = 3
bit_or(2, 4) # binary equivalent: (010, 100) returns 110 = 6
bit_not(4) # binary equivalent: (0..100) returns 1..011 = -5

1 {{function|bit_and}}(4, 7) # binary equivalent: (100, 111) returns 100 = 4
2
3 {{function|bit_and}}(7, 5) # binary equivalent: (111, 101) returns 101 = 5
4
5 {{function|bit_and}}(1, 4) # binary equivalent: (001, 100) returns 000 = 0
6
7
8 {{function|bit_or}}(1, 3) # binary equivalent: (001, 011) returns 011 = 3
9
10 {{function|bit_or}}(2, 4) # binary equivalent: (010, 100) returns 110 = 6
11
12
13 {{function|bit_not}}(4) # binary equivalent: (0..100) returns 1..011 = -5
lshift
, rshift
, and urshift
are also available. lshift(value, bitsToShift) is the general format for all three.
lshift(4, 2) # returns 16
urshift(10, 2) # returns 2
rshift(-10, 2) # returns -3
urshift(-10, 2) # returns 4611686018427387901
rshift(3, 1) # returns 1

1 {{function|lshift}}(4, 2) # returns 16
2
3 {{function|urshift}}(10, 2) # returns 2
4
5 {{function|rshift}}(-10, 2) # returns -3
6
7 {{function|urshift}}(-10, 2) # returns 4611686018427387901
8
9 {{function|rshift}}(3, 1) # returns 1
if()
function comes in. We are creating "code branches"
when we use if and other conditional statements, which means that sometimes code will not get run.
The syntax of the if statements is as follows:
if(condition){
// code to run if true
} else {
// code to run if false
}

1 {{keyword|if}}(condition){
2 // code to run if true
3
4 } {{keyword|else}} {
5 // code to run if false
6
7 }
if(true){
msg('Once');
} else {
// This "block" won't run at all
msg('Twice');
}

1 {{keyword|if}}({{keyword|true}}){
2 {{function|msg}}('Once');
3 } {{keyword|else}} {
4 // This "block" won't run at all
5
6 {{function|msg}}('Twice');
7 }
if
technically returns a value. If
the value in each block is a single, returning value, that value will be returned. As a convention, only if a
ternary operator is desired should you use the functional syntax. The following code works as expected:
@var = if(@condition, 1, 2);

1 @var = {{keyword|if}}(@condition, 1, 2);
true
* Any non-empty string
* Any number different from 0
* A non-empty array
Null values are always considered false. All primitives, and some more complex objects implement the
ms.lang.Booleanish type, which allows them to return true if the value is '''trueish''', meaning that while the value
itself is not a boolean, it has a true/false interpretation, and can explicitly be cast to a boolean with the
{{function|boolean}} function. This is a generic concept though, and so it's not possible to create a comprehensive
list of things that are supported with this mechanism.
==else if==
if/else if/else chains can be formed as well, if multiple conditions need to be checked. Using only
if/else would quickly get messy if you have multiple values to check for.
Instead, you may use the ''else if'' chain.
if(@val1){
// code1
} else if(@val2){
// code2
} else if(@val3){
// code3
}

1 {{keyword|if}}(@val1){
2 // code1
3
4 } {{keyword|else}} {{keyword|if}}(@val2){
5 // code2
6
7 } {{keyword|else}} {{keyword|if}}(@val3){
8 // code3
9
10 }
val
s will be evaluated from top to bottom, and once the first val is true,
the corresponding code will be run. If none of the vals are true, then nothing in the chain will run.
if(@val1){
// code1
} else if(@val2){
// code2
} else if(@val3){
// code3
} else {
// default case
}

1 {{keyword|if}}(@val1){
2 // code1
3
4 } {{keyword|else}} {{keyword|if}}(@val2){
5 // code2
6
7 } {{keyword|else}} {{keyword|if}}(@val3){
8 // code3
9
10 } {{keyword|else}} {
11 // default case
12
13 }
@val
s
is true, then it will behave the same. However, if none of the vals are true, then the
final code block will be run instead. This is the final "else" clause of the statement.
The {{function|ifelse}} function is the non-brace way to do if/else if/else chains, though
its usage is not recommended, as it is less readable. Internally, if/else if/else chains are
converted to it still, however.
==switch()==
A switch statement works by simplifying comparisons. Unlike if/else if/else, switch checks to see if some value
is equal to another value, then running that code, instead of just seeing if the value itself is true.
Switch statements can actually be written using if chains, so to demonstrate, here is the same code written both ways:
@value = 'value';
if(@value == 'value1'){
// code1
} else if(@value == 'value2'){
// code2
} else if(@value == 'value3'){
// code3
} else {
// default
}
switch(@value){
case 'value1':
code1();
break();
case 'value2':
code2();
break();
case 'value3':
code3();
break();
default:
code4();
break();
}

01 @value = 'value';
02 {{keyword|if}}(@value == 'value1'){
03 // code1
04
05 } {{keyword|else}} {{keyword|if}}(@value == 'value2'){
06 // code2
07
08 } {{keyword|else}} {{keyword|if}}(@value == 'value3'){
09 // code3
10
11 } {{keyword|else}} {
12 // default
13
14 }
15
16 {{function|switch}}(@value){
17 {{keyword|case}} 'value1':
18 {{function|code1}}();
19 {{function|break}}();
20 {{keyword|case}} 'value2':
21 {{function|code2}}();
22 {{function|break}}();
23 {{keyword|case}} 'value3':
24 {{function|code3}}();
25 {{function|break}}();
26 {{keyword|default}}:
27 {{function|code4}}();
28 {{function|break}}();
29 }
#if val equals either test2, test3, or test4, code234 is run
switch(@val){
case 'test1':
code1();
break();
case 'test2':
case 'test3':
case 'test4':
code234();
break();
default:
defaultCode();
break();
}

01 #if val equals either test2, test3, or test4, code234 is run
02
03 {{function|switch}}(@val){
04 {{keyword|case}} 'test1':
05 {{function|code1}}();
06 {{function|break}}();
07 {{keyword|case}} 'test2':
08 {{keyword|case}} 'test3':
09 {{keyword|case}} 'test4':
10 {{function|code234}}();
11 {{function|break}}();
12 {{keyword|default}}:
13 {{function|defaultCode}}();
14 {{function|break}}();
15 }
@value = 1;
switch(@value){
case 0:
case0();
break();
case 1..5:
case1_5(); // This one will run
break();
}

1 @value = 1;
2 {{function|switch}}(@value){
3 {{keyword|case}} 0:
4 {{function|case0}}();
5 {{function|break}}();
6 {{keyword|case}} 1..5:
7 {{function|case1_5}}(); // This one will run
8
9 {{function|break}}();
10 }
switch(@value){
case 1:
code1();
case 2:
break();
default:
defaultCode();
}

1 {{function|switch}}(@value){
2 {{keyword|case}} 1:
3 {{function|code1}}();
4 {{keyword|case}} 2:
5 {{function|break}}();
6 {{keyword|default}}:
7 {{function|defaultCode}}();
8 }
switch(@v){
case 1:
msg('1');
case 2:
msg('2');
}

1 {{function|switch}}(@v){
2 {{keyword|case}} 1:
3 {{function|msg}}('1');
4 {{keyword|case}} 2:
5 {{function|msg}}('2');
6 }
msg('1')
. We might expect that the code
simply won't message anything at all if @v is 1. This is incorrect. Due to the way fallthroughs work, it will simply change it to a combined case 1 and 2. We can
add a bit more code to ensure that this won't happen:
switch(@v){
case 1:
msg('1');
break();
case 2:
msg('2');
break();
}

1 {{function|switch}}(@v){
2 {{keyword|case}} 1:
3 {{function|msg}}('1');
4 {{function|break}}();
5 {{keyword|case}} 2:
6 {{function|msg}}('2');
7 {{function|break}}();
8 }
msg('1')
, as expected, nothing happens when @v is 1.
switch
also has a pure functional syntax, but it is not recommended for use in new code.
{{LearningTrail}}
Find a bug in this page? Edit this page yourself, then submit a pull request.