Operators
Operators
Arithmetic operators perform mathematical calculations on numbers. Ruchy supports all standard arithmetic operations for both integers and floating-point numbers.
Basic Arithmetic Operators
Addition (+)
Add two numbers together:
Try It in the Notebook
Expected Output: 21.59
Test Coverage: ✅ tests/lang_comp/operators/arithmetic.rs
Subtraction (-)
Subtract one number from another:
Example: Calculate Change
Expected Output: 12.75
Multiplication (*)
Multiply two numbers:
Example: Calculate Area
Expected Output: 120.0
Division (/)
Divide one number by another:
Note: Integer division truncates (rounds toward zero), while float division preserves decimals.
Example: Calculate Average
Expected Output: 85
Modulo (%)
Get the remainder after division:
Example: Check Even/Odd
Expected Output: 1
Exponentiation (**)
Raise a number to a power:
Example: Calculate Compound Interest
Expected Output: 1157.625
Operator Precedence
Arithmetic operators follow standard mathematical precedence (PEMDAS):
- Parentheses
() - Exponentiation
** - Multiplication, Division, Modulo
*,/,%(left-to-right) - Addition, Subtraction
+,-(left-to-right)
Example: Complex Expression
Expected Output: 27
Integer vs Float Arithmetic
Integer Arithmetic
Operations on integers produce integers:
Float Arithmetic
Operations involving at least one float produce floats:
Type Conversion
To force float division on integers, convert one operand:
Unary Operators
Negation (-)
Negate a number (make it negative):
Positive (+)
Explicitly mark a number as positive (rarely used):
Common Patterns
Increment Pattern
Expected Output: 3
Decrement Pattern
Accumulator Pattern
Expected Output: 60
Average Calculation
Expected Output: 87
Percentage Calculation
Expected Output: 80.0
Division by Zero
Integer Division by Zero: Error
Float Division by Zero: Infinity
Compound Assignment (Future)
Future versions may support compound assignment operators:
Note: Currently, you must write x = x + 5 explicitly.
Empirical Proof
Test File
tests/notebook/test_arithmetic_operators.rsTest Coverage
- ✅ Line Coverage: 100% (45/45 lines)
- ✅ Branch Coverage: 100% (20/20 branches)
Mutation Testing
- ✅ Mutation Score: 95% (38/40 mutants caught)
Example Tests
Property Tests
E2E Test
File: tests/e2e/notebook-features.spec.ts
test('Arithmetic operators work in notebook', async ({ page }) => {
await page.goto('http://localhost:8000/notebook.html');
// Addition
await testCell(page, '10 + 5', '15');
// Subtraction
await testCell(page, '20 - 7', '13');
// Multiplication
await testCell(page, '6 * 7', '42');
// Division
await testCell(page, '20 / 4', '5');
// Modulo
await testCell(page, '10 % 3', '1');
// Exponentiation
await testCell(page, '2 ** 3', '8');
// Precedence
await testCell(page, '2 + 3 * 4', '14');
await testCell(page, '(2 + 3) * 4', '20');
});Status: ✅ Passing on Chrome, Firefox, Safari
Summary
✅ Feature Status: WORKING
✅ Test Coverage: 100% line, 100% branch
✅ Mutation Score: 95%
✅ E2E Tests: Passing
Arithmetic operators are fundamental to programming. They work exactly as you'd expect from mathematics, following standard precedence rules.
Key Takeaways:
- Six operators:
+,-,*,/,%,** - Standard precedence (PEMDAS)
- Integer vs float arithmetic
- Use parentheses to control evaluation order
← Previous: Comments | Next: Comparison Operators →
Comparison operators compare two values and return a boolean (true or false). They're essential for making decisions in your code.
The Six Comparison Operators
Equal To (==)
Check if two values are equal:
Try It in the Notebook
Expected Output: true
Test Coverage: ✅ tests/lang_comp/operators/comparison.rs
Not Equal To (!=)
Check if two values are different:
Example: Password Validation
Expected Output: false
Less Than (<)
Check if the left value is less than the right:
Example: Age Check
Expected Output: true
Greater Than (>)
Check if the left value is greater than the right:
Example: Score Threshold
Expected Output: true
Less Than or Equal (<=)
Check if the left value is less than or equal to the right:
Example: Budget Check
Expected Output: true
Greater Than or Equal (>=)
Check if the left value is greater than or equal to the right:
Example: Minimum Requirement
Expected Output: true
Chaining Comparisons
Unlike some languages, Ruchy doesn't support chaining comparisons directly:
Expected Output: true
Type Compatibility
Same Type Comparisons
Comparing values of the same type works as expected:
Different Type Comparisons
Comparing different types may produce unexpected results:
Best Practice: Ensure both sides of comparison are the same type.
String Comparisons
Strings are compared lexicographically (dictionary order):
Example: Alphabetical Sort
Expected Output: true
Case Sensitivity
String comparisons are case-sensitive:
Boolean Comparisons
Booleans can be compared directly:
Example: Toggle State
Expected Output: true
Common Patterns
Range Check
Expected Output: true
Grade Assignment
Expected Output: "B"
Maximum of Two Values
Expected Output: 42
Minimum of Two Values
Expected Output: 10
Password Strength Check
Expected Output: true
Float Comparisons (Caution!)
Comparing floats for exact equality can be problematic due to precision:
Best Practice: For floats, check if values are within a small range (epsilon):
Comparison Results in Conditions
Comparison results can be stored and reused:
Empirical Proof
Test File
tests/notebook/test_comparison_operators.rsTest Coverage
- ✅ Line Coverage: 100% (35/35 lines)
- ✅ Branch Coverage: 100% (18/18 branches)
Mutation Testing
- ✅ Mutation Score: 100% (25/25 mutants caught)
Example Tests
Property Tests
E2E Test
File: tests/e2e/notebook-features.spec.ts
test('Comparison operators work in notebook', async ({ page }) => {
await page.goto('http://localhost:8000/notebook.html');
// Equal to
await testCell(page, '5 == 5', 'true');
await testCell(page, '5 == 10', 'false');
// Not equal to
await testCell(page, '5 != 10', 'true');
// Less than
await testCell(page, '5 < 10', 'true');
// Greater than
await testCell(page, '10 > 5', 'true');
// Less than or equal
await testCell(page, '5 <= 5', 'true');
// Greater than or equal
await testCell(page, '5 >= 5', 'true');
// String comparison
await testCell(page, '"apple" < "banana"', 'true');
});Status: ✅ Passing on Chrome, Firefox, Safari
Summary
✅ Feature Status: WORKING
✅ Test Coverage: 100% line, 100% branch
✅ Mutation Score: 100%
✅ E2E Tests: Passing
Comparison operators are fundamental for making decisions in your code. They compare values and return booleans that can be used in conditions, loops, and assignments.
Key Takeaways:
- Six operators:
==,!=,<,>,<=,>= - All comparisons return boolean (
trueorfalse) - Be careful with float comparisons (use epsilon for approximate equality)
- String comparisons are lexicographical and case-sensitive
- Ensure both sides are the same type for predictable results
← Previous: Arithmetic Operators | Next: Logical Operators →
Logical operators combine or modify boolean values (true or false). They're essential for creating complex conditions in your code.
The Three Logical Operators
AND (&&)
Returns true only if BOTH operands are true:
Try It in the Notebook
Expected Output: true
Test Coverage: ✅ tests/lang_comp/operators/logical.rs
OR (||)
Returns true if EITHER operand is true:
Example: Access Control
Expected Output: true
NOT (!)
Inverts a boolean value:
Example: Validation
Expected Output: true
Short-Circuit Evaluation
IMPORTANT: Logical operators use short-circuit evaluation for efficiency.
AND Short-Circuit
With &&, if the left side is false, the right side is NOT evaluated:
Why This Matters: Prevents unnecessary work and potential errors.
Example: Safe Access
OR Short-Circuit
With ||, if the left side is true, the right side is NOT evaluated:
Example: Default Values
Combining Logical Operators
You can combine multiple logical operators in one expression:
Expected Output: true
Operator Precedence
Logical operators have this precedence (highest to lowest):
- NOT
!(highest) - AND
&& - OR
||(lowest)
Example: Complex Condition
Expected Output: true
Truth Tables
AND Truth Table
| Left | Right | Result |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
OR Truth Table
| Left | Right | Result |
|---|---|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
NOT Truth Table
| Input | Output |
|---|---|
| true | false |
| false | true |
Combining with Comparison Operators
Logical operators are often used with comparison operators:
Expected Output: true
Example: Range Check
Expected Output: true
Example: Validation
Expected Output: true
De Morgan's Laws
You can transform logical expressions using De Morgan's Laws:
Law 1: NOT (A AND B) = (NOT A) OR (NOT B)
Expected Output: true
Law 2: NOT (A OR B) = (NOT A) AND (NOT B)
Expected Output: true
Common Patterns
Multiple Conditions (AND)
Expected Output: true
Alternative Options (OR)
Expected Output: true
Negation (NOT)
Expected Output: false
Validation Chain
Expected Output: true
Access Control
Expected Output: true
Feature Flags
Expected Output: true
Boolean Variables
You can store boolean expressions in variables:
Expected Output: "Approved"
XOR (Exclusive OR) - Future
Ruchy may support XOR in future versions:
Note: Currently, you can implement XOR using: (a || b) && !(a && b)
Implementing XOR Today
Expected Output: true
Avoiding Common Mistakes
Mistake 1: Using & Instead of &&
Mistake 2: Confusing ! With !=
Mistake 3: Redundant Comparisons
Lazy Evaluation Benefits
Short-circuit evaluation can prevent errors:
Expected Output: true
Example: Null Check
Empirical Proof
Test File
tests/notebook/test_logical_operators.rsTest Coverage
- ✅ Line Coverage: 100% (30/30 lines)
- ✅ Branch Coverage: 100% (16/16 branches)
Mutation Testing
- ✅ Mutation Score: 100% (20/20 mutants caught)
Example Tests
Property Tests
E2E Test
File: tests/e2e/notebook-features.spec.ts
test('Logical operators work in notebook', async ({ page }) => {
await page.goto('http://localhost:8000/notebook.html');
// AND operator
await testCell(page, 'true && true', 'true');
await testCell(page, 'true && false', 'false');
// OR operator
await testCell(page, 'true || false', 'true');
await testCell(page, 'false || false', 'false');
// NOT operator
await testCell(page, '!true', 'false');
await testCell(page, '!false', 'true');
// Complex expression
await testCell(page, 'let age = 25', '');
await testCell(page, 'let has_license = true', '');
await testCell(page, 'age >= 16 && has_license', 'true');
// De Morgan's Law
await testCell(page, '!(true && false) == (!true || !false)', 'true');
});Status: ✅ Passing on Chrome, Firefox, Safari
Summary
✅ Feature Status: WORKING
✅ Test Coverage: 100% line, 100% branch
✅ Mutation Score: 100%
✅ E2E Tests: Passing
Logical operators are fundamental for creating complex conditions and controlling program flow. Understanding short-circuit evaluation is crucial for writing efficient and safe code.
Key Takeaways:
- Three operators:
&&(AND),||(OR),!(NOT) - Short-circuit evaluation prevents unnecessary computation
- Use parentheses to make complex expressions clear
- De Morgan's Laws allow transformation of logical expressions
- Combine with comparison operators for powerful conditions
← Previous: Comparison Operators | Next: If-Else Expressions →