# Generic Types

Ergo Framework uses several specialized types for identifying and addressing processes, nodes, and other entities in the system. Understanding these types is essential for working with the framework.

## Identifiers and Names

### gen.Atom

`gen.Atom` is a specialized string used for names - node names, process names, event names. While technically just a string, treating it as a distinct type allows the framework to optimize how these names are handled in the network stack.

Atoms appear in single quotes when printed:

```go
fmt.Printf("%s", gen.Atom("myprocess"))
// Output: 'myprocess'
```

The network stack caches atoms and maps them to numeric IDs to reduce bandwidth when the same names appear repeatedly in messages.

### gen.PID

A `gen.PID` uniquely identifies a process. It contains the node name where the process lives, a unique sequential ID, and a creation timestamp. The creation timestamp changes when a node restarts, allowing you to detect if you're talking to a reincarnation of a node rather than the original.

`gen.PID` values print with the node name hashed for brevity:

```go
pid := gen.PID{Node: "node@localhost", ID: 1001, Creation: 1685523227}
fmt.Printf("%s", pid)
// Output: <90A29F11.0.1001>
```

The hash (90A29F11) is a CRC32 of the node name. This keeps the printed form compact while remaining unique.

### gen.ProcessID

A `gen.ProcessID` identifies a process by its registered name rather than `gen.PID`. This is useful when you need to address a process but don't know its `gen.PID`, or when the `gen.PID` might change across restarts but the name remains constant.

```go
processID := gen.ProcessID{Name: "worker", Node: "node@localhost"}
fmt.Printf("%s", processID)
// Output: <90A29F11.'worker'>
```

### gen.Ref

`gen.Ref` values are unique identifiers generated by nodes. They're used for correlating requests and responses in synchronous calls, and as tokens when registering events.

A `gen.Ref` is guaranteed unique within a node for its lifetime. The structure includes the node name, creation time, and a unique ID array.

```go
ref := node.MakeRef()
fmt.Printf("%s", ref)
// Output: Ref#<90A29F11.128194.23952.0>
```

References can also embed deadlines (stored in ID\[2]) for timeout tracking. Recipients can check `ref.IsAlive()` to see if a request is still valid.

### gen.Alias

`gen.Alias` is like a temporary `gen.PID`. Processes create aliases for additional addressability without registering names. Meta processes use aliases as their primary identifier.

Aliases use the same structure as references but print with a different prefix:

```go
alias := process.CreateAlias()
fmt.Printf("%s", alias)
// Output: Alias#<90A29F11.128194.23952.0>
```

### gen.Event

`gen.Event` values represent named message streams that processes can subscribe to. A `gen.Event` identifier consists of a name and the node where it's registered.

```go
event := gen.Event{Name: "user_login", Node: "node@localhost"}
fmt.Printf("%s", event)
// Output: Event#<90A29F11:'user_login'>
```

### gen.Env

Environment variable names in Ergo are case-insensitive. The `gen.Env` type ensures this by converting to uppercase.

```go
env := gen.Env("database_url")
fmt.Printf("%s", env)
// Output: DATABASE_URL
```

This allows processes to inherit environment variables from parents, leaders, and the node, with consistent naming regardless of how they're specified.

## Core Interfaces

The framework defines several interfaces that provide access to different parts of the system.

### gen.Node

The `gen.Node` interface is what you get when you start a node. It provides methods for spawning processes, managing applications, configuring networking, and controlling the node lifecycle.

```go
node, err := ergo.StartNode("mynode@localhost", gen.NodeOptions{})
// node implements gen.Node interface
```

Node operations can be called from any goroutine. The node manages processes but isn't itself an actor.

### gen.Process

The `gen.Process` interface represents a running actor. It provides methods for sending messages, spawning children, linking to other processes, and managing the actor's lifecycle.

Actors typically embed this interface:

```go
type MyActor struct {
    act.Actor  // Embeds gen.Process
}

func (a *MyActor) HandleMessage(from gen.PID, message any) error {
    // Process methods are available directly
    a.Send(from, "reply")
    return nil
}
```

Process methods enforce state-based access control. Some operations are only available when the process is in certain states, ensuring actor model constraints are maintained.

### gen.Network

The `gen.Network` interface manages distributed communication. It handles connections to remote nodes, routing, and service discovery.

```go
network := node.Network()
remoteNode, err := network.GetNode("remote@otherhost")
```

Network transparency means sending messages to remote processes uses the same API as local processes. The `gen.Network` interface is where you configure how that transparency is achieved.

### gen.RemoteNode

A `gen.RemoteNode` represents a connection to another Ergo node. Through this interface, you can spawn processes on the remote node or start applications there.

```go
remoteNode, err := network.GetNode("node@remotehost")
pid, err := remoteNode.Spawn("worker", gen.ProcessOptions{}, args)
```

The remote operations require the target node to have enabled the corresponding permissions.

## Type Design Philosophy

These types reflect a few design decisions worth understanding.

**Hashing for readability** - Node names are hashed in output to keep logs and traces readable while maintaining uniqueness. Full names can be verbose, especially in distributed systems with descriptive naming.

**Separate types for concepts** - `gen.PID`, `gen.ProcessID`, `gen.Alias`, and `gen.Event` are distinct types even though they could have been unified. Each represents a different way of addressing or identifying something in the system, and the type system helps keep these concepts clear.

**Network-aware design** - Many types include the node name. This isn't just for completeness - it's what enables network transparency. A `gen.PID` tells you not just which process, but which node, allowing the framework to route messages appropriately.

For detailed API documentation of these interfaces and types, refer to the godoc comments in the source code.
