Language Reference

Every Construct

The whole language as tables, for when you know what you want and just need the syntax.

Everything Psy has, in one page, without the explanations. The chapters have those.

Files

.psy                 a module
psy.config.ts        build and tooling configuration

Statements

FormNotes
use "./mod"activate the target's declaration keywords
import { A } from "./mod"named imports only
import { A as B } from "./mod"renaming
export { A } from "./mod"re-export
const Name = valuescalar constant
const Name: + blockstructured constant
spec Name:a spec
spec Name extends A, B:multiple inheritance, A strongest
abstract spec Name:an abstract spec
abstract spec Name as kw:exposes a declaration keyword
kw Name:a framework declaration
export ...on any declaration form

Members

FormNotes
name: valuea property
name: + blocka property with a block value
abstract name: Typea contract; abstract specs only

Block operations

FormMeaning
key: valueobject assignment
- valuelist item
- + blocklist item with a block value
+ valuecomposition
++ valueduplicate-preserving list concatenation
raw linesmultiline string content, to the end of the block

Values

FormKind
3, -2.5, 1e3number
true, falseboolean
nullnull
"text"quoted string
bare textunquoted string
Namereference if Name is a symbol, else string
A.b.creference (always)
superfirst inherited definition of this property
self.name, self.keyword, self.abstractspec metadata
[a, b]inline list
{ a: 1 }inline object

Types

string | number | boolean | null | Foo | T[] | T?
TypeMatches
stringa string value
numbera number value
booleana boolean value
nulla null value
Fooa spec reference whose spec inherits Foo
T[]a list whose every item matches T
T?T, null, or an absent property

No generics.

Composition semantics

Kind+++
stringordered block concatenation, joined by a blank linenot allowed
listconcatenate, stable dedupconcatenate, keep duplicates
objectrecursive deep merge, leftmost winsnot allowed
number, boolean, nullnot allowednot allowed

Mixing kinds in one block is PSY4003. Composing exactly one value is the identity.

Resolution rules

RuleBehaviour
Parent precedenceextends A, B, C gives A > B > C
LinearizationC3-style merge; deterministic fallback to depth-first
Keyword base orderexplicit parents outrank the keyword's abstract spec
Plain superfirst inherited definition of the same property
+ supercompose all inherited definitions, in precedence order
super bindinglexical — relative to the spec that wrote it
self bindingdynamic — the spec being resolved
Local block orderlater operations win; composition operands keep leftmost precedence among themselves
Identifier resolutiona lone identifier is a reference only if it names a symbol; a dotted path always is
Block kindinferred from the first non-composition operation

Module resolution

SpecifierResolved as
./Foo, ../Foo./Foo.psy, then ./Foo/index.psy
@scope/pkgnode_modules walk; psy field, else index.psy
@scope/pkg/sub<sub>.psy, then <sub>/index.psy inside the package
unresolvablePSY3003
malformedPSY2016

Built-in packages inside a standalone binary are a fallback only; an installed package always wins.

Naming conventions

Spec and constant names   PascalCase        (specNaming)
Property names            camelCase         (propertyNaming)
Framework keywords        lowercase kebab   (keywordNaming)

Conventions, enforced by lint rules you can turn off — not by the parser.

Whitespace and comments

  • Spaces only; tabs are PSY1001.
  • Indentation defines blocks; a newline terminates a statement; no semicolons.
  • Formatter default indentation is four spaces.
  • // comment is the only comment form, recognised everywhere including inside multiline strings.
  • Escapes, and only these three: \\, \//, \${.
  • Blank lines and comment-only lines never affect layout.

Reserved words

abstract  as     boolean  const  export  extends  false  from
import    null   number   self   spec    string   super  true   use

A declaration keyword may not be one of these (PSY3021).

Rejected in v1

See What v1 Does Not Do.

On this page