Skip to main content
Lion’s type system is built on Effect and exposes a small set of types and tagged error classes that flow through every evaluation. Understanding these lets you handle errors precisely and compose Lion evaluation with your own Effect-based code.

EvaluateResult

From @lionlang/core/types/evaluation
import type { EvaluateResult } from "@lionlang/core/types/evaluation";
The return type shared by evaluate and every special form handler:
type EvaluateResult = Effect.Effect<
  unknown,
  ParseError | ArgumentMismatchError | InvalidFunctionCallError,
  LionEnvironmentService
>
Success
unknown
The evaluated Lion value. The type is unknown because Lion expressions can produce any JSON-compatible value, a JavaScript function (from lambda), or any host value that was placed in the environment.
Error
ParseError | ArgumentMismatchError | InvalidFunctionCallError
A union of the three error types that can occur during evaluation. All three are typed so you can handle them selectively with Effect.catchTag or Effect.catchAll.
Requirements
LionEnvironmentService
The Effect context dependency. evaluate requires this service to resolve environment references and to support define. run fulfills this requirement automatically, so the Effect it returns has never as its requirements type.

ArgumentMismatchError

From @lionlang/core/errors/evaluation
import { ArgumentMismatchError } from "@lionlang/core/errors/evaluation";
A tagged error class raised when a standard library function receives arguments of the wrong type.
export class ArgumentMismatchError extends Schema.TaggedError<ArgumentMismatchError>(
  "ArgumentMismatchError"
)("ArgumentMismatchError", {}) {}
_tag
"ArgumentMismatchError"
The discriminant tag. Use Effect.catchTag("ArgumentMismatchError", ...) to handle this error selectively.

Handling example

import { Effect } from "effect";
import { run } from "@lionlang/core/evaluation/evaluate";
import { stdlib } from "@lionlang/core/modules";

const result = await Effect.runPromise(
  Effect.catchTag(
    run(["number/add", "hello", 1], stdlib),
    "ArgumentMismatchError",
    (_err) => Effect.succeed(null)
  )
);

InvalidFunctionCallError

From @lionlang/core/errors/evaluation
import { InvalidFunctionCallError } from "@lionlang/core/errors/evaluation";
Raised when an array expression’s head does not resolve to a callable value after evaluation.
export class InvalidFunctionCallError extends Schema.TaggedError<InvalidFunctionCallError>(
  "InvalidFunctionCallError"
)("InvalidFunctionCallError", { expression: LionExpressionSchema }) {}
_tag
"InvalidFunctionCallError"
The discriminant tag. Use Effect.catchTag("InvalidFunctionCallError", ...) to handle this error selectively.
expression
LionExpressionType
The array expression that triggered the error. Inspect this field to identify which expression head failed to resolve to a function.

Handling example

import { Effect } from "effect";
import { run } from "@lionlang/core/evaluation/evaluate";
import { stdlib } from "@lionlang/core/modules";

const result = await Effect.runPromise(
  Effect.catchTag(
    run(["not-a-function", 1, 2], stdlib),
    "InvalidFunctionCallError",
    (err) => {
      console.error("Bad call:", JSON.stringify(err.expression));
      return Effect.succeed(null);
    }
  )
);

LionEnvironmentService

From @lionlang/core/services/evaluation
import { LionEnvironmentService } from "@lionlang/core/services/evaluation";
An Effect Context.Tag that carries the active Environment through the evaluation pipeline.
export class LionEnvironmentService extends Context.Tag(
  "LionEnvironmentService"
)<LionEnvironmentService, Environment>() {}
Tag identifier
"LionEnvironmentService"
The string identifier used by Effect’s context system to locate the service.
Service value
Environment
The Environment instance holding the mutable bindings Ref and, for inner scopes, a reference to the parent environment.
Callers using run do not need to interact with LionEnvironmentService directly — run provisions it automatically from the environment argument. You only need this tag when composing evaluate manually or writing a custom special form handler that needs to read or modify the environment.

getService

From @lionlang/core/services/evaluation
import { getService } from "@lionlang/core/services/evaluation";
A convenience utility for retrieving a typed service from the Effect context:
export const getService = <T, U>(context: Context.Tag<T, U>) =>
  pipe(Effect.context<T>(), Effect.map(Context.get(context)));
Used internally by evaluatePrimitive and the special form handlers to access the current LionEnvironmentService:
const environment = await Effect.runPromise(
  pipe(
    getService(LionEnvironmentService),
    Effect.provideServiceEffect(LionEnvironmentService, makeEnvironment({}))
  )
);