Variables & Data Types
Flowa is a dynamically-typed language where variables can hold any type and change at runtime.
Variable Declaration
All variables are declared with the let keyword:
let name = "Alice";
let age = 30;
let pi = 3.14159;
let active = true;
let data = null;Variable Rules
- Must start with a letter or underscore
- Can contain letters, digits, underscores
- Case-sensitive (
myVar≠myvar) - Cannot use reserved keywords
Reserved Keywords
let, func, if, else, while, for, return, true, false, null, break, continueData Types
Strings
Strings are sequences of characters enclosed in double quotes:
let greeting = "Hello, World!";
let multiline = "Line 1
Line 2
Line 3";
let empty = "";String Operations
// Concatenation
let first = "Hello";
let last = "World";
let combined = first + " " + last; // "Hello World"
// Length
let length = len("Hello"); // 5
// Case conversion
let upper_str = upper("hello"); // "HELLO"
let lower_str = lower("WORLD"); // "world"
// Substring extraction
let str = "Hello, World!";
let sub = substring(str, 0, 5); // "Hello"
// Contains check
let has_world = contains(str, "World"); // true
// Trim whitespace
let trimmed = trim(" hello "); // "hello"
// Check prefix/suffix
let starts = startsWith("Hello", "He"); // true
let ends = endsWith("Hello", "lo"); // true
// Get character at index
let char = charAt("Hello", 1); // "e"
// Replace
let replaced = replace("Hello World", "World", "Flowa"); // "Hello Flowa"
// Split
let parts = split("a,b,c", ","); // ["a", "b", "c"]Numbers
Flowa supports both integers and floating-point numbers:
let integer = 42;
let negative = -10;
let float_num = 3.14159;
let scientific = 1.5e10;Arithmetic Operations
let a = 10;
let b = 3;
let add = a + b; // 13
let sub = a - b; // 7
let mul = a * b; // 30
let div = a / b; // 3.333...
let mod = a % b; // 1 (modulo/remainder)Math funcs
// Power
let pow_result = power(2, 8); // 256
// Square root
let sqrt_val = sqrt(16); // 4
// Rounding
let floor_val = floor(3.7); // 3
let ceil_val = ceil(3.2); // 4
let round_val = round(3.5); // 4
// Absolute value
let abs_val = abs(-5); // 5
// Min/Max
let min_val = min(10, 5); // 5
let max_val = max(10, 5); // 10Booleans
Boolean values represent true or false:
let is_active = true;
let is_completed = false;Boolean Operations
let x = true;
let y = false;
// Logical AND
let and_result = x && y; // false
// Logical OR
let or_result = x || y; // true
// Logical NOT
let not_result = !x; // falseComparison Operators
let a = 5;
let b = 10;
let eq = a == b; // false (equal)
let neq = a != b; // true (not equal)
let lt = a < b; // true (less than)
let lte = a <= b; // true (less than or equal)
let gt = a > b; // false (greater than)
let gte = a >= b; // false (greater than or equal)Null
null represents the absence of a value:
let empty_value = null;
if (empty_value == null) {
print("Value is null");
}Arrays
Arrays are ordered collections of values:
// Empty array
let arr = [];
// Array with values
let numbers = [1, 2, 3, 4, 5];
// Mixed types
let mixed = [1, "two", 3.0, true, null];Array Access
let numbers = [10, 20, 30, 40, 50];
// Access by index (0-based)
let first = numbers[0]; // 10
let third = numbers[2]; // 30
// Modify elements
numbers[1] = 25; // [10, 25, 30, 40, 50]Array Operations
let arr = [1, 2, 3];
// Add element to end
arr = push(arr, 4); // [1, 2, 3, 4]
// Remove last element
let last = pop(arr); // 4, arr = [1, 2, 3]
// Remove first element
let first = shift(arr); // 1, arr = [2, 3]
// Reverse array
let reversed = reverse([1, 2, 3]); // [3, 2, 1]
// Sort array
let sorted = sort([3, 1, 4, 1, 5]); // [1, 1, 3, 4, 5]
// Slice (extract portion)
let numbers = [1, 2, 3, 4, 5];
let subset = slice(numbers, 1, 3); // [2, 3]
// Check if includes value
let has_three = includes([1, 2, 3], 3); // true
// Find index of value
let idx = indexOf([1, 2, 3, 2], 2); // 1 (first occurrence)
// Get length
let length = len(arr);
// Join array
let joined = join(["a", "b", "c"], "-"); // "a-b-c"Hashes (Objects/Dictionaries)
Hashes store key-value pairs:
// Empty hash
let hash = {};
// Hash with values
let person = {
"name": "Alice",
"age": 30,
"city": "New York"
};Important: Always use quoted strings for hash keys.
Hash Access
let person = {
"name": "Bob",
"age": 25,
"email": "bob@example.com"
};
// Access values
let name = person["name"]; // "Bob"
let age = person["age"]; // 25
// Modify values
person["age"] = 26;
// Add new keys
person["phone"] = "555-1234";Nested Hashes
let user = {
"name": "Alice",
"address": {
"street": "123 Main St",
"city": "Boston",
"zip": "02101"
},
"contacts": {
"email": "alice@example.com",
"phone": "555-5678"
}
};
// Access nested values
let city = user["address"]["city"]; // "Boston"
let email = user["contacts"]["email"]; // "alice@example.com"Type Conversion
To Number
let str = "42";
let num = tonumber(str); // 42
let invalid = tonumber("abc"); // Returns null or 0To String
let num = 42;
let str = tostring(num); // "42"
let bool = true;
let str2 = tostring(bool); // "true"Type Checking
let value = "hello";
let type_name = type(value); // "string"
// Possible return values:
// "string", "number", "boolean", "array", "hash", "func", "null"
if (type(value) == "string") {
print("It's a string!");
}Variable Scope
Global Scope
Variables declared outside funcs are global:
let global_var = "I'm global";
func test() {
print(global_var); // Can access global
}
test();Local Scope
Variables declared inside funcs are local:
func test_scope() {
let local_var = "I'm local";
print(local_var);
}
test_scope();
// print(local_var); // ERROR - out of scopeClosure
funcs can capture variables from outer scopes:
func create_counter() {
let count = 0;
func increment() {
count = count + 1;
return count;
}
return increment;
}
let counter = create_counter();
print(counter()); // 1
print(counter()); // 2
print(counter()); // 3Best Practices
Meaningful Names
// Good
let user_count = 10;
let is_active = true;
let total_price = 99.99;
// Avoid
let x = 10;
let flag = true;
let temp = 99.99;Initialize Variables
// Good
let count = 0;
let items = [];
let user = {};
// Avoid uninitialized variables
let data; // undefined behaviorUse Appropriate Types
// Use arrays for collections
let numbers = [1, 2, 3, 4, 5];
// Use hashes for structured data
let user = {
"id": 123,
"name": "Alice",
"email": "alice@example.com"
};
// Use null for absent values
let optional_value = null;Examples
Working with User Data
let user = {
"id": 1,
"username": "alice",
"email": "alice@example.com",
"age": 30,
"is_active": true,
"tags": ["developer", "admin"],
"preferences": {
"theme": "dark",
"language": "en"
}
};
// Access and modify
print("User: " + user["username"]);
user["age"] = user["age"] + 1;
user["tags"] = push(user["tags"], "moderator");
// Type checking
if (type(user["tags"]) == "array") {
print("Tags count: " + tostring(len(user["tags"])));
}Data Processing
let prices = [19.99, 29.99, 39.99, 49.99];
let total = 0;
let i = 0;
while (i < len(prices)) {
total = total + prices[i];
i = i + 1;
}
print("Total: $" + tostring(total));
print("Average: $" + tostring(total / len(prices)));Next Steps
- Control Flow - Learn about if/else, loops, and more
- funcs - Explore funcs and closures
- Control Flow - Learn about if/else, loops, and more
- funcs - Explore funcs and closures