Examples you can try.
Each complete source file passes tyc check with v1.0.0-beta.3. Start a project, paste an example into src/main.ty and check it.
tyc init hello
cd helloNullable values
Narrow an optional value before passing it to a function.
def find_user(uid: int) -> str?:
return "ada" if uid == 1 else None
def greet(user: str) -> None:
print(f"hello, {user}")
def main() -> None:
let user: str? = find_user(1)
if user is not None:
greet(user)
main()Check with tyc check src/; compile with tyc build. Generated helpers are included in build/ when needed.
Explicit bindings
Use let for a fixed binding and mut for a value you intend to reassign.
let limit: int = 3
mut attempts: int = 0
attempts += 1
print(attempts < limit)Check with tyc check src/; compile with tyc build. Generated helpers are included in build/ when needed.
Exhaustive matching
Handle every variant of a sealed union.
class Circle:
radius: float
class Square:
side: float
type Shape = Circle | Square
def area(shape: Shape) -> float:
match shape:
case Circle(radius):
return 3.14 * radius * radius
case Square(side):
return side * sideCheck with tyc check src/; compile with tyc build. Generated helpers are included in build/ when needed.
Errors as values
Propagate a Result inside a function with a matching error type.
def divide(a: int, b: int) -> Result[int, str]:
if b == 0:
return Err("division by zero")
return Ok(a // b)
def calculate() -> Result[int, str]:
let value: int = divide(10, 2)?
return Ok(value * 2)Check with tyc check src/; compile with tyc build. Generated helpers are included in build/ when needed.
Classes become dataclasses
Declare typed fields and let the compiler generate the constructor.
class User:
name: str
enabled: bool = TrueCheck with tyc check src/; compile with tyc build. Generated helpers are included in build/ when needed.
Concurrent fetching
Run independent calls in a task group. This example prints ada: 0 posts.
import asyncio
type UserId = int
class User:
name: str
class Post:
title: str
@gatherable
async def fetch_user(uid: UserId) -> User:
await asyncio.sleep(0)
return User(name="ada")
@gatherable
async def fetch_posts(uid: UserId) -> list[Post]:
await asyncio.sleep(0)
return []
async def dashboard(uid: UserId) -> str:
gather:
user = fetch_user(uid)
posts = fetch_posts(uid)
return f"{user.name}: {len(posts)} posts"
async def main() -> None:
print(await dashboard(1))
asyncio.run(main())Check with tyc check src/; compile with tyc build. Generated helpers are included in build/ when needed.
Configuration boundaries
Validate a port and propagate a failure through an explicit Result.
def parse_port(raw: str) -> Result[int, str]:
if not raw.isdecimal():
return Err("port must be a number")
let port: int = int(raw)
if port < 1 or port > 65535:
return Err("port must be between 1 and 65535")
return Ok(port)
def configure(raw_port: str) -> Result[int, str]:
let port: int = parse_port(raw_port)?
return Ok(port)Check with tyc check src/; compile with tyc build. Generated helpers are included in build/ when needed.
Learn the language.
Walk through the rules, with worked examples and emitted Python.