# `PtcRunner.Lisp.Env`
[🔗](https://github.com/andreasronge/ptc_runner/blob/main/lib/ptc_runner/lisp/env.ex#L1)

Builds the initial environment with builtins for PTC-Lisp.

Provides the foundation environment with all builtin functions
and their descriptors. The environment supports multiple binding types:

- `{:normal, fun}` - Fixed-arity function
- `{:variadic, fun, identity}` - Variadic function with identity value for 0-arg case
- `{:variadic_nonempty, name, fun}` - Variadic function requiring at least 1 argument
- `{:multi_arity, name, tuple_of_funs}` - Multiple arities where tuple index = arity - min_arity
- `{:collect, fun}` - Collects all args into a list and passes to unary function

# `binding`

```elixir
@type binding() ::
  PtcRunner.Lisp.Env.Builtin.t()
  | {:normal, function()}
  | {:variadic, function(), term()}
  | {:variadic_nonempty, atom(), function()}
  | {:multi_arity, atom(), tuple()}
  | {:collect, function()}
  | {:constant, term()}
```

# `env`

```elixir
@type env() :: %{required(atom()) =&gt; binding()}
```

# `builtin?`

```elixir
@spec builtin?(atom() | String.t()) :: boolean()
```

Check if a name is a builtin function.

Returns `true` if the given atom is a builtin function name.

## Examples

    iex> PtcRunner.Lisp.Env.builtin?(:map)
    true

    iex> PtcRunner.Lisp.Env.builtin?(:filter)
    true

    iex> PtcRunner.Lisp.Env.builtin?(:my_var)
    false

# `builtins_by_category`

Get the list of builtin functions for a category.

Delegates to `PtcRunner.Lisp.Registry.builtins_by_category/1`.

## Examples

    iex> :join in PtcRunner.Lisp.Env.builtins_by_category(:string)
    true

    iex> :set in PtcRunner.Lisp.Env.builtins_by_category(:set)
    true

# `builtins_by_namespace`

# `category_name`

Get a human-readable name for a category.

Delegates to `PtcRunner.Lisp.Registry.category_name/1`.

## Examples

    iex> PtcRunner.Lisp.Env.category_name(:string)
    "String"

    iex> PtcRunner.Lisp.Env.category_name(:core)
    "Core"

# `clojure_namespace?`

```elixir
@spec clojure_namespace?(atom()) :: boolean()
```

Check if a namespace is a known Clojure-style namespace.

## Examples

    iex> PtcRunner.Lisp.Env.clojure_namespace?(:"clojure.string")
    true

    iex> PtcRunner.Lisp.Env.clojure_namespace?(:str)
    true

    iex> PtcRunner.Lisp.Env.clojure_namespace?(:my_ns)
    false

# `constant?`

Check if a name is a namespaced constant.

# `initial`

```elixir
@spec initial() :: env()
```

# `namespace_category`

```elixir
@spec namespace_category(atom()) :: atom() | nil
```

Get the category for a Clojure-style namespace.

Returns `:string`, `:set`, or `:core`.

## Examples

    iex> PtcRunner.Lisp.Env.namespace_category(:"clojure.string")
    :string

    iex> PtcRunner.Lisp.Env.namespace_category(:str)
    :string

---

*Consult [api-reference.md](api-reference.md) for complete listing*
