Syntax Keywords
The alias keyword is the core keyword of the Alia language, used to define new syntax structures. This document describes the definition forms, matching mechanism, and invocation forms of alias.
1. Basic Syntax
alias <Keys pattern> -> <Stack implementation>
alias <Keys pattern> -> <Stack implementation> => <Key aliasName>
alias <Keys pattern> -> <Object type> <Stack implementation>
alias <Keys pattern> -> <Object type> <Stack implementation> => <Key aliasName>
alias <Keys pattern> => <Key aliasName>
alias <Keys pattern>
alias <Keys pattern> -> <Object type>
-> <Object type> declares the return type of the implementation body, and => <Key aliasName> declares the registered name of the syntax keyword. Declarations without an implementation body only register the matching pattern and produce no executable action.
Inline Alias Expressions
When evaluated as an expression, alias returns an Alias object:
alias <Keys pattern> -> <Stack implementation>
alias <Keys pattern> -> <Object type> <Stack implementation>
After an inline alias expression is assigned to a variable, the variable holds an Alias object, which can be passed as an argument or stored in an object.
const add = alias <Number a> and <Number b> -> Number { a + b }
assert (call add [1, 2]) == 3 error 'inline alias mismatch'
2. Matching Mechanism
Match Priority
When both short and long pattern definitions exist, matching the long pattern in code executes the long one:
alias testmatch <Boolean condition> <Stack stack> -> {
if condition { call stack.run }
}
alias testmatch <Boolean condition> <Stack stack1> else <Stack stack2> -> {
if condition { call stack1.run } else { call stack2.run }
}
let result1 = ''
testmatch true {
result1 = 'yes'
} else {
result1 = 'no'
}
assert result1 == 'yes' error 'long match mismatch'
3. Keyword Aliases
=> provides a registered name for a matching pattern. When the first item of the pattern is not a keyword, the explicit name determines the invocation entry:
alias <Number a> and <Number b> -> Number { a + b } => add
assert (add 1 and 2) == 3 error 'named alias mismatch'
A named alias registers both the syntax keyword and an Alias object of the same name once defined. See Section 4 for how the object form is stored and invoked.
4. Anonymous Aliases
An anonymous alias has no registered name; the alias expression returns an Alias object after evaluation and is assigned to a variable:
const add = alias <Number a> and <Number b> -> Number { a + b }
assert (add 1 and 2) == 3 error 'anonymous alias mismatch'
const applyOperation = alias <Alias op> and <Number a> and <Number b> -> Number {
call op [a, b]
}
assert (call applyOperation [add, 5, 3]) == 8 error 'higher order mismatch'
The alias expression returns an Alias object after evaluation; this object can be stored and passed like any ordinary value.
call Syntax Invocation (Dynamic Dispatch)
Invocation with known patterns should prefer the syntax form. The call array/object forms are reserved for dynamic dispatch scenarios where the target or argument shape can only be determined at runtime, as well as expression positions where the syntax form cannot be used:
const add = alias <Number a> and <Number b> -> Number { a + b }
assert (call add [1, 2]) == 3 error 'array call mismatch'
assert (call add *[b:2, a:1]) == 3 error 'object call mismatch'
call alias [arg1, arg2, ...]: passes an Array, with values supplied in parameter declaration ordercall alias *[key:value, key2:value2, ...]: passes an Object, with keys corresponding to parameter names and values serving as argument values
Aliases in Objects
Once an anonymous alias is stored in an object, it is invoked through a member target:
const helpers = *[
add: alias <Number a> and <Number b> -> Number { a + b },
multiply: alias <Number a> and <Number b> -> Number { a * b }
]
assert (call helpers.add [3, 4]) == 7 error 'object alias add mismatch'
assert (call helpers.multiply [3, 4]) == 12 error 'object alias multiply mismatch'
Value Access and Execution for Zero-Argument Forms
Zero-argument syntax keywords execute as standalone statements; retrieving their value in an expression position requires call. For a zero-argument Alias object, a direct reference obtains the object, while call executes it:
let a = 21
let b = 21
alias plusAandB -> { a + b }
assert (call plusAandB) == 42 error 'keyword call mismatch'
const plusAandBObj = alias -> Number { a + b }
assert (call plusAandBObj) == 42 error 'object call mismatch'
5. Complex Pattern Matching
Patterns with Parameters
alias <Number a> plus <Number b> equals <Number c> -> Boolean {
a + b == c
}
assert (1 plus 2 equals 3) == true error 'pattern match mismatch'
assert (2 plus 3 equals 6) == false error 'pattern mismatch mismatch'
Nested Patterns
alias whenMatch <Boolean condition> then <Stack stack1> else <Stack stack2> -> {
condition ? call stack1.run : call stack2.run
}
let nestedResult = ''
whenMatch true then { nestedResult = 'yes' } else { nestedResult = 'no' }
assert nestedResult == 'yes' error 'nested match mismatch'
Parameter Type Semantics
The matching behavior of parameters declared with <Type name> differs by type:
<Stack stack>: matches Stack values or stack literals — stack literals ({}/*{}/-> {}), variables holding a Stack, and expressions returning a Stack can all serve as arguments. The static type must beStack; non-Stack values (such as numbers or strings) reportTYPE_ARGUMENT_MISMATCHat check time andRUNTIME_TYPE_ERRORat runtime.<Alias aliasObject>: matches Alias objects —alias ... -> {...}literals, variables holding an Alias, or a named alias identifier. The actual type of the argument is validated; non-Alias values (such as stack literals or numbers) reportTYPE_ARGUMENT_MISMATCHat check time andRUNTIME_TYPE_ERRORat runtime.
const apply = alias <Alias op> and <Number a> -> Number { call op [a] }
const incAlias = alias <Number x> -> Number { x }
assert (call apply [incAlias, 5]) == 5 error 'alias param mismatch'
let caught = false
try { call apply [{}, 5] } catch e { caught = true }
assert caught == true error 'alias type check mismatch'
<Alias> parameters can receive stored Alias objects both in syntax-form invocations and in call array/object invocations.
6. Removing and Disabling Aliases
Removing an Alias
alias customPrint <Value val> -> {
print val
}
customPrint 'Hello'
remove customPrint
After removal the name no longer matches; invoking it raises an undefined-alias error:
alias tempAlias <Number val> -> Number {
val
}
assert (tempAlias 42) == 42 error 'before remove mismatch'
remove tempAlias
let removed = false
try { tempAlias 1 } catch e { removed = true }
assert removed == true error 'remove mismatch'
Disabling an Alias
alias toggleAlias <String val> -> String {
'enabled: ' .. val
}
assert (toggleAlias 'test') == 'enabled: test' error 'before disable mismatch'
disable toggleAlias
let disabled = false
try { toggleAlias 'test' } catch e { disabled = true }
assert disabled == true error 'disable mismatch'
enable toggleAlias
assert (toggleAlias 'test') == 'enabled: test' error 'enable mismatch'
The targets of remove, disable, and enable are alias names, without any parameter pattern.
7. Example Code
alias repeat3 <Number times> times <Stack stack> -> {
for { let i = 0 } i < times { i ++ } {
call stack.run
}
}
let repeatCount = 0
repeat3 3 times {
repeatCount = repeatCount + 1
}
assert repeatCount == 3 error 'repeat mismatch'
alias greet <String name> with <String? greeting> -> String {
(greeting ?? 'Hello') .. ', ' .. name .. '!'
}
assert (greet 'Alice' with 'Hello') == 'Hello, Alice!' error 'greet mismatch'
assert (greet 'Bob' with 'Hi') == 'Hi, Bob!' error 'greet with mismatch'
alias <Number num> squared -> Number {
num * num
}
alias <Number num> cubed -> Number {
num * num * num
}
assert (5 squared) == 25 error 'squared mismatch'
assert (3 cubed) == 27 error 'cubed mismatch'
alias choose <Boolean c> between <Value a> and <Value b> -> Value {
c ? a : b
}
assert (choose true between 'Yes' and 'No') == 'Yes' error 'choose mismatch'
const numbers = [1, 2, 3, 4, 5]
const double = alias <Number x> -> Number { x * 2 }
let doubledTotal = 0
each n in numbers {
const d = call double [n]
doubledTotal = doubledTotal + d
}
assert doubledTotal == 30 error 'each alias mismatch'