docs: Five Philosophy — the bible of why Five exists

The founding document of Five, written as a manifesto:
- Why 30 years of xBase code must not be discarded
- Why Go is the right foundation for the next 50 years
- Why human-readable code matters more in the AI era
- What was designed: 5 principles, 5 architectures
- The vision: living code that bridges past and future

"Code fades, but thought endures."

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-31 12:04:40 +09:00
parent 542373572f
commit 409c82dd3c
2 changed files with 548 additions and 0 deletions

251
docs/five-philosophy-en.md Normal file
View File

@@ -0,0 +1,251 @@
# Five — Code Fades, but Thought Endures
> *"Good code is not what machines execute, but what humans read."*
> — Charles KWON OhJun
---
## Prologue: The Weight of 30 Years
In the 1990s, xBase languages — dBASE, Clipper, Harbour — were the heartbeat of millions of businesses worldwide. They calculated payroll, managed inventory, tracked customers. People's livelihoods depended on that code.
Then the world changed. Java came. .NET came. Python came. Now AI has come.
But those payroll systems are still running. Thirty-year-old PRG code still calculates someone's salary today.
**Should we throw it away?**
I believe we should not.
---
## Chapter 1: Design That Preserves
### Code is an Asset
The most expensive thing in software is not building something new. It's **rebuilding what has already been proven**.
Code that has run for 30 years contains thousands of bug fixes. Hundreds of tax regulation changes are embedded in it. Undocumented business rules live inside those `IF` statements.
"Modernizing" this to Python means resetting 30 years of experience to zero.
**Five's First Principle: Don't change a single line of existing code.**
```prg
// This code was written in 1995
USE customers NEW
SET FILTER TO balance > 10000
GO TOP
DO WHILE !Eof()
? name, balance
SKIP
ENDDO
// It runs as-is in Five, 2026.
// And now, in the same file:
IMPORT "database/sql"
db := sql.Open("postgres", connStr)
```
---
## Chapter 2: Why Go
### Three Questions When Choosing a Language
**1. Will it still be alive in 10 years?**
Go was created by Google. But that's not why it survives. Go survives because **it is simple**.
Generics came late to Go. Intentionally. Go has no exceptions. Intentionally. Go has no inheritance. Intentionally.
A language that rejects complexity doesn't follow trends. Just as C has survived 50 years, Go is built to survive the next 50.
**2. Does it align with the future of hardware?**
CPUs no longer get faster. They get more cores. Go's goroutines were designed for this future.
```prg
// Process 100,000 items across 8 cores
PARALLEL FOR i := 1 TO 100000
aResult[i] := ProcessItem(aData[i])
NEXT
```
Other languages require thread pools, mutexes, deadlock analysis. In Five, it's one line.
**3. Is the output self-contained?**
Go produces a single binary. No JVM. No Python interpreter. No Node.js runtime.
```bash
five build payroll.prg -o payroll
scp payroll server:/usr/local/bin/
# Done. Zero dependencies.
```
You never need to ask a customer to install Java on their server.
---
## Chapter 3: Code in the Age of AI
### AI Changed Everything, Except One Thing
In 2025, AI learned to write code. But **understanding code is still a human task**.
AI-generated Go:
```go
func processCustomers(db *sql.DB, threshold float64) ([]CustomerResult, error) {
rows, err := db.QueryContext(ctx, `SELECT c.id, c.name,
COALESCE(SUM(o.amount), 0) as total FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
GROUP BY c.id, c.name HAVING COALESCE(SUM(o.amount), 0) > $1`, threshold)
if err != nil {
return nil, fmt.Errorf("query customers: %w", err)
}
defer rows.Close()
var results []CustomerResult
for rows.Next() {
var r CustomerResult
if err := rows.Scan(&r.ID, &r.Name, &r.Total); err != nil {
return nil, fmt.Errorf("scan: %w", err)
}
results = append(results, r)
}
return results, rows.Err()
}
```
AI-generated Five:
```prg
FUNCTION ProcessCustomers(nThreshold)
LOCAL aResult, i
aResult := {}
USE customers NEW
GO TOP
DO WHILE !Eof()
IF customer->total > nThreshold
AAdd(aResult, {customer->id, customer->name, customer->total})
ENDIF
SKIP
ENDDO
RETURN aResult
```
Both do the same thing. But only one allows a sales manager to ask: *"Is nThreshold supposed to be ten thousand?"*
### The Greatest Danger of AI-Generated Code
The biggest risk of AI code is not that it **doesn't work**. It's that it **works but is wrong**.
- A 0.01% error in tax calculation
- A condition that allows negative inventory
- Date comparison logic that ignores time zones
These bugs pass tests. These bugs survive code reviews. These bugs are found only by **someone who can read the code**.
**Five's Second Principle: Code must be readable by humans.**
---
## Chapter 4: Building the Bridge
### Not a Transpiler — A Fusion Language
Five is not "a tool that converts Harbour to Go." Five is **a language that unifies two worlds**.
TypeScript added types to JavaScript. Kotlin removed Java's pain points. **Five places Go's future on top of xBase's 30-year legacy.**
```prg
// The past (xBase)
USE customers NEW
SEEK "CHARLES"
// The present (Five)
IMPORT "net/http"
http.ListenAndServe(":8080", handler)
// The future (Five)
PARALLEL FOR i := 1 TO RecCount()
aResult[i] := ASYNC AnalyzeCustomer(i)
NEXT
aFinal := AWAIT AllResults(aResult)
```
Past, present, and future coexist in a single `.prg` file.
### The Philosophy of IMPORT
```prg
IMPORT "database/sql"
```
What this single line means:
- Access to 500,000+ Go packages
- No `#pragma BEGINDUMP`, no wrappers, no FFI
- In PRG syntax, by PRG developers, the PRG way
What other languages call "external library integration," Five calls **"just IMPORT."**
---
## Chapter 5: What Was Designed
### 1. Survival of 30-Year Code
232/236 (98%) Harbour compatibility. Existing PRG code runs without modification. DBF, NTX, CDX index engines reimplemented in Go. 351 Harbour RTL functions ported.
**Design philosophy: Compatibility is non-negotiable.**
### 2. Complete Access to Go's Ecosystem
One `IMPORT` line for any Go package. `pkg.Func()` — call Go functions in PRG syntax. `obj:Method()` — manipulate Go objects Harbour-style. FastPath optimization — within 2x of native Go performance.
**Design philosophy: The boundary must be invisible.**
### 3. Democratization of Concurrency
goroutine, channel, select in PRG syntax. `SPAWN`, `<-`, `WATCH` — usable by developers who don't know Go. `PARALLEL FOR` — parallel processing in a single line.
**Design philosophy: Powerful things need not be difficult.**
### 4. Enforced Code Safety
Analyzer auto-detects undeclared and unused variables. `DEFER` prevents resource leaks. VM Shutdown automatically closes open databases.
**Design philosophy: Code that's hard to get wrong is good code.**
### 5. Coexistence with AI
PRG code is human-readable. Even when AI generates it, non-developers can verify it. Hungarian notation makes variable types visible in names.
**Design philosophy: Even when AI creates, humans must own.**
---
## Chapter 6: Toward the Future
### The World Five Envisions
A payroll system written in 1995 serves as a REST API in 2026. From the same codebase. Without changing a single line. And 10x faster with goroutines.
This is not code that's "just maintained" like COBOL at a bank. **This is living code.** New features are added. It deploys to new infrastructure. New developers can read and understand it.
### Technology is a Tool, and Tools Exist for People
Five does not pursue technical superiority. Five pursues **the right of people to own their code**.
When AI services go down, when frameworks release breaking changes, when cloud providers raise their prices —
Your code must remain yours. Single binary. Zero dependencies. Human-readable.
**That is Five.**
---
> *"We cannot predict the future.*
> *But we can write code that the future can still read."*
>
> — Five, 2026

297
docs/five-philosophy-ko.md Normal file
View File

@@ -0,0 +1,297 @@
# Five — 코드는 사라져도, 생각은 남는다
> *"좋은 코드는 기계가 실행하는 것이 아니라, 사람이 읽는 것이다."*
> — Charles KWON OhJun
---
## 서문: 30년의 무게
1990년대, dBASE와 Clipper로 시작된 xBase 언어는 전 세계 수백만 기업의 심장이었습니다.
급여를 계산하고, 재고를 관리하고, 고객을 추적했습니다.
그 코드 위에 사람들의 생계가 달려 있었습니다.
그리고 세상은 바뀌었습니다.
Java가 왔고, .NET이 왔고, Python이 왔고, 이제 AI가 왔습니다.
하지만 그 급여 시스템은 아직도 돌아가고 있습니다.
30년 된 PRG 코드가 오늘도 누군가의 월급을 계산합니다.
**이 코드를 버려야 할까요?**
저는 아니라고 생각합니다.
---
## 제1장: 버리지 않는 설계
### 코드는 자산입니다
소프트웨어 산업에서 가장 비싼 것은 새로 만드는 것이 아닙니다.
**이미 검증된 것을 다시 만드는 것**입니다.
30년간 운영된 코드에는 수천 개의 버그 수정이 녹아 있습니다.
수백 번의 세무 규정 변경이 반영되어 있습니다.
문서화되지 않은 업무 규칙이 `IF` 문 안에 살아 있습니다.
이것을 Python으로 "현대화"한다는 것은
30년의 경험을 0으로 리셋하는 것입니다.
**Five의 첫 번째 원칙: 기존 코드를 한 줄도 바꾸지 않습니다.**
```prg
// 1995년에 작성된 이 코드가
USE customers NEW
SET FILTER TO balance > 10000
GO TOP
DO WHILE !Eof()
? name, balance
SKIP
ENDDO
// 2026년 Five에서 그대로 실행됩니다.
// 그리고 이제, 같은 파일에서 이것도 됩니다:
IMPORT "database/sql"
db := sql.Open("postgres", connStr)
```
---
## 제2장: 왜 Go인가
### 언어를 고를 때 묻는 세 가지 질문
**1. 10년 후에도 살아 있을 것인가?**
Go는 Google이 만들었습니다. 하지만 그것이 이유가 아닙니다.
Go가 살아남는 이유는 **단순하기 때문**입니다.
Go에는 제네릭이 늦게 들어왔습니다. 의도적입니다.
Go에는 예외(exception)가 없습니다. 의도적입니다.
Go에는 상속이 없습니다. 의도적입니다.
복잡한 것을 배제한 언어는 유행을 타지 않습니다.
C가 50년을 살아남은 것처럼, Go는 다음 50년을 살아남을 언어입니다.
**2. 하드웨어의 미래와 맞는가?**
CPU는 더 이상 빨라지지 않습니다. 대신 코어가 늘어납니다.
Go의 goroutine은 이 미래를 위해 설계되었습니다.
```prg
// 10만 건을 8코어로 병렬 처리
PARALLEL FOR i := 1 TO 100000
aResult[i] := ProcessItem(aData[i])
NEXT
```
다른 언어에서는 스레드 풀, 뮤텍스, 데드락을 고민해야 합니다.
Five에서는 `PARALLEL FOR` 한 줄입니다.
**3. 최종 결과물이 독립적인가?**
Go는 단일 바이너리를 만듭니다.
JVM도, Python 인터프리터도, Node.js 런타임도 필요 없습니다.
```bash
five build payroll.prg -o payroll
scp payroll server:/usr/local/bin/
# 끝. 의존성 없음.
```
고객의 서버에 Java를 설치해달라고 할 필요가 없습니다.
---
## 제3장: AI 시대의 코드
### AI가 모든 것을 바꿨지만, 한 가지는 바꾸지 못합니다
2025년, AI는 코드를 작성할 수 있게 되었습니다.
하지만 **코드를 이해할 수 있는 것은 여전히 사람**입니다.
AI가 만든 Go 코드:
```go
func processCustomers(db *sql.DB, threshold float64) ([]CustomerResult, error) {
rows, err := db.QueryContext(ctx, `SELECT c.id, c.name,
COALESCE(SUM(o.amount), 0) as total FROM customers c
LEFT JOIN orders o ON c.id = o.customer_id
GROUP BY c.id, c.name HAVING COALESCE(SUM(o.amount), 0) > $1`, threshold)
if err != nil {
return nil, fmt.Errorf("query customers: %w", err)
}
defer rows.Close()
var results []CustomerResult
for rows.Next() {
var r CustomerResult
if err := rows.Scan(&r.ID, &r.Name, &r.Total); err != nil {
return nil, fmt.Errorf("scan: %w", err)
}
results = append(results, r)
}
return results, rows.Err()
}
```
AI가 만든 Five 코드:
```prg
FUNCTION ProcessCustomers(nThreshold)
LOCAL aResult, i
aResult := {}
USE customers NEW
GO TOP
DO WHILE !Eof()
IF customer->total > nThreshold
AAdd(aResult, {customer->id, customer->name, customer->total})
ENDIF
SKIP
ENDDO
RETURN aResult
```
두 코드 모두 같은 일을 합니다.
하지만 **영업팀장이 읽고 "nThreshold가 만원 맞아?"라고 물어볼 수 있는 코드는 하나뿐**입니다.
### AI에게 가장 위험한 것
AI가 만든 코드의 가장 큰 위험은 **작동하지 않는 것이 아닙니다**.
**작동하지만 틀린 것**입니다.
- 세금 계산에서 0.01%의 오차
- 재고에서 음수를 허용하는 조건문
- 날짜 비교에서 시간대를 무시하는 로직
이 버그들은 테스트를 통과합니다.
이 버그들은 코드 리뷰에서 놓칩니다.
이 버그들은 **코드를 읽을 수 있는 사람만** 발견합니다.
**Five의 두 번째 원칙: 코드는 사람이 읽을 수 있어야 합니다.**
---
## 제4장: 다리를 놓다
### 트랜스파일러가 아닌 융합 언어
Five는 "Harbour를 Go로 변환하는 도구"가 아닙니다.
Five는 **두 세계를 하나로 만드는 언어**입니다.
TypeScript는 JavaScript에 타입을 추가했습니다.
Kotlin은 Java의 불편함을 해소했습니다.
**Five는 xBase의 30년 유산에 Go의 미래를 올립니다.**
```prg
// 과거의 코드 (xBase)
USE customers NEW
SEEK "CHARLES"
// 현재의 코드 (Five)
IMPORT "net/http"
http.ListenAndServe(":8080", handler)
// 미래의 코드 (Five)
PARALLEL FOR i := 1 TO RecCount()
aResult[i] := ASYNC AnalyzeCustomer(i)
NEXT
aFinal := AWAIT AllResults(aResult)
```
과거, 현재, 미래가 하나의 `.prg` 파일에 공존합니다.
### IMPORT의 철학
```prg
IMPORT "database/sql"
```
이 한 줄이 의미하는 것:
- Go의 50만 개 패키지에 대한 접근
- `#pragma BEGINDUMP` 없이, 래퍼 없이, FFI 없이
- PRG 문법으로, PRG 개발자가, PRG 방식으로
다른 언어가 "외부 라이브러리 연동"이라고 부르는 것을
Five는 **"그냥 IMPORT"**라고 부릅니다.
---
## 제5장: 무엇을 설계했는가
### 1. 30년 코드의 생존
232/236 (98%) Harbour 호환. 기존 PRG 코드가 수정 없이 실행됩니다.
DBF, NTX, CDX 인덱스 엔진을 Go로 재구현했습니다.
351개의 Harbour RTL 함수를 포팅했습니다.
**설계 철학: 호환성은 타협할 수 없다.**
### 2. Go 생태계의 완전한 접근
`IMPORT` 한 줄로 Go 전체 패키지 사용.
`pkg.Func()` — Go 함수를 PRG 문법으로 호출.
`obj:Method()` — Go 객체를 Harbour 스타일로 조작.
FastPath 최적화 — native Go의 2배 이내 성능.
**설계 철학: 경계가 보이지 않아야 한다.**
### 3. 동시성의 민주화
goroutine, channel, select를 PRG 문법으로.
`SPAWN`, `<-`, `WATCH` — Go를 모르는 개발자도 사용 가능.
`PARALLEL FOR` — 병렬 처리를 루프 한 줄로.
**설계 철학: 강력한 것이 어려울 필요는 없다.**
### 4. 안전한 코드의 강제
Analyzer가 미선언/미사용 변수를 자동 검출.
`DEFER`로 리소스 누수 방지.
VM Shutdown이 열린 DB를 자동으로 닫음.
**설계 철학: 실수하기 어려운 코드가 좋은 코드다.**
### 5. AI와의 공존
PRG 코드는 사람이 읽을 수 있습니다.
AI가 생성해도, 비개발자가 검증할 수 있습니다.
헝가리안 표기법으로 변수 타입이 이름에 보입니다.
**설계 철학: AI가 만들어도 사람이 주인이다.**
---
## 제6장: 미래로
### Five가 꿈꾸는 세계
1995년에 작성된 급여 시스템이
2026년에 REST API로 서비스됩니다.
같은 코드베이스에서.
한 줄도 바꾸지 않고.
그리고 goroutine으로 10배 빠르게.
은행의 COBOL처럼 "유지만 하는 코드"가 아닙니다.
**살아 있는 코드입니다.**
새로운 기능이 추가되고, 새로운 인프라에 배포되고,
새로운 개발자가 읽고 이해할 수 있는 코드입니다.
### 기술은 도구이고, 도구는 사람을 위한 것입니다
Five는 기술적 우월함을 추구하지 않습니다.
Five는 **사람이 코드를 소유할 수 있는 권리**를 추구합니다.
AI 서비스가 중단되어도,
프레임워크가 버전업되어도,
클라우드 업체가 가격을 올려도,
당신의 코드는 당신의 것이어야 합니다.
단일 바이너리. 의존성 없음. 사람이 읽을 수 있음.
**그것이 Five입니다.**
---
> *"우리는 미래를 예측할 수 없습니다.*
> *하지만 미래에도 읽을 수 있는 코드를 만들 수는 있습니다."*
>
> — Five, 2026