# Five — Where Harbour Meets Go > **Keep your xBase code. Gain all of Go.** Five is a fusion language that transpiles Harbour PRG code to Go native binaries. Don't throw away 30 years of xBase business logic — use Go's modern power with PRG syntax. ## Why Five ### 1. Your existing code just works ```prg USE customers NEW INDEX ON Upper(name) TO cust_name SEEK "CHARLES" ? customers->name, customers->balance ``` This runs as-is. DBF, NTX, CDX — all supported. Thousands of lines of existing PRG code build with Five unchanged. ### 2. Every Go package, directly from PRG ```prg IMPORT "strings" IMPORT "database/sql" IMPORT _ "modernc.org/sqlite" PROCEDURE Main() LOCAL db, aRows, i ? strings.ToUpper("hello five!") db := sql.Open("sqlite", ":memory:") db:Exec("CREATE TABLE users (id INTEGER, name TEXT)") db:Exec("INSERT INTO users VALUES (1, 'Charles')") aRows := SqlScan(db, "SELECT * FROM users") FOR i := 1 TO Len(aRows) ? aRows[i]["name"] NEXT db:Close() RETURN ``` One `IMPORT` line gives you access to 500,000+ Go packages. SQL, HTTP, WebSocket, JSON, crypto, regex — all from PRG code. No `#pragma BEGINDUMP` needed. ### 3. Goroutines are PRG syntax ```prg LOCAL ch := Channel() SPAWN {|| ch <- HeavyWork() } // launch goroutine ? "doing other work..." result := <- ch // receive result WATCH CASE msg := <- chServer1 ? "Server 1 replied:", msg CASE msg := <- chServer2 ? "Server 2 replied:", msg CASE <- chTimeout ? "Timeout!" END WATCH ``` Concurrency that's impossible in Harbour — natural in Five. `SPAWN`, `<-`, `WATCH` — these ARE Go's goroutine, channel, select. ### 4. Builds to native binary ```bash five build myapp.prg -o myapp ./myapp # single executable, zero dependencies ``` No JVM. No interpreter. No runtime. Go compiler produces native binary. Cross-compile to Linux, macOS, Windows. ### 5. Safe code by default ```prg PROCEDURE Main() LOCAL cName, nAge // all variables must be declared cName := "Charles" nAge := 30 ? cName, nAge DEFER db:Close() // guaranteed resource cleanup RETURN ``` Five's compiler checks automatically: - Undeclared variable → warning - Unused variable → hint - `DEFER` prevents resource leaks ## For Harbour Developers **Nothing to change. Everything to gain.** | Existing Harbour | Five adds | |-----------------|-----------| | DBF/NTX/CDX | + **SQLite, PostgreSQL, MySQL** | | Single thread | + **goroutine parallelism** | | C library dependency | + **500K Go packages** | | Interpreter/HRB | + **native binary** | | Windows focused | + **Linux, macOS, cloud** | ## For Go Developers **Data processing, 10x faster to write.** ```prg // Look how concise this is USE sales NEW INDEX ON DToS(date) + Str(amount) TO sales_idx SET FILTER TO amount > 1000 GO TOP DO WHILE !Eof() ? date, customer, amount SKIP ENDDO ``` In Go, this requires CSV parsing, struct definitions, sort interfaces, filter loops... One xBase command replaces 20 lines of Go code. ## Key Numbers ``` Harbour compat: 98% (232/236 test files) RTL functions: 351 Go interop: FastPath 15M calls/sec Tests: 13 packages ALL PASS Build output: single native binary ``` ## Five-Only Syntax ```prg // Multi-return cName, nAge := GetUserInfo() // DEFER — automatic cleanup DEFER db:Close() // Channel operators ch <- "hello" msg := <- ch // WATCH — channel multiplexing WATCH CASE msg := <- ch1 CASE <- chTimeout END WATCH // Parallel FOR PARALLEL FOR i := 1 TO 100000 aResult[i] := Process(aData[i]) NEXT // ASYNC/AWAIT future := ASYNC HeavyQuery() result := AWAIT future // Nil-safe ? customer?:address?:city // f-string ? f"Name: {cName}, Age: {nAge}" // Slice aSub := aData[2:5] // Direct Go package calls ? strings.ToUpper("hello") ? math.Sqrt(144) ? fmt.Sprintf("%.2f", 3.14) ``` ## Getting Started ```bash # Install go install github.com/aspect-build/five@latest # Run five run hello.prg # Build five build hello.prg -o hello # Debug five debug hello.prg ``` ```prg // hello.prg PROCEDURE Main() ? "Hello, Five!" ? f"Today: {Date()}" RETURN ``` --- **Five — 30 years of xBase heritage, powered by Go's future.**