Skip to content

Data Types

EverSharp is dynamically typed, meaning variables don't have declared types. The type of a value is determined at runtime. This guide covers all eight data types in EverSharp.


Overview

Type Description Example
decimal All numeric values 42, 3.14, -100.5
string Text values "Hello", "World"
boolean True/false values true, false
null Absence of value null
DateTime Date and time $Now(), $ToDate("2024/01/15")
DateOnly Date without time $ToDateOnly("2024/01/15")
Instance Objects/dictionaries { "name": "John", "age": 30 }
InstanceArray Arrays [1, 2, 3], $Array(1, 2, 3)

Decimal (Numbers)

All numbers in EverSharp are represented as decimal (128-bit precision).

Literals

// Integers
age = 42;
count = 1000;
negative = -50;

// Decimals
rate = 0.15;
pi = 3.14159;
precise = 0.0001;

// Large numbers
population = 8000000000;

Operations

// Arithmetic
sum = 10 + 20; // 30
difference = 50 - 15; // 35
product = 6 * 7; // 42
quotient = 100 / 4; // 25
remainder = 17 % 5; // 2

// Compound assignment
value = 10;
value += 5; // 15
value -= 3; // 12
value *= 2; // 24
value /= 4; // 6
value %= 4; // 2

// Increment/decrement
counter = 5;
old = counter++; // old=5, counter=6
old = counter--; // old=6, counter=5

Comparison

a = 10;
b = 20;

a < b; // true
a > b; // false
a <= 10; // true
a >= 10; // true
a == 10; // true
a != 20; // true

Type Characteristics

  • No integer vs float distinction: All numbers are decimal
  • High precision: 128-bit decimal type
  • No scientific notation: Cannot write 1e6 or 1.5e-3
  • No hexadecimal: Cannot write 0xFF
  • Default value: Variables default to null, not 0

String

Strings represent text values. They must be enclosed in double quotes.

Literals

// Simple strings
name = "John Doe";
message = "Hello, World!";
empty = "";

// With escape sequences
path = "C:\\Users\\Documents"; // Backslash
quote = 'He said, "Hello"'; // Quote
multiline = "Line 1\nLine 2\nLine 3"; // Newline
tabbed = "Column1\tColumn2"; // Tab

Concatenation

firstName = "John";
lastName = "Doe";
fullName = firstName + " " + lastName; // "John Doe"

// With numbers (converts to string)
age = 30;
message = "Age: " + age; // "Age: 30"

Comparison

// Equality
"hello" == "hello"; // true
"Hello" == "hello"; // false (case-sensitive)
"abc" != "xyz"; // true

// Lexicographic comparison
"apple" < "banana"; // true
"zebra" > "apple"; // true

Instance Methods

Strings have several built-in methods:

text = "Hello, World!";

// Case conversion
upper = text.ToUpper(); // "HELLO, WORLD!"
lower = text.ToLower(); // "hello, world!"

// Trimming
padded = "  hello  ";
trimmed = padded.Trim(); // "hello"

// Splitting
csv = "apple,banana,orange";
fruits = csv.Split(","); // ["apple", "banana", "orange"]

// Substring operations
text.StartsWith("Hello"); // true
text.EndsWith("World!"); // true
text.Contains("World"); // true

// Replacement
replaced = text.Replace("World", "EverSharp"); // "Hello, EverSharp!"

// Conversion
number = "123.45".ToNumber(); // 123.45 (decimal)
str = text.ToString(); // "Hello, World!" (identity)

Type Characteristics

  • Double quotes only: Single quotes are not valid
  • No string interpolation: Must use concatenation
  • Immutable: Methods return new strings
  • Case-sensitive: "Hello" ≠ "hello"

Boolean

Booleans represent true/false values.

Literals

isActive = true;
hasErrors = false;

Logical Operations

// AND (both must be true)
true && true; // true
true && false; // false
false && false; // false

// OR (at least one must be true)
true || false; // true
false || true; // true
false || false; // false

// NOT (inverts value)
!true; // false
!false; // true

// Combined
isEligible = age >= 18 && hasLicense && !isExpired;

From Comparisons

age = 25;
isAdult = age >= 18; // true

premium = 1200;
isAffordable = premium <= 1000; // false

name = "John";
isJohn = name == "John"; // true

Short-Circuit Evaluation

// AND: right side not evaluated if left is false
result = false && expensiveFunction(); // expensiveFunction() NOT called

// OR: right side not evaluated if left is true
result = true || expensiveFunction(); // expensiveFunction() NOT called

// Useful for null checks
if (person != null && person.age > 18) {
  // person.age only accessed if person is not null
}

Truthiness

EverSharp has strict boolean semantics:

// CORRECT: Explicit comparisons
if (count > 0) {
}
if (name != null) {
}
if (name != "") {
}

// WRONG: Cannot use non-boolean in conditions
// if (count) { }          // ERROR
// if (name) { }           // ERROR

Null

Represents the absence of a value.

Literal

value = null;

Default Value

Variables auto-initialize to null:

x; // null (uninitialized)
y = null; // null (explicit)

Null Checks

person = null;

// Check if null
if (person == null) {
  $Log("Person is null");
}

// Check if not null
if (person != null) {
  name = person.name;
}

// Safe property access
if (policy != null && policy.customer != null) {
  customerName = policy.customer.name;
}

Null Behavior

// Cannot access properties on null
person = null;
// name = person.name;     // ERROR: RuntimeException

// Cannot call methods on null
// upper = person.ToUpper();  // ERROR: RuntimeException

// Can compare
person == null; // true
person != null; // false

// Can pass as argument
$Log(person); // Logs "null"

// Can return from functions
function getValue() {
  return null;
}

DateTime

Represents date and time values.

Creation

// Current date/time
now = $Now(); // Current UTC time
today = $Today(); // Today at midnight (00:00:00)

// Parse from string
date1 = $ToDate("2024/01/15");
date2 = $ToDate("2024/01/15 14:30:00");
utcDate = $ToDateUTC("2024/01/15 14:30:00");

Date Arithmetic

startDate = $ToDate("2024/01/15");

// Add time
nextWeek = $AddDays(startDate, 7);
nextMonth = $AddMonths(startDate, 1);
nextYear = $AddYears(startDate, 1);
later = $AddHours(startDate, 3);
later = $AddMinutes(startDate, 30);
later = $AddSeconds(startDate, 45);

// Date boundaries
start = $StartOfDay(now); // 00:00:00
end = $EndOfDay(now); // 23:59:59

Date Comparison

date1 = $ToDate("2024/01/15");
date2 = $ToDate("2024/12/31");

date1 < date2; // true
date1 > date2; // false
date1 == date1; // true
date1 != date2; // true

Date Differences

startDate = $ToDate("2020/01/01");
endDate = $ToDate("2024/01/01");

years = $DifferenceInYears(startDate, endDate); // -4
days = $DifferenceInDays(startDate, endDate); // -1461
hours = $DifferenceInHours(startDate, endDate); // -35064
minutes = $DifferenceInMinutes(startDate, endDate); // -2103840
seconds = $DifferenceInSeconds(startDate, endDate); // -126230400

Extracting Components

date = $ToDate("2024/03/15 14:30:00");

year = $Year(date); // 2024
month = $Month(date); // 3
day = $Day(date); // 15

Formatting

date = $Today();
formatted = $ToShortDateString(date); // Format to short string

Timezone Conversion

utcTime = $Now();
localTime = $ConvertTimeFromUtc(utcTime, "Eastern Standard Time");
abbr = $GetTimeZoneAbbreviation("Eastern Standard Time", localTime);

DateOnly

Represents a date without time component.

Creation

dateOnly = $ToDateOnly("2024/01/15");

Use Cases

// Birth dates (no time needed)
birthDate = $ToDateOnly("1990/05/20");

// Expiration dates
expiryDate = $ToDateOnly("2025/12/31");

// Comparison
today = $ToDateOnly($Today());
if (expiryDate < today) {
  $Log("Expired");
}

Instance (Objects)

Objects are collections of key-value pairs (dictionaries).

Creation

// Simple object
person = {
  name: "John Doe",
  age: 30,
  active: true,
};

// Nested objects
policy = {
  number: "POL-12345",
  premium: 1500,
  customer: {
    name: "Alice",
    email: "alice@example.com",
    address: {
      city: "Boston",
      state: "MA",
    },
  },
};

// Empty object
empty = {};

Property Access

// Read properties
name = person.name; // "John Doe"
age = person.age; // 30

// Nested access
city = policy.customer.address.city; // "Boston"

// Set properties
person.age = 31;
person.email = "john@example.com";

// Add new properties
person.phone = "555-1234";

Dynamic Property Access

// Using $GetValue/$SetValue
name = $GetValue(person, "name");
$SetValue(person, "age", 32);

// Add property dynamically
person.AddProperty("country", "USA");

Iteration Pattern

// Objects don't have built-in iteration
// Store keys separately if needed
keys = ["name", "age", "email"];
i = 0;
while (i < keys.Length) {
  key = keys[i];
  value = $GetValue(person, key);
  $Log("{0}: {1}", key, value);
  i++;
}

Type Characteristics

  • Keys must be strings: Always quoted in literals
  • Trailing comma not allowed: { "a": 1, } is invalid
  • No methods (except AddProperty, ToString)
  • Mutable: Properties can be added/modified

InstanceArray (Arrays)

Arrays are ordered collections of values.

Creation

// Array literal
numbers = [1, 2, 3, 4, 5];
names = ["Alice", "Bob", "Charlie"];
mixed = [42, "hello", true, null];
empty = [];

// Nested arrays
matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9],
];

// Array of objects
people = [
  { name: "John", age: 30 },
  { name: "Jane", age: 25 },
  { name: "Bob", age: 35 },
];

// Using $Array function
numbers = $Array(1, 2, 3, 4, 5);

Indexing

numbers = [10, 20, 30, 40, 50];

// Zero-based access
first = numbers[0]; // 10
second = numbers[1]; // 20
last = numbers[4]; // 50

// Set elements
numbers[2] = 99; // [10, 20, 99, 40, 50]

// Dynamic index
index = 3;
value = numbers[index]; // 40

Length Property

numbers = [1, 2, 3, 4, 5];
len = numbers.Length; // 5

// Access last element
last = numbers[numbers.Length - 1]; // 5

Array Methods

Arrays have extensive built-in methods. See Native Functions - Arrays for complete list.

Common operations:

numbers = [1, 2, 3, 4, 5];

// Filter
evens = numbers.Filter((x) => x % 2 == 0); // [2, 4]

// Map
doubled = numbers.Map((x) => x * 2); // [2, 4, 6, 8, 10]

// Reduce
sum = numbers.ReduceToNum((acc, x) => acc + x, 0); // 15

// Find
first = numbers.Find((x) => x > 3); // 4

// Sort
sorted = $Sort($Array(3, 1, 4, 2)); // [1, 2, 3, 4]

// Reverse
reversed = numbers.Reverse(); // [5, 4, 3, 2, 1]

Mutation methods:

arr = [1, 2, 3];

// Add elements
arr.Push(4); // [1, 2, 3, 4]
arr.AddRange($Array(5, 6)); // [1, 2, 3, 4, 5, 6]
arr.Insert(0, 0); // [0, 1, 2, 3, 4, 5, 6]

// Remove elements
arr.Remove(3); // [0, 1, 2, 4, 5, 6]
arr.RemoveAt(0); // [1, 2, 4, 5, 6]
arr.Clear(); // []

Working with Objects

people = [
  { name: "John", age: 30 },
  { name: "Jane", age: 25 },
  { name: "Bob", age: 35 },
];

// Filter by property
adults = people.Filter((p) => p.age >= 18);

// Extract property
names = people.Map((p) => p.name); // ["John", "Jane", "Bob"]

// Sort by property
byAge = people.OrderBy((p) => p.age);

// Find by property
john = people.Find((p) => p.name == "John");

Type Conversion

EverSharp does not perform implicit type conversions (except string concatenation).

Explicit Conversions

// String to number
num = "123.45".ToNumber(); // 123.45
num = $ToNumber("456"); // 456

// Number to string
str = $ToString(123); // "123"

// String to date
date = $ToDate("2024/01/15");
dateOnly = $ToDateOnly("2024/01/15");
utcDate = $ToDateUTC("2024/01/15 10:00");

// Any to string
str = value.ToString(); // Works on most types
json = $Stringify(object); // JSON representation

Type Checking Patterns

// Check for null
if (value != null) {
  // Process value
}

// Check array length
if (array.Length > 0) {
  first = array[0];
}

// Check string empty
if (text != "" && text != null) {
  // Process text
}

Dynamic Typing Examples

Variables can hold any type:

// Same variable, different types
value = 42; // number
value = "hello"; // now string
value = true; // now boolean
value = [1, 2, 3]; // now array
value = { key: "value" }; // now object
value = null; // now null

Function parameters are dynamically typed:

function process(input) {
  // input can be any type
  if (input != null) {
    result = input.ToString();
    $Log(result);
  }
}

process(42); // Logs "42"
process("hello"); // Logs "hello"
process([1, 2, 3]); // Logs "[1,2,3]"

Best Practices

  1. Check types at runtime: Use comparison and method availability
  2. Handle null explicitly: Always check != null before property access
  3. Use appropriate conversion functions: Don't rely on implicit conversions
  4. Be aware of string concatenation: + with strings converts other operand
  5. Use type-appropriate methods: .ToNumber() for strings, .Filter() for arrays

Next Steps