The Scaly Programming Language

The Scaly Programming Language

Table of Contents
1 Introduction	000
1.1 Overview	000
1.2 Design Philosophy	000
1.3 Implementation Status	000
2 Lexical Structure	000
2.1 Overview	000
2.2 Whitespace and Line Breaks	000
2.3 Comments	000
2.4 Literals	000
2.4.1 Integer Literals	000
2.4.2 Floating-Point Literals	000
2.4.3 String Literals	000
2.4.4 Character Literals	000
2.4.5 Boolean Literals	000
2.5 Identifiers	000
3 Grammar	000
4 Definitions	000
4.1 Overview	000
4.2 Definitions	000
4.2.1 Structure Definitions	000
4.2.2 Union Definitions	000
5 Expressions	000
5.1 Overview	000
5.2 Literals	000
5.2.1 Boolean Literals	000
5.2.2 Integer Literals	000
5.2.3 Hexadecimal Literals	000
5.2.4 Floating-Point Literals	000
5.2.5 String Literals	000
5.2.6 Character Literals	000
5.3 Operations	000
5.3.1 Prefix Functions	000
5.3.2 Operator Chains	000
5.3.3 Parentheses and Grouping	000
5.3.4 Identifier Shapes	000
5.3.5 Let Bindings	000
5.4 If Expressions	000
5.5 Match Expressions	000
5.6 Choose Expressions	000
5.6.1 Basic Choose	000
5.6.2 Choose with Result	000
5.6.3 Choose Else Branch	000
A. Standard Library Reference	000
A.1 Types	000
A.1.1 define Sum(left: int, right: int)	000
A.1.2 define Difference(left: int, right: int)	000
A.1.3 define Product(left: int, right: int)	000
A.1.4 define Quotient(left: int, right: int)	000
A.2 Operators	000
A.2.1 operator +(left: int, right: int) returns Sum	000
A.2.2 operator -(left: int, right: int) returns Difference	000
A.2.3 operator *(left: int, right: int) returns Product	000
A.2.4 operator /(left: int, right: int) returns Quotient	000
A.2.5 operator div(left: int, right: int) returns int	000
A.2.6 operator mod(left: int, right: int) returns int	000
A.2.7 operator =(left: int, right: int) returns bool	000
A.2.8 operator <>(left: int, right: int) returns bool	000
A.2.9 operator <(left: int, right: int) returns bool	000
A.2.10 operator >(left: int, right: int) returns bool	000
A.2.11 operator <=(left: int, right: int) returns bool	000
A.2.12 operator >=(left: int, right: int) returns bool	000
A.3 Functions	000
A.3.1 function -(right: int) returns int	000
A.3.2 function +(right: int) returns int	000
A.3.3 function abs(x: int) returns int	000

1 Introduction
1.1 Overview
Scaly is a programming language designed to be self-scaling: it adapts to the needs of the developer, from simple scripts to complex systems. The language emphasizes clarity through postfix operators, eliminating precedence rules, and optional region-based memory management.
1.2 Design Philosophy
Scaly follows these core principles:
• Clarity over cleverness — Code should be readable without mental parsing of operator precedence.
• Explicit over implicit — Memory management and control flow are visible in the code structure.
• Incremental complexity — Simple programs stay simple; advanced features are available when needed.
1.3 Implementation Status
This specification documents the language as it is implemented. Features are added incrementally, with each addition reflected immediately in this document.
Current implementation status:
• Literals — implemented
• Operators — planned
• Bindings — planned
• Functions — planned
2 Lexical Structure
2.1 Overview
This chapter describes the lexical structure of Scaly: how source text is divided into tokens. The lexer transforms a sequence of characters into a sequence of tokens that the parser then processes.
2.2 Whitespace and Line Breaks
Whitespace characters (space, tab) separate tokens but are otherwise insignificant. Line breaks, however, are syntactically meaningful in Scaly — they can terminate statements and declarations.
A colon (:) can be used in place of a line break when multiple statements should appear on a single line.
2.3 Comments
Scaly supports two forms of comments:
• Single-line comments start with a semicolon (;) and extend to the end of the line.
• Multi-line comments start with ;* and end with *;.

; This is a single-line comment

;* This is a
   multi-line comment *;
    
2.4 Literals
2.4.1 Integer Literals
Integer literals represent whole numbers. They can be written in decimal or hexadecimal notation.

42        ; decimal
0x2A      ; hexadecimal (same value)
      
2.4.2 Floating-Point Literals
Floating-point literals represent decimal numbers with a fractional part or an exponent.

3.14159       ; pi
2.5e10        ; scientific notation
1.0e-5        ; small number
      
2.4.3 String Literals
String literals are enclosed in double quotes. They support standard escape sequences.

"Hello, World!"
"Line 1\nLine 2"      ; with newline escape
"Tab:\tValue"         ; with tab
"Quote: \"nested\""   ; escaped quotes
      
Strings can span multiple lines without any special syntax — newlines are simply included as part of the string content:

"This is a string
that spans multiple
lines."
      
2.4.4 Character Literals
Character literals represent single Unicode code points, enclosed in backticks.

`a`           ; lowercase a
`\n`          ; newline character
`\u{1F600}`   ; emoji (grinning face)
      
2.4.5 Boolean Literals
Boolean literals are true and false.

true
false
      
2.5 Identifiers
Identifiers name variables, functions, types, and other entities. Scaly supports three forms of identifiers:
• Alphanumeric identifiers start with a letter and continue with letters, digits, or underscores.
• Operator identifiers consist of operator characters such as +, -, *, /.
• String identifiers are enclosed in single quotes and can contain any characters.

myVariable        ; alphanumeric
calculate_total   ; with underscore
++                ; operator identifier
'my identifier'   ; string identifier (with spaces)
    
3 Grammar
This chapter presents the complete grammar of the Scaly programming language in a formal notation. Each production defines a syntactic construct, with nonterminals linking to their definitions.
Notation:
• identifier, literal — terminal symbols from the lexer
• 'keyword' — keyword terminals
• X | Y — alternatives
• X? — optional
• X+ — one or more
• X* — zero or more
Program = File Statement* 
File = Package* Use* Declaration* 
Declaration = Symbol ':'? 
Symbol = Private | Definition | Function | Operator | Trait | Macro | Module
Private = 'private' Export 
Export = Definition | Function | Operator | Trait | Module
Member = Constituent ':'? 
Constituent = Definition | Function | Procedure | Operator | Implement | Trait | Macro | Module
Definition = 'define' IDENTIFIER GenericParameters? ':'? Attribute* Concept 
GenericParameters = '[' GenericParameter+ ']' 
GenericParameter = IDENTIFIER Attribute* ',' 
Concept = Class | Namespace | Union | Constant | Delegate | Intrinsic
Class = Structure ':'? Body? ':'? 
Body = '{' Use* Init* DeInit? Member* '}' ':'? 
Namespace = '{' Use* Declaration* '}' ':'? 
Union = 'union' ':'? '(' Variant+ ')' ':'? Body? ':'? 
Variant = IDENTIFIER Attribute* TypeAnnotation? ',' ':'? 
Constant = Type Operand* ':'? 
Delegate = 'delegate' ParameterSet? Attribute* Returns? Throws? 
GenericArguments = '[' GenericArgument* ']' 
GenericArgument = Type ',' 
Optional = '?' 
ParameterSet = Parameters | Type
Parameters = '(' Item* ')' 
Item = IDENTIFIER TypeAnnotation? ',' ':'? Attribute* ':'? 
Returns = 'returns' Type Attribute* 
Throws = 'throws' Type Attribute* 
Use = 'use' Name ':'? 
Implement = 'implement' Type Attribute* ':'? '{' Use* Method* '}' ':'? 
Trait = 'trait' Name Extends? Attribute* '{' Use* Method* '}' ':'? 
Method = Function | Procedure | Operator
Init = 'init' ParameterSet? ':'? Action ':'? 
DeInit = 'deinit' ':'? Action ':'? 
Function = 'function' Target 
Procedure = 'procedure' Target 
Operator = 'operator' Target 
Target = Named | Routine
Named = IDENTIFIER Routine 
Routine = GenericArguments? Lifetime? ParameterSet? Attribute* Returns? ':'? Throws? ':'? Implementation 
Implementation = Action | Extern | Instruction | Intrinsic
Extern = 'extern' 
Instruction = 'instruction' ':'? 
Intrinsic = 'intrinsic' ':'? 
Extends = 'extends' Extend* 
Extend = Type ',' 
Macro = 'macro' IDENTIFIER Model Operand+ 
Attribute = ATTRIBUTE Model ':'? 
Model = Literal | Name | Object | Vector
Module = 'module' IDENTIFIER ':'? 
Package = 'package' Name ':'? 
Initializer = '(' Operand+ ')' 
Operand = Expression MemberAccess* 
MemberAccess = '.' Name 
Expression = Literal | Type | Object | Vector | Block | If | Match | Lambda | For | While | Choose | Try | Repeat | SizeOf | Is
Literal = LITERAL 
Object = '(' Component* ')' 
Component = Operand+ Attribute* Value? ',' 
Value = ':' Operand+ Attribute* 
Vector = '[' Element+ ']' Lifetime? 
Element = Operand+ Attribute* ',' 
Block = '{' Use* Statement* '}' 
If = 'if' Operand+ ':' Command Else? 
Else = 'else' ':'? Command 
Match = 'match' Operand+ ':' Branch+ Else? 
Branch = Case+ ':' Statement 
Case = 'case' Operand+ 
Statement = Command ':'? 
While = 'while' Condition ':' Label? Action 
Choose = 'choose' Operand+ ':' When* Else? 
Try = 'try' Condition ':' When* Else? 
Condition = Operation | Let
When = 'when' IDENTIFIER ':' Name ':'? Command ':'? 
Command = Operation | Let | Var | Mutable | Set | Continue | Break | Return | Throw
Let = 'let' Binding 
Var = 'var' Binding 
Mutable = 'mutable' Binding 
Binding = IDENTIFIER BindingAnnotation? Operand+ 
BindingAnnotation = ':' BindingSpec 
BindingSpec = Structure | Type | Array
Array = '[' Type* ']' 
Structure = '(' Part* ')' 
Part = Field | Property
Field = 'private' Property 
Property = IDENTIFIER TypeAnnotation Initializer? ',' ':'? Attribute* ':'? 
TypeAnnotation = ':' Type 
Continue = 'continue' Loop? ':'? 
Break = 'break' Loop? Operand* ':'? 
Loop = 'loop' IDENTIFIER 
Return = 'return' Operand* 
Throw = 'throw' Operand* 
Lambda = 'lambda' Operand+ ':' Action 
For = 'for' IDENTIFIER TypeAnnotation? 'in' Operand+ ':' Label? Action 
Label = 'label' IDENTIFIER ':'? 
Repeat = 'repeat' Label? Action 
Action = Operation | Set
Operation = Operand+ 
Set = 'set' Operand+ ':' Operand+ 
SizeOf = 'sizeof' Type 
Is = 'is' Name 
Type = Name GenericArguments? Optional? Lifetime? 
Name = IDENTIFIER Extension* 
Extension = '.' IDENTIFIER 
Lifetime = Call | Local | Reference | Thrown
Call = '#' 
Local = '$' 
Reference = '^' IDENTIFIER 
Thrown = '!' 
4 Definitions
4.1 Overview
Definitions declare new types that can be used throughout a program. Types can have properties, methods, and nested definitions.
4.2 Definitions
Definitions declare new types that can be used throughout a program.
4.2.1 Structure Definitions
The define keyword creates a new structure type with named properties.
Input	Result	
define Point(x: int, y: int)
Point(3, 4)	{"_type":"Point","x":3,"y":4}	
define Point(x: int, y: int)
Point(3, 4).x	3	
define Point(x: int, y: int)
let p Point(3, 4)
p.x + p.y	7	
define Point(x: int, y: int)
define Rectangle(origin: Point, width: int, height: int)
Rectangle(Point(0, 0), 10, 5).width	10	

4.2.2 Union Definitions
Unions define types with multiple variants. Each variant can optionally carry a value.
Input	Result	
define Option union(Some: int, None)
Some(5)	{"_type":"Option","_variant":"Some","value":5}	
define Option union(Some: int, None)
None	{"_type":"Option","_variant":"None"}	
define Result union(Ok: int, Err: String)
Ok(42)	{"_type":"Result","_variant":"Ok","value":42}	
define Result union(Ok: int, Err: String)
Err("error")	{"_type":"Result","_variant":"Err","value":"error"}	
define Option union(Some: int, None)
Some(5).value	5	

5 Expressions
5.1 Overview
Expressions are the core computational units of Scaly. Every expression evaluates to a value. Unlike many languages, Scaly uses postfix operators and does not define operator precedence — evaluation order is always explicit.
5.2 Literals
Expressions are the core computational units of Scaly. Every expression evaluates to a value.
5.2.1 Boolean Literals
The boolean literals are true and false.
Input	Result	
true	true	
false	false	

5.2.2 Integer Literals
Integer literals are sequences of decimal digits, optionally preceded by a minus sign for negative numbers.
Input	Result	
42	42	
0	0	
-7	-7	

5.2.3 Hexadecimal Literals
Hexadecimal literals start with 0x or 0X followed by hexadecimal digits (0-9, a-f, A-F).
Input	Result	
0xFF	255	
0x1A	26	
0x0	0	

5.2.4 Floating-Point Literals
Floating-point literals contain a decimal point separating the integer and fractional parts.
Input	Result	
3.14	3.14	
2.0	2	
0.5	0.5	

5.2.5 String Literals
String literals are enclosed in double quotes. They may span multiple lines, with line breaks preserved in the resulting string.
Input	Result	
"hello"	hello	
""	

5.2.6 Character Literals
Character literals represent a single character, enclosed in backticks.
Input	Result	
`a`	a	
`Z`	Z	

5.3 Operations
Operations allow combining expressions.
5.3.1 Prefix Functions
An operation is a sequence of operands that evaluates to a single value. Each operand is an expression optionally followed by member access. An operation ends with a colon, a line break, or anything which is not an expression. Evaluation uses a context which is empty at the start of an operation. When the context is empty, operator-shaped identifiers act as prefix functions, taking the next operand as their argument.
Input	Result	
-7	-7	
-(-3)	3	
+ 3	3	

5.3.2 Operator Chains
When the context holds a value, operators chain left-to-right. Each operator takes the current value and the next operand, producing a new value. There is no operator precedence built into the language itself. Operator precedence is built into the implementation of the individual operators. The common arithmetic operators are built into the standard library.
Input	Result	
3 + 4	7	
10 - 3	7	
6 * 7	42	
3 + 4 * 2	11	
20 - 5 - 3	12	

5.3.3 Parentheses and Grouping
Parentheses create a empty context. This allows prefix forms inside an otherwise operator chain, and explicit grouping when needed.
Input	Result	
5 * (- 2)	-10	
2 * (3 + 4)	14	
(2 + 3) * (4 + 1)	25	

5.3.4 Identifier Shapes
Identifiers can have name shape (alphanumeric) or operator shape (symbols). The shape is purely lexical and does not determine behavior. Whether an identifier acts as a prefix function or chain operator depends on its declaration and the register state.
Input	Result	
10 div 3	3	
abs (- 5)	5	

5.3.5 Let Bindings
Let bindings introduce local variables. The syntax is let followed by a name and a value expression (no equals sign). Multiple statements are separated by colons or newlines.
Input	Result	
let x 5
x	5	
let x 5
x + 3	8	
let x 5
let y 3
x + y	8	
let x 2 + 3
x * 2	10	

5.4 If Expressions
If expressions evaluate one of two branches based on a boolean condition. The syntax is if followed by the condition, a colon, the consequent, and optionally else with an alternative.
if true: 1 else 0        ; evaluates to 1
if false: 1 else 0       ; evaluates to 0
if 5 > 3: 10 else 20     ; evaluates to 10
If expressions can be nested:
if false: 1 else if true: 2 else 3  ; evaluates to 2
5.5 Match Expressions
Match expressions compare a value against multiple cases. The syntax is match followed by the scrutinee, a colon, one or more case branches, and optionally else.
match 2: case 1: 10 case 2: 20 else 0  ; evaluates to 20
match 5: case 1: 10 else 0              ; evaluates to 0
Multiple cases can share the same branch:
match 2: case 1 case 2: "one or two" else "other"
5.6 Choose Expressions
Choose expressions pattern match on union types, binding the inner value to a variable.
5.6.1 Basic Choose
Choose expressions match on the variant of a union value and bind the inner value.
Input	Result	
define Option union(Some: int, None)
choose Some(5): when v: Some: v + 1 else 0	6	
define Option union(Some: int, None)
choose None: when v: Some: v else -1	-1	
define Option union(Some: int, None)
let x Some(10)
choose x: when v: Some: v * 2 else 0	20	

5.6.2 Choose with Result
Choose works with any union type, including Result.
Input	Result	
define Result union(Ok: int, Err: String)
choose Ok(42): when v: Ok: v when e: Err: 0 else -1	42	
define Result union(Ok: int, Err: String)
choose Err("error"): when v: Ok: v when e: Err: 0 else -1	0	

5.6.3 Choose Else Branch
The else branch is evaluated when no when clause matches.
Input	Result	
define Option union(Some: int, None)
choose None: when v: Some: v else 99	99	

A. Standard Library Reference
A.1 Types
A.1.1 define Sum(left: int, right: int)
Deferred sum. Enables operator precedence by delaying evaluation.
left: int
 	Left operand
right: int
 	Right operand
A.1.2 define Difference(left: int, right: int)
Deferred difference. Enables operator precedence by delaying evaluation.
left: int
 	Left operand
right: int
 	Right operand
A.1.3 define Product(left: int, right: int)
Deferred product. Enables operator precedence by delaying evaluation.
left: int
 	Left operand
right: int
 	Right operand
A.1.4 define Quotient(left: int, right: int)
Deferred quotient. Enables operator precedence by delaying evaluation.
left: int
 	Left operand
right: int
 	Right operand
A.2 Operators
A.2.1 operator +(left: int, right: int) returns Sum
Addition. Lower precedence than multiplication and division.
left: int
 	Left addend
right: int
 	Right addend
A.2.2 operator -(left: int, right: int) returns Difference
Subtraction. Lower precedence than multiplication and division.
left: int
 	Minuend
right: int
 	Subtrahend
A.2.3 operator *(left: int, right: int) returns Product
Multiplication. Higher precedence than addition and subtraction.
left: int
 	Left factor
right: int
 	Right factor
A.2.4 operator /(left: int, right: int) returns Quotient
Division. Higher precedence than addition and subtraction.
left: int
 	Dividend
right: int
 	Divisor
A.2.5 operator div(left: int, right: int) returns int
Integer division, truncating toward zero.
left: int
 	Dividend
right: int
 	Divisor
A.2.6 operator mod(left: int, right: int) returns int
Modulo (remainder after integer division).
left: int
 	Dividend
right: int
 	Divisor
A.2.7 operator =(left: int, right: int) returns bool
Equality comparison.
left: int
 	Left operand
right: int
 	Right operand
A.2.8 operator <>(left: int, right: int) returns bool
Inequality comparison.
left: int
 	Left operand
right: int
 	Right operand
A.2.9 operator <(left: int, right: int) returns bool
Less than comparison.
left: int
 	Left operand
right: int
 	Right operand
A.2.10 operator >(left: int, right: int) returns bool
Greater than comparison.
left: int
 	Left operand
right: int
 	Right operand
A.2.11 operator <=(left: int, right: int) returns bool
Less than or equal comparison.
left: int
 	Left operand
right: int
 	Right operand
A.2.12 operator >=(left: int, right: int) returns bool
Greater than or equal comparison.
left: int
 	Left operand
right: int
 	Right operand
A.3 Functions
A.3.1 function -(right: int) returns int
Unary negation.
right: int
 	Value to negate
A.3.2 function +(right: int) returns int
Unary plus (identity).
right: int
 	Value to return unchanged
A.3.3 function abs(x: int) returns int
Absolute value.
x: int
 	Value whose absolute value to compute