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 configurationStatements
| Form | Notes |
|---|---|
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 = value | scalar constant |
const Name: + block | structured 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
| Form | Notes |
|---|---|
name: value | a property |
name: + block | a property with a block value |
abstract name: Type | a contract; abstract specs only |
Block operations
| Form | Meaning |
|---|---|
key: value | object assignment |
- value | list item |
- + block | list item with a block value |
+ value | composition |
++ value | duplicate-preserving list concatenation |
| raw lines | multiline string content, to the end of the block |
Values
| Form | Kind |
|---|---|
3, -2.5, 1e3 | number |
true, false | boolean |
null | null |
"text" | quoted string |
bare text | unquoted string |
Name | reference if Name is a symbol, else string |
A.b.c | reference (always) |
super | first inherited definition of this property |
self.name, self.keyword, self.abstract | spec metadata |
[a, b] | inline list |
{ a: 1 } | inline object |
Types
string | number | boolean | null | Foo | T[] | T?| Type | Matches |
|---|---|
string | a string value |
number | a number value |
boolean | a boolean value |
null | a null value |
Foo | a 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 | + | ++ |
|---|---|---|
| string | ordered block concatenation, joined by a blank line | not allowed |
| list | concatenate, stable dedup | concatenate, keep duplicates |
| object | recursive deep merge, leftmost wins | not allowed |
| number, boolean, null | not allowed | not allowed |
Mixing kinds in one block is PSY4003. Composing exactly one value is the
identity.
Resolution rules
| Rule | Behaviour |
|---|---|
| Parent precedence | extends A, B, C gives A > B > C |
| Linearization | C3-style merge; deterministic fallback to depth-first |
| Keyword base order | explicit parents outrank the keyword's abstract spec |
Plain super | first inherited definition of the same property |
+ super | compose all inherited definitions, in precedence order |
super binding | lexical — relative to the spec that wrote it |
self binding | dynamic — the spec being resolved |
| Local block order | later operations win; composition operands keep leftmost precedence among themselves |
| Identifier resolution | a lone identifier is a reference only if it names a symbol; a dotted path always is |
| Block kind | inferred from the first non-composition operation |
Module resolution
| Specifier | Resolved as |
|---|---|
./Foo, ../Foo | ./Foo.psy, then ./Foo/index.psy |
@scope/pkg | node_modules walk; psy field, else index.psy |
@scope/pkg/sub | <sub>.psy, then <sub>/index.psy inside the package |
| unresolvable | PSY3003 |
| malformed | PSY2016 |
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.
// commentis 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 useA declaration keyword may not be one of these (PSY3021).
Rejected in v1
See What v1 Does Not Do.