Topazdocs
시작

토파즈 소개

토파즈는 애플리케이션 의도를 간결하고 일관된 문법으로 표현하는 프로그래밍 언어입니다.

토파즈는 애플리케이션의 의도를 간결하게 표현하는 프로그래밍 언어입니다. Python이나 TypeScript처럼 읽기 쉽지만, 같은 뜻을 여러 방식으로 쓰기보다 일관된 문법을 택합니다. 사람이 직접 쓰든 코드 생성 도구가 만들든 결과가 같은 규칙을 따르도록 설계했습니다.

기계를 세밀하게 제어해야 한다면 Rust가 더 알맞습니다. 토파즈는 그보다 한 층 위에서 명령줄 도구, 데이터 변환, 서비스 로직, 설정 처리, SQL·셸·경로를 다루는 프로그램에 집중합니다. 작성한 코드는 바로 실행할 수 있고, 필요하면 독립 실행 파일이나 Python 소스로 만들 수 있습니다.

이 페이지의 예제는 실제 토파즈 도구로 검사하고 실행합니다.

Lena Code 연동. 토파즈는 Lena Code와 함께 STUDIO HAZE 제품군을 이루는 자매 제품입니다. Lena Code의 변환 작업에서 토파즈를 입력 언어와 출력 언어로 사용할 수 있습니다. 자세한 범위는 Lena Code 연동에서 설명합니다.

유니코드를 기본으로

식별자는 렉서부터 Unicode입니다. 도메인 단어를 로마자로 흉내 내지 않고 그대로 코드에 둡니다.

TOPAZ
function greet(name: string, language: string) -> string {
    return match language {
        case "한국어" => "안녕하세요, {name}님!"
        case "Русский" => "Привет, {name}!"
        case _ => "Hello, {name}!"
    }
}

let 사용자 = "김토파즈"
print(greet(사용자, "한국어"))
print(greet("Topaz", "Русский"))
OUTPUT
안녕하세요, 김토파즈님!
Привет, Topaz!

사용자는 평범한 변수입니다. 유니코드 식별자는 예외 기능이 아니라 언어의 기본입니다. 토파즈는 작성한 이름을 몰래 다른 형태로 바꾸지 않으며, 서로 헷갈릴 수 있는 모듈 이름은 오류로 처리합니다.

알아둘 네 가지

작고 닫힌 표면

의도마다 쓰는 방법은 하나입니다. 복구 가능한 실패는 Result, 부재는 옵셔널, 정리는 defer, match는 빠짐없이 다루는 것을 기본으로 삼습니다. 이런 정책을 언어가 정하므로 파일마다 방언을 새로 만들지 않아도 됩니다.

TOPAZ
function parsePort(raw: string) -> Result<int, string> {
    let n = toInt(raw) ?? -1
    if n < 1 {
        return Err("not a port: {raw}")
    }
    return Ok(n)
}

function startup(raw: string) -> Result<string, string> {
    defer print("config closed")
    let port = parsePort(raw)?
    return Ok("listening on {port}")
}

print("{startup("8080")}")
print("{startup("http")}")
OUTPUT
config closed
Ok(listening on 8080)
config closed
Err(not a port: http)

? 연산자는 Err를 전파하고, defer는 어떤 종료 경로에서도 실행됩니다. 그래서 위 출력에 config closed가 두 번 나옵니다.

코드 생성 도구와 함께 쓰기 좋은 문법

토파즈는 사람이 쓴 코드와 자동 생성된 코드가 같은 규칙을 따르도록 문법의 선택지를 의도적으로 줄였습니다. 잘못된 형태는 명확한 오류가 되고, 이 사이트의 예제도 실제 도구로 검사합니다. 덕분에 코드가 어디서 왔든 읽고 고치고 검토하는 방식이 달라지지 않습니다.

의도를 구조로 보존하는 템플릿

sql, sh, path 문자열은 템플릿입니다. 문자열 하나로 뭉개지지 않고 파트와 보간을 따로 보존하는 구조화된 값입니다.

TOPAZ
let table = "users"
let q = sql"select * from {table} where active = {true}"
print("{q}")
OUTPUT
<sql template, 3 part(s), 2 interpolation(s)>

현재는 템플릿의 구조를 요약해 보여줍니다. SQL 실행기나 셸 실행기처럼 각 분야에 맞춘 렌더링 기능은 이후 버전에서 추가할 예정입니다.

정적 검사와 여러 출력 방식

토파즈는 정적 타입 언어입니다. 프로그램을 실행하기 전에 파일 전체의 타입을 검사합니다.

TOPAZ
type TrafficLight = "red" | "yellow" | "green"

function next(light: TrafficLight) -> TrafficLight {
    return match light {
        case "red" => "green"
        case "green" => "yellow"
        case _ => "red"
    }
}

topaz run은 코드를 읽고 이름과 타입을 검사한 뒤 곧바로 실행합니다. 같은 소스에서 topaz emittopaz build를 사용하면 다른 형태의 결과물을 만들 수 있습니다. Rust 대상은 독립 실행형 네이티브 바이너리를 만들고, Python 대상은 program.py와 실행에 필요한 topaz_py_rt.py를 만듭니다.

Rust와 Python 출력은 같은 언어 규칙을 따르도록 함께 시험합니다. 현재 지원 범위와 제한 사항은 도구 모음 상태에서 확인할 수 있습니다.

SH
topaz build app.tpz --target python --out-dir py-out

토파즈가 맞지 않는 경우

소유권과 수명을 직접 제어해야 하거나, 안전하지 않은 메모리 경계와 임베디드 환경을 다루거나, 성능 병목을 세밀하게 최적화해야 한다면 Rust, C, Zig가 더 알맞습니다. 토파즈는 그런 저수준 제어를 목표로 하지 않습니다.

토파즈는 반대편 작업을 위한 언어입니다. 시스템 레벨 소스 표면 없이 배포 가능한 애플리케이션 로직, 도메인 언어가 그대로 남는 코드, 사람과 에이전트가 일관되게 만들어 낼 수 있는 작은 문법을 원할 때 맞습니다.

여기서 시작하세요

말하는 방법은 하나.