Morph Language Reference
Status: Living document. This page is a normative sketch of surface syntax. Step-by-step tutorials and runnable patterns live under
Docs/learnmorph/.
Morph source files use the .mx extension. Documentation examples use the mx fenced-block tag for .mx surface snippets (same convention as Learn Morph).
Lexical and structure
- Statements usually end with
;. - Modules:
module Name;at the top of a file imports another module (resolution searchessrc/, packagemodules/, then the standard library). This is not a nestedmodule { }declaration block. - Entry point:
Init method() { ... }insrc/Main.mxis the program entry (no parameters, no return type required). - One class per file is enforced when configured (class name matches filename); see Learn Morph Class declaration.
Names and declarations
Variables
Bind with is (recommended for variables). A shorthand without is exists; see Variable declaration.
count is 10;
name is "Morph" as string;
ratio is 0.5; // inferred float
Type annotations use as type after the value:
x is 42 as int;
Bare names can introduce dynamic or typed uninitialized slots; the tutorials spell out the exact forms.
Methods (all functions)
Functions are Name method(params) [as ReturnType] { ... }. Method names are PascalCase (see Method declaration).
Add method(a as int, b as int) as int {
return a + b;
}
Init method() {
Print("hello");
}
Parameters: identifier as Type, comma-separated. Return type: as Type after ); omit for no value (void).
Types: class, struct, enum
Class — reference-style object:
Player class {
health is 100 as int;
}
Struct — value-style aggregate:
Point struct {
x is 0 as int;
y is 0 as int;
}
Enum — named constants; branch with switch / case, not Rust-style match:
Color enum {
Red,
Green
}
switch (c) {
case Color.Red:
Print("red");
break;
default:
break;
}
Generics (classes): Name class<T> { ... } — see Generic classes.
Instantiation: call the type like a method — Player(), Box<int>().
Primitive types (user-facing)
The primary scalar types documented for users are int, float, string, bool. Inference rules: integer literals → int, decimal literals → float, etc. See Primitive types.
There is also dynamic for late-bound or uninitialized slots (tutorial section).
Operators and control flow
- Arithmetic and comparison: familiar
+,-,*,/,==,!=,<,>,&&,||, etc., inside( ... )where the grammar requires it. if/else/else if: C-style with parentheses around the condition.- Loops:
for (init; cond; step) { },while (cond) { }, and range-style / parallel forms described in Learn Morph Control flow.
There is no fn keyword, let bindings, or match expr { pat => ... } surface syntax as in Rust.
Tensors and GPU
- Import tensor support with
module Tensor;(and useTensor<float>etc.) — see Tensor creation. - Element-wise ops:
+,-,*,/on tensors. - Matrix multiply: binary
@. gpu { }blocks: only inside methods; tensor-oriented work; no arbitrary control flow inside the block. See GPU blocks.
Do not use placeholder syntax like tensor<f32, [h, w]> or gpu fn ... in real Morph sources; that is not the taught or documented surface language.
Pointers
Morph uses readable keywords instead of & / *:
p is address of x;
Print(value of p);
value of p is 99;
See Pointers.
Ownership highlights
is— bind / alias (shared view of data per language rules).another— deep / independent copy when copying is intended.move— transfer ownership; prior name must not be used afterward.
See Ownership.
Project configuration (morph.toml)
Package dependencies and native (modulecpp) configuration are described in Morph TOML. Typical dependency form:
[dependencies]
example = { github = "owner/repo", version = "^1.0.0" }
Use module PackageName; in .mx sources to consume installed packages — not import as in other languages.
Related specs
- Compiler IR: NIR specification — SSA IR and pipeline (implementation-oriented; not a substitute for surface syntax above).