Doing math
Adama lets you do math, and that's awesome! It has the typical operations that you would expect, and then some fun twists. So, let's get into it.
Operators
Parentheses: ( expr )
You can wrap any expression with parentheses, and parentheses will alter the precedence of evaluation. See operator precedence section for details about operator precedence.
Sample Code
public int z;
@construct {
z = (1 + 2) * 3;
}
Result
{"z":6}
Typing: The resulting type is the type of the sub-expression.
Unary numeric negation: - expr
When you want to turn a positive into a negative, a negative into a positive, a smile into a frown, a frown upside down, or reflect a value over the y-axis. This is done with the subtract symbol prefixing any expression.
Sample Code
public int z;
public formula neg_z = -z;
@construct {
z = 42;
}
Result
{"z":42,"neg_z":-42}
Typing: The sub-expression type must be an int, long, or double. The resulting type is the type of the sub-expression.
Unary boolean negation / not / logical compliment: ! expr
Turn false into true, and true into false. This is the power of the unary Not operator using the exclamation point !. Money back if it doesn't invert those boolean values!
Sample Code
public bool a;
public formula not_a = !a;
@construct {
a = true;
}
Result
{"a":true,"not_a":false}
Typing: The sub-expression type must be a bool, and the resulting type is also bool.
Addition: expr + expr
You'll need to use addition to count the phat stacks of money you'll earn with a computer science degree.
Sample Code
public int a;
public formula b = a + 10;
public formula c = b + 100;
@construct {
a = 1;
}
Result
{"a":1,"b":11,"c":111}
Typing: The addition operator is commonly used to add two numbers, but it can also be used with strings and lists. The following table summarizes the typing and behavior:
left type | right type | result type | behavior |
---|---|---|---|
int | int | int | integer addition |
double | double | double | floating point addition |
double | int | double | floating point addition |
int | double | double | floating point addition |
long | long | long | integer addition |
long | int | long | integer addition |
int | long | long | integer addition |
string | string | string | concatenation |
int | string | string | concatenation |
long | string | string | concatenation |
double | string | string | concatenation |
bool | string | string | concatenation |
string | int | string | concatenation |
string | long | string | concatenation |
string | double | string | concatenation |
string | bool | string | concatenation |
list<int> | int | list<int> | integer addition on each element |
list<int> | long | list<long> | integer addition on each element |
list<int> | double | list<double> | floating point addition on each element |
list<long> | int | list<int> | integer addition on each element |
list<long> | long | list<long> | integer addition on each element |
list<double> | int | list<double> | floating point addition on each element |
list<double> | double | list<double> | floating point addition on each element |
list<string> | int | list<string> | concatenation on each element |
list<string> | long | list<string> | concatenation on each element |
list<string> | double | list<string> | concatenation on each element |
list<string> | bool | list<string> | concatenation on each element |
Subtraction: expr - expr
You'll need the subtract operator to remove taxes from your phat stack of dolla-bills.
Sample Code
public int a;
public formula b = a - 10;
public formula c = b - 100;
@construct {
a = 1000;
}
Result
{"a":1000,"b":990,"c":890}
Typing:
The subtraction operator is commonly used to subtract a number from another number, but it can also be used with lists. The following table summarizes the typing and behavior.
left type | right type | result type | behavior |
---|---|---|---|
int | int | int | integer subtraction |
int | double | double | floating point subtraction |
double | double | double | floating point subtraction |
double | int | double | floating point subtraction |
long | int | int | integer subtraction |
long | long | long | integer subtraction |
int | long | int | integer subtraction |
list<int> | int | list<int> | integer subtraction on each element |
list<int> | long | list<long> | integer subtraction on each element |
list<int> | double | list<double> | floating point subtraction on each element |
list<long> | int | list<int> | integer subtraction on each element |
list<long> | long | list<long> | integer subtraction on each element |
list<double> | int | list<double> | floating point subtraction on each element |
list<double> | double | list<double> | floating point subtraction on each element |
Multiplication: expr * expr
TODO: something pithy about multiplication.
Sample Code
public int a;
public formula b = a * 2;
public formula c = b * 3;
@construct {
a = 7;
}
Result
{"a":7,"b":14,"c":42}
Typing: TODO | int | int | int | integer subtraction | | int | double | double | floating point subtraction | | double | double | double | floating point subtraction | | double | int | double | floating point subtraction | | long | int | int | integer subtraction | | long | long | long | integer subtraction | | int | long | int | integer subtraction |
Division: expr / expr
TODO: something pithy about division.
Sample Code
public double a;
public formula b = a / 2;
public formula c = b / 10;
@construct {
a = 20;
}
Result
{"a":20.0,"b":10.0,"c":1.0}
Typing:
In Adama, division always results in a maybe<> due to a division by zero.
left type | right type | result type |
---|---|---|
int | int | maybe |
double | int | maybe |
int | double | maybe |
double | double | maybe |
Modulus: expr % expr
TODO: something pithy about Modulus and remainders.
Sample Code
public int a;
public formula b = a % 2;
public formula c = a % 4;
@construct {
a = 7;
}
Result
{"a":7,"b":1,"c":3}
Typing: The left and right side must be integral (i.e. int or long), and the result is integral as well. The following table summarizes the logic precisely.
left type | right type | result type |
---|---|---|
int | int | int |
long | int | int |
int | long | int |
long | long | long |
Less than: expr < expr
TODO: something pithy
Sample Code
public int a;
public int b;
public formula cmp1 = a < b;
public formula cmp2 = b < a;
@construct {
a = 1;
b = 2;
}
Result
{"a":1,"b":2,"cmp1":true,"cmp2":false}
Typing: The left and right must be comparable, and the resulting type is always bool. The following table outlines comparability
left type | right type |
---|---|
int | int |
int | long |
int | double |
long | int |
long | long |
long | double |
double | int |
double | long |
double | double |
string | string |
TODO: do maybes play into this?
Greater than: expr > expr
TODO: something pithy
Sample Code
public int a;
public int b;
public formula cmp1 = a > b;
public formula cmp2 = b > a;
@construct {
a = 1;
b = 2;
}
Result
{"a":1,"b":2,"cmp1":false,"cmp2":true}
Typing: This has the same typing as <
Less than or equal to: expr <= expr
TODO: something pithy
Sample Code
public int a;
public int b;
public formula cmp1 = a <= b;
public formula cmp2 = b <= a;
public formula cmp3 = a + 1 <= b;
@construct {
a = 1;
b = 2;
}
Result
{"a":1,"b":2,"cmp1":true,"cmp2":false,"cmp3":true}
Typing: This has the same typing as <
Greater than or equal to: expr >= expr
TODO: something pithy
Sample Code
public int a;
public int b;
public formula cmp1 = a >= b;
public formula cmp2 = b >= a;
public formula cmp3 = a + 1 >= b;
@construct {
a = 1;
b = 2;
}
Typing: This has the same typing as <
Result
{"a":1,"b":2,"cmp1":false,"cmp2":true,"cmp3":true}
Equality: expr == expr
TODO: something pithy
Sample Code
public int a;
public int b;
public formula eq1 = a == b;
public formula eq2 = a + 1 == b;
@construct {
a = 1;
b = 2;
}
Result
{"a":1,"b":2,"eq1":false,"eq2":true}
Typing: If a left and right type are comparable (see table under <), then the types can be tested for equality. The resulting type is a bool. Beyond comparable left and right types, the following table
Inequality: expr != expr
TODO: something pithy
Sample Code
public int a;
public int b;
public formula neq1 = a != b;
public formula neq2 = a + 1 != b;
@construct {
a = 1;
b = 2;
}
Result
{"a":1,"b":2,"neq1":true,"neq2":false}
Typing: This has the same typing as =;
Logical and: expr && expr
TODO: something pithy
Truth Table
left | right | result |
---|---|---|
false | false | false |
true | false | false |
false | true | false |
true | true | true |
Sample Code
public bool a;
public bool b;
public formula and = a && b;
@construct {
a = true;
b = false;
}
Result
{"a":true,"b":false,"and":false}
Typing: The left and right expressions must have a type of bool, and the resulting type is bool.
Logical or: expr || expr
TODO: something pithy
Truth Table
left | right | result |
---|---|---|
false | false | false |
true | false | true |
false | true | true |
true | true | true |
Sample Code
public bool a;
public bool b;
public formula or = a || b;
@construct {
a = true;
b = false;
}
Result
{"a":true,"b":false,"or":true}
Typing: The left and right expressions must have a type of bool, and the resulting type is bool.
Conditional / Ternary: expr ? expr : expr
Sample Code
public bool cond;
public formula inline = a ? 5 : 10;
@construct {
cond = true;
}
Result
{"cond":true,"inline":5}
Typing: The first expression must have a type of bool, and the second and third type must be the compatible under type rectification. The result is the rectified type. For more information about type rectification, see anonymous messages and arrays.
Operator precedence
When multiple operators operate on different operands (i.e. things), the order of operators (or operator precedence) is used to break ambiguities such that the final result is deterministic. This avoids confusion, and operators with a higher level must evaluate first.
When there are multiple operators at the same level, then an associativity rule indicates how to evaluate those operations. Typically, this is left to right, but some operators may not be associative or be right to left.
level | operator(s) | description | associativity |
---|---|---|---|
11 | expr._ident expr[expr] exprF(expr0,...,exprN) (expr) | field dereference index lookup functional application parentheses | left to right |
10 | expr++ expr-- | post-increment post-decrement | not associative |
9 | ++expr --expr | pre-increment pre-decrement | not associative |
8 | -expr !expr | unary negation | not associative |
7 | expr*expr expr/expr expr%expr | multiply divide modulo | left to right |
6 | expr+expr expr-expr | addition subtraction | left to right |
5 | expr<expr expr>expr expr<=expr expr>=expr | less than greater than less than or equal to greater than or equal to | not associative |
4 | expr==expr expr!=expr | equality inequality | not associative |
3 | expr&&expr | logical and | left to right |
2 | expr||expr | logical or | left to right |
1 | expr?expr:_expr | inline conditional / ternary | right to left |