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:
251
docs/five-philosophy-en.md
Normal file
251
docs/five-philosophy-en.md
Normal 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
297
docs/five-philosophy-ko.md
Normal 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
|
||||
Reference in New Issue
Block a user