# Your First GocciaScript Program

*For developers who know JavaScript and want to learn GocciaScript — a guided walkthrough from hello world to a multi-file async program.*

## Executive Summary

- **Familiar syntax** — GocciaScript is modern JavaScript minus the quirks; `.js` files, no transpilation needed
- **Key differences** — No `var`, `function`, traditional `for` loops, or `while` loops by default; use `let`/`const`, arrow functions, strict equality, `for...of`/array methods
- **Full walkthrough** — Variables, arrow functions, arrays, objects, classes, modules, async/await
- **Next steps** — Links to language restrictions, built-in API reference, and example programs

## What is GocciaScript?

GocciaScript is a subset of JavaScript implemented in FreePascal. It strips away the quirks of early ECMAScript by default — `var`, `function`, loose equality, `eval`, traditional `for` loops, and `while` loops — and keeps the modern parts: arrow functions, classes with private fields, async/await, modules, and implicit strict mode. If you've written modern JavaScript, you already know most of GocciaScript.

## Prerequisites

You need the [FreePascal](https://www.freepascal.org/) compiler (`fpc`):

```bash
# macOS
brew install fpc

# Ubuntu/Debian
sudo apt-get install fpc

# Windows
choco install freepascal
```

Clone the repository and build the script loader:

```bash
git clone https://github.com/frostney/GocciaScript.git
cd GocciaScript
./build.pas loader
```

This produces `build/GocciaScriptLoader`, the command you'll use to run every script in this tutorial.

## Hello, World

Create a file called `hello.js`:

```javascript
const message = "Hello from GocciaScript!";
console.log(message);
```

Run it:

```bash
./build/GocciaScriptLoader hello.js
```

You should see:

```text
Hello from GocciaScript!
```

That's it — GocciaScript files are plain `.js` files. No special extension, no transpilation step.

## Variables

GocciaScript has two variable declarations: `let` (mutable) and `const` (immutable). There is no `var`.

```javascript
const name = "Alice";
let score = 0;

score = score + 10;
console.log(`${name} scored ${score} points`);
// Alice scored 10 points
```

Attempting to reassign a `const` throws an error:

```javascript
const x = 5;
x = 10; // TypeError: Assignment to constant variable
```

## Arrow Functions

GocciaScript uses arrow functions exclusively. The `function` keyword does not exist.

```javascript
// Single expression — implicit return
const double = (n) => n * 2;

// Block body — explicit return
const greet = (name) => {
  const greeting = `Hello, ${name}!`;
  return greeting;
};

console.log(double(21));       // 42
console.log(greet("World"));   // Hello, World!
```

Arrow functions capture their surrounding scope's `this` — there's no `this` rebinding. For methods that need their own `this`, use shorthand method syntax inside classes or object literals.

## Working with Arrays

GocciaScript keeps traditional `for` loops and `while` loops off by default. Use array methods and `for...of` for new code:

```javascript
const numbers = [1, 2, 3, 4, 5];

// Transform with map
const doubled = numbers.map((n) => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// Filter
const evens = numbers.filter((n) => n % 2 === 0);
console.log(evens); // [2, 4]

// Reduce
const sum = numbers.reduce((total, n) => total + n, 0);
console.log(sum); // 15

// Iterate with for...of
for (const n of numbers) {
  console.log(n);
}
```

All the modern array methods you'd expect are available: `find`, `findLast`, `some`, `every`, `flat`, `flatMap`, `at`, `toSorted`, `toReversed`, and more. See the [Built-in Objects](built-ins.md) reference for the full list.

## Objects

Object literals work like JavaScript, including shorthand properties, computed keys, and methods:

```javascript
const x = 10;
const y = 20;

const point = {
  x,
  y,
  distanceTo(other) {
    const dx = this.x - other.x;
    const dy = this.y - other.y;
    return Math.sqrt(dx ** 2 + dy ** 2);
  },
};

const origin = { x: 0, y: 0 };
console.log(point.distanceTo(origin)); // 22.360679774997898
```

Note that the `distanceTo` method uses shorthand method syntax (`distanceTo() { ... }`), not an arrow function. This is important: shorthand methods receive the call-site `this` (the object they're called on), while arrow functions inherit `this` from their enclosing scope.

## Classes

Classes support constructors, private fields, getters, setters, static methods, and inheritance:

Private names are validated at parse time: using an undeclared `#name` is a `SyntaxError`. Getter-only and setter-only private accessors also follow normal accessor semantics, so invalid writes or reads throw `TypeError`. Private static names are brand-checked against the actual class receiver, so inherited static calls like `Derived.methodFromBase()` cannot read or write `Base`'s private static state through `this`.

```javascript
class CoffeeShop {
  #name = "Goccia Coffee";
  #beans = ["Arabica", "Robusta", "Ethiopian"];
  #prices = { espresso: 2.5, latte: 4.0, cappuccino: 3.75 };

  getMenu() {
    return this.#beans.map((bean) => `${bean} blend`);
  }

  calculateTotal(order) {
    return order.reduce((total, item) => total + (this.#prices[item] ?? 0), 0);
  }

  get name() {
    return this.#name;
  }
}

const shop = new CoffeeShop();
console.log(`Welcome to ${shop.name}!`);
console.log("Menu:", shop.getMenu());

const order = ["espresso", "latte"];
console.log(`Total: $${shop.calculateTotal(order).toFixed(2)}`);
```

Inheritance uses `extends` and `super`:

```javascript
class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    return `${this.name} makes a sound`;
  }
}

class Dog extends Animal {
  speak() {
    return `${this.name} barks`;
  }
}

const dog = new Dog("Rex");
console.log(dog.speak());            // Rex barks
console.log(dog instanceof Animal);  // true
```

## Modules

GocciaScript supports ES-style default, named, and namespace imports and exports. Project examples prefer named exports for internal modules because explicit import names make refactors easier to review; default exports are supported when a module intentionally exposes a primary value or interoperates with code that uses default exports.

Create a file called `math.js`:

```javascript
export const add = (a, b) => a + b;
export const multiply = (a, b) => a * b;
```

Import it from another file called `app.js` in the same directory:

```javascript
import { add, multiply } from "./math.js";

console.log(add(2, 3));       // 5
console.log(multiply(4, 5));  // 20
```

Run the entry point:

```bash
./build/GocciaScriptLoader app.js
```

You can also rename imports with `as`:

```javascript
import { add as sum } from "./math.js";
console.log(sum(1, 2)); // 3
```

Or import the full namespace object when you want all exports under one binding:

```javascript
import * as math from "./math.js";
import * as config from "./config.json";

console.log(math.add(2, 3));   // 5
console.log(config.version);   // top-level JSON/TOML/YAML keys are namespace properties
```

Named imports and exports also support string-literal export names when a module exposes a name that is not a valid identifier:

```javascript
import { "foo-bar" as fooBar } from "./config.json";
import { "0" as firstDoc } from "./multi.yaml";

const localValue = 42;
export { localValue as "0" };
```

And re-export from one module to another:

```javascript
export { add, multiply } from "./math.js";
```

## Async/Await

Async functions and `await` work as you'd expect from modern JavaScript:

```javascript
const fetchUser = async (id) => {
  const result = await Promise.resolve({ id, name: "Alice" });
  return result;
};

const main = async () => {
  const user = await fetchUser(1);
  console.log(`User: ${user.name}`);
};

main();
```

Promises are fully supported — `.then()`, `.catch()`, `.finally()`, `Promise.all()`, `Promise.race()`, `Promise.any()`, `Promise.allSettled()`, and `Promise.withResolvers()`.

GocciaScript uses a synchronous microtask queue: all pending `.then()` callbacks are drained after synchronous code completes.

## Strict Equality by Default

GocciaScript uses strict equality by default. Use `===` and `!==` for predictable comparisons:

```javascript
console.log(1 === 1);     // true
console.log(1 === "1");   // false
console.log(null === undefined); // false
```

The loose equality operators (`==` and `!=`) are available only in compatibility mode with `--compat-loose-equality`.

## What's Different from JavaScript

Here's a quick reference of GocciaScript's key restrictions:

| JavaScript | GocciaScript | Alternative |
|------------|-------------|-------------|
| `var x = 1` | Not supported | `let x = 1` or `const x = 1` |
| `function foo() {}` | Not supported | `const foo = () => {}` |
| `==` / `!=` | Off by default | `===` / `!==` or `--compat-loose-equality` |
| `for (init; test; update)` | Off by default | `for...of`, `.map()`, `.forEach()`, `.reduce()`, or `--compat-traditional-for-loop` for JavaScript compatibility |
| `while (...)` / `do ... while (...)` | Off by default | `for...of`, `.map()`, `.forEach()`, `.reduce()`, or `--compat-while-loops` for JavaScript compatibility |
| `eval("code")` | Not supported | No alternative (by design) |
| `arguments` | Off by default | Prefer rest parameters (`...args`) or Script-source `--compat-non-strict-mode` |
| sloppy assignment failures | Strict by default | Script-source `--compat-non-strict-mode` when porting code that expects failed property writes to be ignored |
| sloppy function `this` | Strict by default | Script-source `--compat-non-strict-mode` when porting scripts that expect `globalThis` |
| legacy `delete` returns | Strict by default | Script-source `--compat-non-strict-mode` when porting sloppy scripts |
| `parseInt("10")` | Not available as global | `Number.parseInt("10")` |
| `isNaN(x)` | Not available as global | `Number.isNaN(x)` |

These restrictions are intentional — they eliminate common sources of bugs and security issues. See [Language](language.md) for the full rationale.

## Next Steps

You now have a working understanding of GocciaScript. Here's where to go from here:

- **[Language](language.md)** — Full list of what's supported and what's excluded, with rationale
- **[Built-in Objects](built-ins.md)** — Complete API reference for all built-in objects (Array, String, Map, Set, Promise, Temporal, etc.)
- **[`examples/`](../examples/)** — More example programs: classes, promises, and unsupported feature demos
- **[Architecture](architecture.md)** — Pipelines and main layers
- **[Interpreter](interpreter.md)** and **[Bytecode VM](bytecode-vm.md)** — Tree-walk vs bytecode execution backends
- **[Core patterns](core-patterns.md)** — Recurring implementation patterns, internal terminology
