Types & Variables
Quartz is a dynamically-typed language, meaning you don't need to declare types explicitly. However, understanding the type system helps you write better code.
Primitive Types
Integers
Whole numbers, positive or negative:
let count = 42
let negative = -17
let zero = 0
let big = 1000000
Floating-Point Numbers (Doubles)
Numbers with decimal points:
let pi = 3.14159
let temperature = -40.5
let tiny = 0.0001
let scientific = 1.5e10 // 1.5 × 10^10
Booleans
True or false values:
let isActive = true
let isEmpty = false
// Boolean expressions
let isAdult = age >= 18
let canDrive = hasLicense && isAdult
Strings
Text enclosed in double quotes:
let name = "Quartz"
let message = "Hello, World!"
let empty = ""
// String concatenation
let greeting = "Hello, " + name + "!"
// Escape sequences
let newline = "Line 1\nLine 2"
let tab = "Column1\tColumn2"
let quote = "She said \"Hello\""
Null
Represents absence of a value:
let nothing = null
// Check for null
if (value == null) {
io.println("No value")
}
Composite Types
Arrays
Ordered collections of values:
// Create arrays
let numbers = [1, 2, 3, 4, 5]
let names = ["Alice", "Bob", "Charlie"]
let mixed = [1, "two", 3.0, true]
let empty = []
// Access by index (0-based)
let first = numbers[0] // 1
let second = numbers[1] // 2
// Modify elements
numbers[0] = 10
// Array length
let size = len(numbers) // 5
// Nested arrays
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
let center = matrix[1][1] // 5
Dictionaries
Key-value collections:
// Create dictionaries
let person = {
"name": "Alice",
"age": 30,
"city": "Boston"
}
// Access by key
let name = person["name"]
// Modify values
person["age"] = 31
// Add new keys
person["email"] = "alice@example.com"
// Nested dictionaries
let company = {
"name": "TechCorp",
"employees": {
"ceo": "John",
"cto": "Jane"
}
}
let ceo = company["employees"]["ceo"]
Variable Declaration
The let Keyword
Declare variables with let:
let name = "Quartz"
let count = 0
let items = []
Assignment
Assign new values with =:
let x = 10
x = 20 // Reassignment
x = x + 1 // Increment
Compound Assignment
Shorthand operators for modification:
let x = 10
x += 5 // x = x + 5 → 15
x -= 3 // x = x - 3 → 12
x *= 2 // x = x * 2 → 24
x /= 4 // x = x / 4 → 6
x %= 4 // x = x % 4 → 2
Multiple Variables
let a = 1
let b = 2
let c = 3
// Or on separate lines with context
let name = "Alice"
let age = 30
let email = "alice@example.com"
Type Conversion
Built-in Conversion Functions
// String to integer
let numStr = "42"
let num = int(numStr) // 42
// String to float
let piStr = "3.14"
let pi = double(piStr) // 3.14
// Number to string
let n = 42
let s = str(n) // "42"
// Boolean conversion
let b = bool(1) // true
let b2 = bool(0) // false
let b3 = bool("") // false
let b4 = bool("hello") // true
Type Checking
import system.runtime as rt
let value = 42
// Check type
if (rt.typeOf(value) == "int") {
io.println("It's an integer!")
}
// Type name
io.println(rt.typeOf("hello")) // "string"
io.println(rt.typeOf([1, 2, 3])) // "array"
io.println(rt.typeOf({"a": 1})) // "dict"
Operators
Arithmetic Operators
| Operator | Description | Example | Result |
|---|---|---|---|
| `+` | Addition | `5 + 3` | `8` |
| `-` | Subtraction | `5 - 3` | `2` |
| `*` | Multiplication | `5 * 3` | `15` |
| `/` | Division | `7 / 2` | `3.5` |
| `%` | Modulo | `7 % 3` | `1` |
Comparison Operators
| Operator | Description | Example | Result |
|---|---|---|---|
| `==` | Equal | `5 == 5` | `true` |
| `!=` | Not equal | `5 != 3` | `true` |
| `<` | Less than | `3 < 5` | `true` |
| `>` | Greater than | `5 > 3` | `true` |
| `<=` | Less or equal | `5 <= 5` | `true` |
| `>=` | Greater or equal | `5 >= 3` | `true` |
Logical Operators
| Operator | Description | Example | Result |
|---|---|---|---|
| `&&` | Logical AND | `true && false` | `false` |
| `||` | Logical OR | `true || false` | `true` |
| `!` | Logical NOT | `!true` | `false` |
String Operator
// String concatenation with +
let full = "Hello" + " " + "World" // "Hello World"
// Concatenate with other types (auto-converts to string)
let msg = "Count: " + 42 // "Count: 42"
Variable Scope
Variables are scoped to their enclosing block:
let global = "I'm global"
fn example() {
let local = "I'm local"
if (true) {
let blockScoped = "I'm in a block"
io.println(global) // Works
io.println(local) // Works
io.println(blockScoped) // Works
}
// io.println(blockScoped) // Error: not in scope
}
// io.println(local) // Error: not in scope
Shadowing
Inner scope can shadow outer variables:
let x = 10
fn example() {
let x = 20 // Shadows outer x
io.println(x) // 20
}
example()
io.println(x) // 10 (unchanged)
Constants by Convention
Quartz doesn't have a const keyword. Use SCREAMING_CASE by convention:
let MAX_SIZE = 100
let PI = 3.14159
let APP_NAME = "MyApp"
// These are still technically mutable, but by convention
// SCREAMING_CASE signals "don't modify this"
Next: Control Flow →