Why Myth?


For AI agents. Myth is an Elements language with explicit intent, predictable lookup and visible uncertainty. Use the current version 1 reference for code generation.

Myth is designed by AI, for AI: a programming language whose starting point is code that an AI can generate, inspect and change with fewer hidden assumptions.

The priority is correctness over saving a few tokens. Concise code is useful, but not when a shorter spelling conceals a conversion, changes which symbol is selected, or treats an unknown API contract as a guarantee.

Make Intent Visible

A small edit should be easy to reason about from the source around it. Myth makes the author show where a name comes from, whether a value can be absent, and what an operation is allowed to change.

Show Where a Name Comes From

Ordinary locals and parameters begin with _. Access to an instance member names its receiver, such as self._title for a field on the current object. A static call names its type, and a qualified name such as global.System.Console starts lookup at the root namespace. If two imports make the same short name ambiguous, the compiler asks for an explicit choice. Reordering the imports cannot silently select another declaration. See Names and Scope.

Put Guarantees in the Declaration

In a written type annotation, the type name takes a nullability suffix. Boolean is the type name. Write Boolean! for a non-null value or Boolean? when absence is allowed. Reference types follow the same rule.

type TitleDraft: class {
  private field _title: String!;

  constructor(_title: String!) {
    self._title = _title;
  }

  method ReadTitle(): String! mutates never; {
    return self._title;
  }
}

type Document: class {
  private field _title: String? = null;

  method ApplyTitle(borrowed mutates never _draft: TitleDraft!)
    writes self._title;
  {
    self._title = _draft.ReadTitle();
  }
}

ApplyTitle takes a non-null draft. The borrowed annotation gives the method temporary access to the draft for the call. The parameter’s mutates never annotation protects the draft from changes. On the document side, writes self._title limits the update to the title field.

These promises guide edits to the method. Storing the draft for later would require a different ownership contract. Editing the draft or writing another document field would also require changing the relevant contract. See Annotations.

Make the Response to Absence Explicit

If absence is expected, handle it in the control flow. Use as not null because(...) when you know why a particular value is present and that guarantee is unavailable to the compiler.

Suppose an imported Factory.Unknown returns null only when its Boolean argument is true. A caller passing false can cite that behavior directly.

readonly var _title = Factory.Unknown(false) as not null because(
  "Factory.Unknown returns a string when its argument is false"
);

The reason records the evidence for that call. The assertion still checks at runtime and throws if the imported implementation breaks its guarantee. See Nullability.

Keep Uncertainty Visible

An imported API can have a clear implementation without exporting enough metadata for Myth to establish its guarantees. Here is an Oxygene example where the result declaration leaves nullability unspecified.

class method Unknown(aNull: Boolean): String;
begin
  exit if aNull then nil else "unknown";
end;

Myth imports the result as having unknown nullability. Returning it directly from a method declared to return String! produces a compile error, even when the argument is the constant false.

static method RequiredTitle(): String! {
  return Factory.Unknown(false);
}
E803 Value with unknown nullability cannot be used as non-null; check for null or use as not null because("...").

When the API can legitimately return null, test the result once and handle both cases.

static method DisplayTitle(_allowMissing: Boolean!): String! {
  if not null _title = Factory.Unknown(_allowMissing) {
    return _title;
  }
  return "(untitled)";
}

What an Unverified Diagnostic Looks Like

Mutation uncertainty has its own diagnostic. In this example, _store holds an imported object. Its Observe() method returns a non-null integer but supplies no mutation contract.

method Value(): Int32! mutates never; {
  return self._store.Observe();
}

The compiler cannot establish that the call leaves the receiver's reachable storage unchanged. This is the diagnostic from the compiler’s interop regression fixture.

U3 Cannot verify mutation effects for method Value: self: mutation effects are unspecified for Observe.

An ordinary build can continue with U3 and exposes the missing evidence. See Unverified for the other diagnostic codes.

Built on Elements

Myth is a language frontend for Elements. It uses the existing compiler infrastructure and platform backends rather than translating source into another language. The goal is direct access to the libraries and frameworks of the selected target, alongside the other Elements languages.

The current implementation has local runtime validation on .NET, the JVM, Cocoa on macOS arm64, and Island on Darwin arm64. This is a narrower claim than support for every device and platform in the Elements family. See Implementation Status.