Quick Reference

A complete reference of all keywords, operators, and syntax in the Meow language.

Keywords

MeowMeaningExample
nyanVariable declarationnyan x = 42
meowFunction definitionmeow add(a int, b int) int { bring a + b }
bringReturn a valuebring x + 1
sniffConditional branch (if)sniff (x > 0) { ... }
scratchElse branch} scratch { ... }
purrLoop (range-based)purr i (10) { ... }
pawLambda (anonymous function)paw(x int) { x * 2 }
nyaPrint valuesnya("Hello!")
lickTransform each element in a list (map)lick(nums, paw(x) { x * 2 })
pickySelect elements matching a condition (filter)picky(nums, paw(x) { x > 0 })
curlCombine a list into a single value (reduce)curl(nums, 0, paw(a, x) { a + x })
peekBranch based on a value (pattern match)peek(v) { 0 => "zero", _ => "other" }
hissRaise an errorhiss("something went wrong")
gagCatch errors (try/recover)gag(paw() { risky() })
is_furballCheck if a value is an erroris_furball(result)
nabImport standard library packagenab "http"
flauntExport (reserved)
yarnTrue (boolean literal)nyan ok = yarn
hairballFalse (boolean literal)nyan ng = hairball
catnapNil (represents no value)nyan nothing = catnap
kittyStruct (composite type) definitionkitty Cat { name: string }

Type Keywords

Meow supports gradual static typing. Type keywords can annotate variables, function parameters, and return values.

TypeMeaningExample
int64-bit signed integernyan x int = 42
float64-bit floating-pointnyan pi float = 3.14
stringUTF-8 stringnyan name string = "Nyantyu"
boolBooleannyan ok bool = yarn
furballError valuepaw(err furball) { ... }
litterList of valuesnyan nums litter = [1, 2, 3]

Type Annotation Syntax

Variables:

nyan x int = 42
nyan name string = "Nyantyu"

Function parameters and return type:

meow add(a int, b int) int {
  bring a + b
}

Go-style grouped parameter types — parameters without a type receive the type of the next parameter with a type:

meow add(a, b int) int {
  bring a + b
}
# a and b are both int

Operators

Arithmetic

OperatorMeaningExample
+Addition / string concatenation1 + 2, "a" + "b"
-Subtraction / unary negation5 - 3, -x
*Multiplication2 * 3
/Division10 / 2
%Modulo10 % 3

Comparison

OperatorMeaningExample
==Equalx == 0
!=Not equalx != 0
<Less thanx < 10
>Greater thanx > 0
<=Less than or equalx <= 100
>=Greater than or equalx >= 1

Logical

OperatorMeaningExample
&&Logical AND (short-circuit)x > 0 && x < 10
||Logical OR (short-circuit)x == 0 || x == 1
!Logical NOT!ok

Special

OperatorMeaningExample
|=|Pipe (chain operations)nums |=| lick(double)
~>Error recovery (catch)divide(10, 0) ~> 0
.Member accesscat.name, file.snoop("x")
..Range (inclusive)1..10
=>Match arm separator0 => "zero"
=Assignmentnyan x = 1

Operator Precedence

From lowest to highest:

PrecedenceOperatorsDescription
1 (lowest)~>Error recovery
2||Logical OR
3&&Logical AND
4== !=Equality
5< > <= >=Comparison
6|=|Pipe
7+ -Addition, subtraction
8* / %Multiplication, division, modulo
9! - (unary)Unary operators
10 (highest)() [] .Call, index, member access

Literals

TypeExampleDescription
Integer42Decimal integer
Float3.14Floating-point number
String"Hello, world!"Double-quoted, \\ for escape
List[1, 2, 3]Ordered collection
Map{"key": "value"}String-keyed dictionary

Delimiters

SymbolMeaningExample
( )Function call / groupingadd(1, 2)
{ }Block / map literalmeow f() { ... }
[ ]List / index access[1, 2, 3], nums[0]
,Separatoradd(a, b)
:Type annotation / map key-valuename: string, {"k": v}

Comments

# Line comment

-~ Block comment
   can span multiple lines ~-

Syntax Examples

Variable Declaration

nyan x = 42
nyan greeting = "Hello!"
nyan pi float = 3.14
nyan cats_are_great = yarn
nyan nothing = catnap

Function Definition

meow add(a int, b int) int {
  bring a + b
}

nya(add(1, 2))   # => 3

Struct (Kitty) Definition

kitty Cat {
  name: string
  age: int
}

nyan nyantyu = Cat("Nyantyu", 3)
nya(nyantyu)            # => Cat{name: Nyantyu, age: 3}
nya(nyantyu.name)       # => Nyantyu
nya(nyantyu.age)        # => 3

Fields are defined with name: type syntax. Instances are created by calling the type name as a constructor. Fields are accessed with . notation.

Conditionals

sniff (x > 0) {
  nya("positive")
} scratch sniff (x == 0) {
  nya("zero")
} scratch {
  nya("negative")
}

Loops

Count form — iterates from 0 to n-1:

purr i (10) {
  nya(i)
}
# prints 0, 1, 2, ..., 9

Range form — iterates from a to b inclusive:

purr i (1..20) {
  nya(i)
}
# prints 1, 2, 3, ..., 20

Error Handling

Use hiss to raise an error and stop execution. The error message is prefixed with Hiss! automatically.

meow divide(a int, b int) int {
  sniff (b == 0) {
    hiss("division by zero")
  }
  bring a / b
}

nya(divide(10, 0))   # => Hiss! division by zero

Multiple arguments are joined with spaces:

hiss("unexpected value:", x)

Use gag to catch errors. Wrap risky code in a lambda and pass it to gag. If the code panics, gag returns a Furball (error value) instead of crashing. Use is_furball to check if a value is an error.

nyan result = gag(paw() { divide(10, 0) })

sniff (is_furball(result)) {
  nya("caught:", result)
} scratch {
  nya("ok:", result)
}
# => caught: Hiss! division by zero

If the code succeeds, gag returns its result normally:

nyan ok = gag(paw() { divide(10, 2) })
nya(ok)   # => 5

Error Recovery with ~>

The ~> (cat tail arrow) operator provides concise error recovery. If the left-hand expression panics, the fallback on the right is used instead. The ~ resembles a cat’s tail, and > points to the fallback.

nyan val = divide(10, 0) ~> 0
nya(val)   # => 0

When no error occurs, the original result is returned:

nyan val = divide(10, 2) ~> 0
nya(val)   # => 5

The fallback can also be a handler function that receives the error:

nyan val = divide(10, 0) ~> paw(err) { 42 }
nya(val)   # => 42

Lambdas

nyan double = paw(x int) { x * 2 }
nya(double(5))   # => 10

List Operations

nyan nums = [1, 2, 3, 4, 5]

lick(nums, paw(x) { x * 2 })           # => [2, 4, 6, 8, 10]
picky(nums, paw(x) { x % 2 == 0 })     # => [2, 4]
curl(nums, 0, paw(acc, x) { acc + x })  # => 15

Map Literals

nyan headers = {
  "Content-Type": "application/json",
  "Authorization": "Bearer token123"
}

Pipe

nyan double = paw(x) { x * 2 }
nums |=| lick(double)

The pipe operator passes the left value as the first argument of the right expression:

[1, 2, 3] |=| lick(paw(x) { x * 2 }) |=| nya
# => [2, 4, 6]

Pattern Matching

nyan result = peek(score) {
  0 => "zero",
  1..10 => "low",
  11..100 => "high",
  _ => "off the charts"
}

Patterns can be:

  • Literal — match a specific value (0, "hello", yarn)
  • Range — match an inclusive range (1..10)
  • Wildcard — match anything (_)

Import (Nab)

Use nab to import a standard library package:

nab "file"
nab "http"
nab "testing"

After importing, call package functions with package.function() syntax:

nab "file"
nyan content = file.snoop("data.txt")
nya(content)

Available packages: file, http, testing. See stdlib.md for details.

Member Access

The . operator accesses fields on kitty instances and functions on imported packages:

# Kitty field access
nyan nyantyu = Cat("Nyantyu", 3)
nya(nyantyu.name)   # => Nyantyu

# Package function call
nab "http"
http.pounce("https://example.com") |=| nya

Testing

Test functions use the test_ prefix and catwalk_ prefix:

nab "testing"

meow test_addition() {
  expect(1 + 1, 2, "basic addition")
}

meow test_string() {
  judge("hello" == "hello")
}

Run tests with meow test:

meow test my_test.nyan

See stdlib.md for judge, expect, refuse, and other testing functions.