Tya Guide
This guide is for people trying Tya for the first time. It starts with installation, then walks through writing a small program, running it, building an executable, and using the basic language features.
For the exact language contract, read the specification. This guide is practical: copy the examples, run the commands, and change the code as you go.
Install
Download the latest release for your platform from GitHub:
curl -fsSL https://tya-lang.org/install.sh | sh
Or install manually from the release page:
https://github.com/komagata/tya/releases/latest
Check that the command is available:
tya version
Tya builds native executables through its bundled toolchain support. If native builds fail on your machine, run:
tya doctor
Create a Program
Create a new directory and a file named hello.tya.
mkdir hello-tya
cd hello-tya
name = "Tya"
print("Hello, {name}")
Run it:
tya run hello.tya
Expected output:
Hello, Tya
Tya source files use .tya. Lowercase files such as hello.tya and
main.tya can be used as script entry points.
Check and Format
Use tya check before running or building when you want a fast validity check.
tya check hello.tya
Use tya format to print canonical source:
tya format hello.tya
Use -w to rewrite the file:
tya format -w hello.tya
Formatting is part of Tya’s language design. A valid program has one canonical source representation.
Build an Executable
Build a native executable:
tya build hello.tya -o hello
Run the built program:
./hello
On Windows, use an .exe output name:
tya build hello.tya -o hello.exe
hello.exe
tya run is for quick local execution. tya build creates a reusable
executable.
A Small Script
Replace hello.tya with a slightly larger program.
greet = name ->
"Hello, {name}"
names = ["Ada", "Matz", "Tya"]
for name in names
print(greet(name))
Run it:
tya run hello.tya
This example shows three core ideas:
- functions are values and use
->; - arrays use
[...]; - indentation defines blocks.
Values
Tya is dynamically typed. Values carry runtime kinds.
name = "Tya"
count = 3
price = 12.5
ready = true
missing = nil
data = b"abc"
Strings use interpolation:
print("count = {count}")
Arrays are mutable:
items = [1, 2]
items.push(3)
print(items[0])
print(items.len())
Dictionaries use string keys:
user = { name: "Ada", admin: true }
print(user["name"])
user["city"] = "London"
Primitive values have methods:
print(" tya ".trim().upper())
print(42.to_s())
print([1, 2, 3].len())
Names
Use snake_case for values, functions, methods, files, import paths, and
dictionary keys.
Use PascalCase for classes and interfaces.
Use SCREAMING_SNAKE_CASE for constants.
user_name = "Ada"
MAX_RETRIES = 3
class UserProfile
initialize = name ->
self.name = name
Leading _ does not make a binding private. For class members, use private.
Control Flow
Use if, elseif, and else.
age = 20
if age >= 20
print("adult")
elseif age >= 13
print("teen")
else
print("young")
Use and, or, and not for boolean logic.
if ready and not disabled
print("ready")
Use while for repeated work:
count = 0
while count < 3
print(count)
count = count + 1
Use for to iterate arrays:
items = ["a", "b", "c"]
for item in items
print(item)
for item, index in items
print("{index}: {item}")
Use break to leave the nearest loop and continue to skip to the next
iteration.
Functions
Functions use ->. Calls always use parentheses.
add = a, b -> a + b
print(add(2, 3))
Use an indented body for multiple statements. The final expression is returned.
double = value ->
result = value * 2
result
print(double(21))
Use return for early return:
label = name ->
if name == ""
return "anonymous"
name
Functions can be passed to other functions:
items = [1, 2, 3]
print(items.map(item -> item * 2))
Errors
Use error(...) to create an error value. Use raise, try, and catch to
handle failures.
require_name = name ->
if name == ""
raise error("name is required")
name
try
print(require_name(""))
catch err
message = err["message"]
print("error: {message}")
Use try/finally when cleanup must run.
try
print("work")
finally
print("cleanup")
Split Code into Files
Create greeting.tya:
hello = name ->
"Hello, {name}"
Create main.tya:
import greeting
print(greeting.hello("Tya"))
Run the entry file:
tya run main.tya
Use an alias when a package name is long:
import net/http as http
resp = http.Client.get("https://example.com/")
print(resp["status"])
Classes
Classes are runtime values. initialize is the constructor hook.
class User
initialize = name ->
self.name = name
label = ->
"user:{self.name}"
user = User("Ada")
print(user.label())
Use private for private class members.
class Counter
private count = 0
increment = ->
self.count = self.count + 1
self.count
PascalCase files such as User.tya are class files. They are library files,
not script entry points.
Standard Library
Standard-library packages are imported like user files.
import json as json
import time as time
json_text = json.Json.dump({ name: "Tya" })
print(json_text)
now = time.Time.now()
print(now.format("rfc3339"))
Common packages include json, toml, csv, url, time, random,
math, file, path, unittest, template, markdown, compress, log,
io, net/ip, net/socket, net/http, channel, and sync.
Generated API documentation can be produced from source comments:
tya doc --json stdlib
Tests
Tya test files end with _test.tya.
Create hello_test.tya:
import unittest
class AdditionTest extends TestCase
test_addition_works = ->
self.assert_equal(4, 2 + 2, "addition")
Run tests:
tya test
Show coverage when your project uses coverage-supported tests:
tya test --cover
tya cover
Lint and Docs
Run lint:
tya lint
tya lint --fix .
Generate docs from source comments:
tya doc
tya doc --html ./site src
Packages
Projects use tya.toml for metadata and dependencies. Resolved dependencies
are written to tya.lock.
tya install
tya add https://github.com/komagata/tya-sqlite --tag v0.1.0
tya update
tya outdated
Git and local path dependencies are supported. Tya does not currently use a central package registry.
Cross Compilation
Build the native target explicitly:
tya build --target native main.tya -o app
Build WebAssembly targets:
tya build --target wasm32-wasi examples/wasm/hello.tya -o hello.wasm
tya build --target wasm32-browser examples/wasm/hello.tya -o hello.wasm
tya doctor wasm
tya run is native-only.
Everyday Command List
tya version
tya run main.tya
tya check main.tya
tya format -w .
tya build main.tya -o app
tya test
tya lint
tya doc
tya doctor
After this guide, read the specification when you need exact syntax, runtime behavior, package rules, or standard-library boundaries.