Skip to main content

Arithmetic Expressions

Arithmetic expressions in Wolf DSL enable mathematical calculations, numeric transformations, and quantitative analysis. They support all standard mathematical operations with automatic type conversion and null safety.

Supported Operations

OperatorOperationExampleResult
+Addition5 + 38
-Subtraction10 - 46
*Multiplication7 * 642
/Division15 / 35
%Modulus (Remainder)17 % 52
^Exponentiation (Power)2 ^ 38

Basic Arithmetic Operations

Schema MathOperations {
number value1
number value2
number addition
number subtraction
number multiplication
number division
number modulus
number power
}

Mapping performCalculations input MathOperations output MathOperations {
MathOperations.addition = MathOperations.value1 + MathOperations.value2
MathOperations.subtraction = MathOperations.value2 - MathOperations.value1
MathOperations.multiplication = MathOperations.value1 * MathOperations.value2
MathOperations.division = MathOperations.value1 / MathOperations.value2
MathOperations.modulus = MathOperations.value1 % MathOperations.value2
MathOperations.power = MathOperations.value2 ^ MathOperations.value1
}

// Input: { value1: 8, value2: 3 }
// Output:
// {
// "addition": 11,
// "subtraction": -5,
// "multiplication": 24,
// "division": 2.67,
// "modulus": 2,
// "power": 9
// }

Order of Operations (Precedence)

Wolf DSL follows standard mathematical precedence rules:

  1. Parentheses () - Highest priority
  2. Exponentiation ^
  3. Multiplication and Division *, / (left to right)
  4. Addition and Subtraction +, - (left to right)

Precedence Examples

Schema PrecedenceExamples {
number result1
number result2
number result3
number result4
number result5
}

Mapping demonstratePrecedence output PrecedenceExamples {
// Standard precedence
PrecedenceExamples.result1 = 2 + 3 * 4 // = 14 (not 20)
PrecedenceExamples.result2 = 10 - 6 / 2 // = 7 (not 2)
PrecedenceExamples.result3 = 2 ^ 3 * 4 // = 32 (8 * 4)

// Using parentheses to override precedence
PrecedenceExamples.result4 = (2 + 3) * 4 // = 20
PrecedenceExamples.result5 = 10 - (6 / 2) // = 7 (same as above)
}

// Output:
// {
// "result1": 14,
// "result2": 7,
// "result3": 32,
// "result4": 20,
// "result5": 7
// }

Working with Different Number Types

Integer vs Decimal Operations

Schema NumericTypes {
number wholeNumber1
number wholeNumber2
number decimal1
number decimal2
number integerDivision
number decimalDivision
number mixedOperation
}

Mapping handleNumericTypes input NumericTypes output NumericTypes {
// Integer operations
NumericTypes.integerDivision = 10 / 3 // = 3.33 (automatic decimal)

// Decimal operations
NumericTypes.decimalDivision = 10.5 / 2.5 // = 4.2

// Mixed operations
NumericTypes.mixedOperation = 10.5 + 5 // = 15.5 (int promoted to decimal)
}

String to Number Conversion

Wolf DSL automatically converts strings to numbers in arithmetic contexts:

Schema StringConversion {
string numberString1
string numberString2
number result1
number result2
number result3
}

Mapping convertStrings input StringConversion output StringConversion {
// Automatic string-to-number conversion
StringConversion.result1 = StringConversion.numberString1 + 10 // "25" + 10 = 35
StringConversion.result2 = StringConversion.numberString1 * 2 // "25" * 2 = 50
StringConversion.result3 = StringConversion.numberString1 + StringConversion.numberString2 // "25" + "15" = 40
}

// Input: { numberString1: "25", numberString2: "15" }
// Output: { result1: 35, result2: 50, result3: 40 }

Real-World Examples

E-commerce Price Calculations

Schema OrderCalculation {
number itemPrice
number quantity
number taxRate
number discountPercent
number shippingCost
number subtotal
number discountAmount
number taxableAmount
number taxAmount
number totalAmount
string formattedTotal
}

Mapping calculateOrderTotal input OrderCalculation output OrderCalculation {
// Calculate subtotal
OrderCalculation.subtotal = OrderCalculation.itemPrice * OrderCalculation.quantity

// Calculate discount
OrderCalculation.discountAmount = OrderCalculation.subtotal *
(OrderCalculation.discountPercent / 100)

// Calculate taxable amount (after discount)
OrderCalculation.taxableAmount = OrderCalculation.subtotal - OrderCalculation.discountAmount

// Calculate tax
OrderCalculation.taxAmount = OrderCalculation.taxableAmount * (OrderCalculation.taxRate / 100)

// Calculate final total
OrderCalculation.totalAmount = OrderCalculation.taxableAmount +
OrderCalculation.taxAmount +
OrderCalculation.shippingCost

// Format for display
OrderCalculation.formattedTotal = currencyFormat(OrderCalculation.totalAmount)
}

// Input: { itemPrice: 50, quantity: 3, taxRate: 8.5, discountPercent: 10, shippingCost: 5.99 }
// Calculation:
// subtotal: 50 * 3 = 150
// discount: 150 * 0.1 = 15
// taxableAmount: 150 - 15 = 135
// tax: 135 * 0.085 = 11.48
// total: 135 + 11.48 + 5.99 = 152.47

Financial Calculations

Schema LoanCalculator {
number principal
number annualRate
number years
number monthlyRate
number numPayments
number monthlyPayment
number totalInterest
number totalPayment
}

Mapping calculateLoan input LoanCalculator output LoanCalculator {
// Convert annual rate to monthly and years to payments
LoanCalculator.monthlyRate = LoanCalculator.annualRate / 12 / 100
LoanCalculator.numPayments = LoanCalculator.years * 12

// Calculate monthly payment using loan formula
// M = P * (r(1+r)^n) / ((1+r)^n - 1)
rateCompound = (1 + LoanCalculator.monthlyRate) ^ LoanCalculator.numPayments
LoanCalculator.monthlyPayment = LoanCalculator.principal *
(LoanCalculator.monthlyRate * rateCompound) /
(rateCompound - 1)

// Calculate totals
LoanCalculator.totalPayment = LoanCalculator.monthlyPayment * LoanCalculator.numPayments
LoanCalculator.totalInterest = LoanCalculator.totalPayment - LoanCalculator.principal
}

// Input: { principal: 200000, annualRate: 4.5, years: 30 }
// Monthly Payment: ~$1,013.37
// Total Interest: ~$164,813.42

Statistical Calculations

Schema StatisticsCalculator {
number[] values
number count
number sum
number average
number variance
number standardDeviation
number min
number max
number range
}

Mapping calculateStatistics input StatisticsCalculator output StatisticsCalculator {
// Basic statistics
StatisticsCalculator.count = length(StatisticsCalculator.values)
StatisticsCalculator.sum = sum(StatisticsCalculator.values, value -> value)
StatisticsCalculator.average = StatisticsCalculator.sum / StatisticsCalculator.count

// Min and Max (using sorting)
sortedValues = sort(StatisticsCalculator.values, value)
StatisticsCalculator.min = sortedValues[0]
StatisticsCalculator.max = sortedValues[-1]
StatisticsCalculator.range = StatisticsCalculator.max - StatisticsCalculator.min

// Variance calculation: Σ(x - μ)² / n
squaredDifferences = map(
StatisticsCalculator.values,
value -> (value - StatisticsCalculator.average) ^ 2
)
StatisticsCalculator.variance = sum(squaredDifferences, diff -> diff) / StatisticsCalculator.count

// Standard deviation: variance
StatisticsCalculator.standardDeviation = StatisticsCalculator.variance ^ 0.5
}

Error Handling and Edge Cases

Division by Zero and Invalid Operations

Schema SafeArithmetic {
number dividend
number divisor
number safeQuotient
number safePower
number safeModulus
}

Mapping performSafeOperations input SafeArithmetic output SafeArithmetic {
// Safe division
SafeArithmetic.safeQuotient = if SafeArithmetic.divisor != 0
then SafeArithmetic.dividend / SafeArithmetic.divisor
else 0 // or some default value

// Safe power operations
SafeArithmetic.safePower = if SafeArithmetic.dividend >= 0
then SafeArithmetic.dividend ^ 0.5 // Square root
else 0 // Handle negative numbers

// Safe modulus
SafeArithmetic.safeModulus = if SafeArithmetic.divisor != 0
then SafeArithmetic.dividend % SafeArithmetic.divisor
else SafeArithmetic.dividend
}

Null Value Handling

Schema NullSafeArithmetic {
number value1
number value2
number safeSum
number safeProduct
number fallbackResult
}

Mapping handleNulls input NullSafeArithmetic output NullSafeArithmetic {
// Null-safe operations (nulls are treated as 0)
NullSafeArithmetic.safeSum = NullSafeArithmetic.value1 + NullSafeArithmetic.value2
NullSafeArithmetic.safeProduct = NullSafeArithmetic.value1 * NullSafeArithmetic.value2

// Explicit null handling
NullSafeArithmetic.fallbackResult = if NullSafeArithmetic.value1 != null && NullSafeArithmetic.value2 != null
then NullSafeArithmetic.value1 + NullSafeArithmetic.value2
else 0
}

Best Practices

1. Use Parentheses for Complex Expressions

//  Good: Clear and readable
total = (basePrice * quantity) + (taxRate * basePrice * quantity) + shippingCost

// Confusing: Hard to understand precedence
total = basePrice * quantity + taxRate * basePrice * quantity + shippingCost

2. Break Complex Calculations into Steps

//  Good: Step-by-step calculation
subtotal = itemPrice * quantity
discountAmount = subtotal * discountRate
taxAmount = (subtotal - discountAmount) * taxRate
finalTotal = subtotal - discountAmount + taxAmount

// Hard to debug: Everything in one line
finalTotal = (itemPrice * quantity) - ((itemPrice * quantity) * discountRate) +
(((itemPrice * quantity) - ((itemPrice * quantity) * discountRate)) * taxRate)

3. Handle Edge Cases

//  Good: Safe division
average = if count > 0 then total / count else 0
percentage = if total > 0 then (completed / total) * 100 else 0

// Dangerous: No error handling
average = total / count // Could divide by zero

4. Use Meaningful Intermediate Variables

//  Good: Descriptive variable names
monthlyInterestRate = annualRate / 12 / 100
numberOfPayments = loanTermYears * 12
compoundFactor = (1 + monthlyInterestRate) ^ numberOfPayments

// Unclear: Generic variable names
r = rate / 12 / 100
n = years * 12
cf = (1 + r) ^ n

Arithmetic expressions in Wolf DSL provide powerful mathematical capabilities for financial calculations, statistical analysis, and numeric data processing, all while maintaining Wolf DSL's declarative clarity and safety.