# Purp Language Specification

**Version 1.0**

Purp is a modern, readable programming language designed to be easy to learn yet powerful enough for advanced applications.

---

## Table of Contents

1. [Syntax Basics](#1-syntax-basics)
2. [Data Types](#2-data-types)
3. [Variables & Constants](#3-variables--constants)
4. [Operators](#4-operators)
5. [Control Flow](#5-control-flow)
6. [Functions](#6-functions)
7. [Classes & Objects](#7-classes--objects)
8. [Collections](#8-collections)
9. [Error Handling](#9-error-handling)
10. [Modules](#10-modules)
11. [Built-in Functions](#11-built-in-functions)

---

## 1. Syntax Basics

### Comments
```purp
-- This is a single-line comment

--- 
This is a 
multi-line comment
---
```

### Statement Termination
- No semicolons required
- One statement per line
- Use `\` for line continuation

### Blocks
All blocks end with `end`:
```purp
if condition
    -- code here
end

define my_function()
    -- code here
end

class MyClass
    -- code here
end
```

### Indentation
- Indentation is recommended for readability but not enforced
- Use consistent indentation (4 spaces recommended)

---

## 2. Data Types

### Primitive Types

| Type | Description | Examples |
|------|-------------|----------|
| `number` | Integer or float | `42`, `3.14`, `-17` |
| `text` | String | `"hello"`, `'world'` |
| `bool` | Boolean | `true`, `false` |
| `nothing` | Null/None | `nothing` |

### Type Checking
```purp
type(42)        -- returns "number"
type("hello")   -- returns "text"
type(true)      -- returns "bool"
type(nothing)   -- returns "nothing"
```

---

## 3. Variables & Constants

### Variable Declaration
Use `is` to declare and assign:
```purp
name is "Alice"
age is 25
price is 19.99
active is true
```

### Constants
Use `always` for immutable values:
```purp
PI always is 3.14159
MAX_SIZE always is 100
```

### Reassignment
```purp
count is 0
count is count + 1  -- reassign
```

### Naming Rules
- Start with letter or underscore
- Can contain letters, numbers, underscores
- Case-sensitive
- Convention: `snake_case` for variables, `PascalCase` for classes

---

## 4. Operators

### Arithmetic
```purp
a + b       -- addition
a - b       -- subtraction
a * b       -- multiplication
a / b       -- division
a % b       -- modulo (remainder)
a ^ b       -- power/exponent
-a          -- negation
```

### Comparison
```purp
a == b      -- equal
a != b      -- not equal
a < b       -- less than
a > b       -- greater than
a <= b      -- less than or equal
a >= b      -- greater than or equal
```

### Logical
```purp
a and b     -- logical AND
a or b      -- logical OR
not a       -- logical NOT
```

### String
```purp
a + b       -- concatenation: "hello" + "world" = "helloworld"
a * n       -- repeat: "ab" * 3 = "ababab"
```

### Assignment
```purp
x is 5      -- assign
x += 1      -- add and assign
x -= 1      -- subtract and assign
x *= 2      -- multiply and assign
x /= 2      -- divide and assign
```

---

## 5. Control Flow

### If Statement
```purp
if condition
    -- code
end

if condition
    -- code
else
    -- code
end

if condition1
    -- code
else if condition2
    -- code
else
    -- code
end
```

### Match Statement (Switch)
```purp
match value
    when 1
        say "one"
    when 2
        say "two"
    when 3, 4, 5
        say "three, four, or five"
    else
        say "other"
end
```

### For Loops
```purp
-- Range-based
for i from 1 to 10
    say i
end

-- With step
for i from 0 to 100 by 10
    say i
end

-- Countdown
for i from 10 to 1 by -1
    say i
end

-- Collection iteration
for item in collection
    say item
end

-- With index
for index, item in collection
    say "{index}: {item}"
end
```

### While Loop
```purp
while condition
    -- code
end
```

### Loop Control
```purp
break       -- exit loop
continue    -- skip to next iteration
```

---

## 6. Functions

### Basic Definition
```purp
define greet()
    say "Hello!"
end

define greet(name)
    say "Hello, {name}!"
end
```

### Return Values
```purp
define add(a, b)
    return a + b
end

result is add(3, 4)  -- result is 7
```

### Default Parameters
```purp
define greet(name is "World")
    say "Hello, {name}!"
end

greet()          -- "Hello, World!"
greet("Alice")   -- "Hello, Alice!"
```

### Multiple Return Values
```purp
define min_max(numbers)
    return min(numbers), max(numbers)
end

low, high is min_max([3, 1, 4, 1, 5])
```

### Anonymous Functions (Lambdas)
```purp
double is (x) -> x * 2
add is (a, b) -> a + b

numbers.map((x) -> x * 2)
```

### First-Class Functions
```purp
define apply(func, value)
    return func(value)
end

result is apply((x) -> x * 2, 5)  -- result is 10
```

---

## 7. Classes & Objects

### Basic Class
```purp
class Person
    has name
    has age
    
    does greet()
        say "Hi, I'm {name}!"
    end
end

alice is new Person("Alice", 25)
alice.greet()
```

### Constructor
```purp
class Rectangle
    has width
    has height
    
    create(w, h)
        width is w
        height is h
    end
    
    does area()
        return width * height
    end
end

rect is new Rectangle(10, 5)
say rect.area()  -- 50
```

### Inheritance
```purp
class Animal
    has name
    
    does speak()
        say "..."
    end
end

class Dog extends Animal
    does speak()
        say "{name} says Woof!"
    end
    
    does fetch()
        say "{name} fetches the ball!"
    end
end

dog is new Dog("Rex")
dog.speak()   -- "Rex says Woof!"
```

### Getters and Setters
```purp
class Circle
    has _radius
    
    get radius
        return _radius
    end
    
    set radius(value)
        if value < 0
            raise "Radius cannot be negative"
        end
        _radius is value
    end
    
    get area
        return 3.14159 * _radius ^ 2
    end
end
```

### Static Members
```purp
class Math
    shared PI is 3.14159
    
    shared does square(n)
        return n * n
    end
end

say Math.PI
say Math.square(5)
```

---

## 8. Collections

### Lists
```purp
-- Creation
numbers is [1, 2, 3, 4, 5]
empty is []
mixed is [1, "two", true, nothing]

-- Access
first is numbers[0]
last is numbers[-1]

-- Modification
numbers[0] is 10
numbers.push(6)
numbers.pop()
numbers.insert(0, 0)
numbers.remove(3)

-- Properties
length is numbers.length

-- Slicing
first_three is numbers[0:3]
last_two is numbers[-2:]

-- Methods
numbers.reverse()
numbers.sort()
numbers.contains(3)     -- true/false
index is numbers.find(3)
```

### Maps (Dictionaries)
```purp
-- Creation
person is {
    name: "Alice",
    age: 25,
    city: "NYC"
}

-- Access
name is person["name"]
name is person.name      -- dot notation

-- Modification
person["email"] is "alice@example.com"
person.phone is "555-1234"

-- Check key exists
if person.has("email")
    say person.email
end

-- Get keys/values
keys is person.keys()
values is person.values()

-- Remove
person.remove("age")
```

### Sets
```purp
colors is set(["red", "green", "blue"])
colors.add("yellow")
colors.remove("red")
colors.contains("blue")  -- true
```

### Ranges
```purp
one_to_ten is 1..10
zero_to_hundred is 0..100

for i in 1..5
    say i
end
```

---

## 9. Error Handling

### Try/Catch
```purp
try
    result is risky_operation()
catch error
    say "Error: {error}"
end
```

### Finally
```purp
try
    file is open("data.txt")
    process(file)
catch error
    say "Error: {error}"
finally
    file.close()
end
```

### Raising Errors
```purp
define divide(a, b)
    if b == 0
        raise "Cannot divide by zero"
    end
    return a / b
end
```

### Custom Error Types
```purp
class ValidationError extends Error
    has field
    has message
end

raise new ValidationError("email", "Invalid email format")
```

---

## 10. Modules

### Importing
```purp
use math                    -- import entire module
use math.sqrt               -- import specific function
use math.{sqrt, sin, cos}   -- import multiple
use math as m               -- alias

use "./helpers"             -- local file
use "./utils/string_utils"  -- nested path
```

### Exporting
```purp
-- In helpers.purp

define helper_function()
    -- code
end

private define internal_function()
    -- not exported
end

class HelperClass
    -- code
end
```

### Module Structure
```
my_project/
├── main.purp
├── utils/
│   ├── math.purp
│   └── strings.purp
└── models/
    ├── user.purp
    └── product.purp
```

---

## 11. Built-in Functions

### Output
```purp
say "Hello"                 -- print with newline
say "Value: {x}"           -- string interpolation
write "No newline"         -- print without newline
```

### Input
```purp
name is ask "What's your name? "
age is ask "How old are you? " as number
```

### Type Conversion
```purp
number("42")       -- 42
number("3.14")     -- 3.14
text(42)           -- "42"
bool(1)            -- true
bool(0)            -- false
list("abc")        -- ["a", "b", "c"]
```

### Math Functions
```purp
abs(-5)            -- 5
round(3.7)         -- 4
floor(3.7)         -- 3
ceil(3.2)          -- 4
min(1, 2, 3)       -- 1
max(1, 2, 3)       -- 3
sum([1, 2, 3])     -- 6
sqrt(16)           -- 4
pow(2, 8)          -- 256
random()           -- random float 0-1
random(1, 10)      -- random int 1-10
```

### String Functions
```purp
length("hello")           -- 5
upper("hello")            -- "HELLO"
lower("HELLO")            -- "hello"
trim("  hello  ")         -- "hello"
split("a,b,c", ",")       -- ["a", "b", "c"]
join(["a", "b"], "-")     -- "a-b"
replace("hello", "l", "L") -- "heLLo"
starts_with("hello", "he") -- true
ends_with("hello", "lo")   -- true
contains("hello", "ell")   -- true
```

### Collection Functions
```purp
length(collection)        -- size/count
empty(collection)         -- true if empty
first(collection)         -- first element
last(collection)          -- last element
reverse(collection)       -- reversed copy
sort(collection)          -- sorted copy
unique(collection)        -- remove duplicates
zip(list1, list2)         -- combine lists
map(list, func)           -- transform each
filter(list, func)        -- filter by condition
reduce(list, func, init)  -- reduce to single value
```

### File Operations
```purp
content is read_file("data.txt")
write_file("out.txt", content)
append_file("log.txt", message)
exists("file.txt")        -- true/false
delete("file.txt")
files is list_dir("./")
```

---

## Reserved Keywords

```
is, always, has, does, new, end, if, else, match, when,
for, from, to, by, in, while, break, continue, 
define, return, class, extends, get, set, shared, create,
try, catch, finally, raise, use, as, private,
true, false, nothing, and, or, not
```

---

## Style Guide

### Naming Conventions
- Variables/functions: `snake_case`
- Classes: `PascalCase`
- Constants: `UPPER_SNAKE_CASE`
- Private members: `_leading_underscore`

### Best Practices
1. Use meaningful, descriptive names
2. Keep functions short and focused
3. Use comments to explain "why", not "what"
4. Prefer `else if` over deeply nested `if`s
5. Handle errors explicitly
