docs: Add readability advantage — AI era code maintainability

Five's hidden strength: PRG code is readable by non-developers.
When AI generates code, humans must verify it.
Five's xBase syntax makes this possible.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-31 09:53:58 +09:00
parent 59568f3301
commit b1a58724c8
2 changed files with 523 additions and 0 deletions

243
docs/five-readability-en.md Normal file
View File

@@ -0,0 +1,243 @@
# Five's Readability — The Real Advantage in the AI Era
## Why Readability Matters When AI Writes Code
AI generates code automatically now.
But there's a problem:
1. **AI creates complex code** — it works, but humans can't understand it
2. **Unmaintainable without AI** — if the AI service goes down, code becomes a black box
3. **Bugs hide in complexity** — if you can't read it, you can't debug it
4. **Team collaboration breaks** — nobody except the AI understands the code
**Five solves this fundamentally.**
## Same Task, Different Readability
### Query Customer List
```prg
// Five (PRG) — 8 lines
USE customers NEW
SET FILTER TO balance > 10000
GO TOP
DO WHILE !Eof()
? name, city, balance
SKIP
ENDDO
```
```go
// Go — 27 lines
func listCustomers() {
db, err := sql.Open("sqlite3", "customers.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
rows, err := db.Query(
"SELECT name, city, balance FROM customers WHERE balance > $1",
10000,
)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var name, city string
var balance float64
if err := rows.Scan(&name, &city, &balance); err != nil {
log.Fatal(err)
}
fmt.Println(name, city, balance)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
}
```
| Language | Lines | Error handling | Non-developer readable |
|----------|------|---------------|:---:|
| **Five (PRG)** | **8** | Built-in | **Yes** |
| Python | 12 | Manual | Maybe |
| Go | 27 | Required | No |
| Java | 15 | Required | No |
## Why PRG is Easy to Read
### 1. Reads like English sentences
```prg
USE customers NEW // Open customer file
GO TOP // Go to the first record
DO WHILE !Eof() // Repeat until end of file
IF balance > 10000 // If balance exceeds 10000
? name, balance // Print name and balance
ENDIF // End condition
SKIP // Move to next record
ENDDO // End loop
```
Even non-programmers can follow the flow.
No `{`, `}`, `func`, `defer`, or cryptic symbols.
### 2. Everything is explicit
```prg
// Five — endings are clear
IF condition
...
ENDIF // IF ends here
FOR i := 1 TO 10
...
NEXT // FOR ends here
DO WHILE condition
...
ENDDO // WHILE ends here
```
```go
// Go — count the braces
if condition {
for i := 0; i < 10; i++ {
if another {
// ...
} // ← which one does this close?
} // ← this one?
} // ← or this one?
```
### 3. Variable names tell their type
```prg
LOCAL cCustomerName, nTotalBalance, dLastPurchase, lIsActive
cCustomerName := "Charles Kwon" // c = Character
nTotalBalance := 15000.50 // n = Numeric
dLastPurchase := Date() // d = Date
lIsActive := .T. // l = Logical
```
Hungarian notation makes types visible in names:
- `c` = Character (string)
- `n` = Numeric (number)
- `d` = Date
- `l` = Logical (boolean)
- `a` = Array
- `o` = Object
Even AI-generated code is self-documenting with these prefixes.
### 4. Error handling doesn't pollute business logic
```go
// Go — more error handling than business logic
result, err := doSomething()
if err != nil {
return fmt.Errorf("doSomething failed: %w", err)
}
result2, err := doAnother(result)
if err != nil {
return fmt.Errorf("doAnother failed: %w", err)
}
```
```prg
// Five — focus on business logic
result := doSomething()
result2 := doAnother(result)
// Errors handled in one place via BEGIN SEQUENCE or ErrorBlock
```
## AI-Era Scenarios
### Scenario 1: AI service goes down
**Go/Python/Java project:**
- 100K lines — days to understand structure
- Complex type systems, generics, interfaces
- Framework dependencies to untangle
- New developer needs weeks to onboard
**Five project:**
- Same features in 30K lines — less code to read
- `USE`, `SKIP`, `SEEK` — commands mean what they say
- Inexperienced developer can read code in one day
### Scenario 2: Emergency bug fix
```prg
// Assume the bug is here
USE orders NEW
SET FILTER TO date >= Date() - 30
GO TOP
DO WHILE !Eof()
IF amount > 0
nTotal += amount // ← bug here: should be = instead of +=?
ENDIF
SKIP
ENDDO
```
Non-developers (sales team, managers) can read this and understand
"nTotal is accumulating something." This level of comprehension is
impossible with Go code.
### Scenario 3: Verifying AI-generated code
```prg
// AI-generated Five code — humans can verify
FUNCTION CalcDiscount(nPrice, nQuantity)
LOCAL nDiscount
IF nQuantity >= 100
nDiscount := nPrice * 0.15 // 100+ units: 15% discount
ELSEIF nQuantity >= 50
nDiscount := nPrice * 0.10 // 50+ units: 10% discount
ELSE
nDiscount := 0 // No discount
ENDIF
RETURN nDiscount
```
A business stakeholder can look at this code and ask:
"Is 15% for 100+ units correct?" — try doing that with Go generics.
## Five + Go = The Optimal Combination
Simplicity alone isn't enough.
**Simple code with powerful capabilities** — that's the goal.
```prg
IMPORT "database/sql"
IMPORT _ "modernc.org/sqlite"
PROCEDURE Main()
LOCAL db, aRows, i
db := sql.Open("sqlite", ":memory:")
DEFER db:Close()
db:Exec("CREATE TABLE orders (id INTEGER, amount REAL)")
db:Exec("INSERT INTO orders VALUES (1, 15000)")
aRows := SqlScan(db, "SELECT * FROM orders")
FOR i := 1 TO Len(aRows)
? aRows[i]["id"], aRows[i]["amount"]
NEXT
RETURN
```
SQL database access in PRG syntax.
Go's `database/sql` powers it behind the scenes,
but the person reading this code **doesn't need to know Go**.
## The Bottom Line
> **In an era where AI writes code,
> code that humans can read is the real asset.
> Five is the only systems language where AI-generated code
> can be verified by humans — even non-developers.**

280
docs/five-readability-ko.md Normal file
View File

@@ -0,0 +1,280 @@
# Five의 가독성 — AI 시대의 진짜 강점
## AI가 코딩하는 시대, 왜 가독성이 중요한가
AI가 코드를 자동 생성하는 시대입니다.
하지만 문제가 있습니다:
1. **AI가 복잡한 코드를 만들어냄** — 정상 동작하지만 사람이 이해 못 함
2. **AI 없이 유지보수 불가** — AI 서비스 중단 시 코드가 블랙박스가 됨
3. **버그 발견이 어려움** — 코드를 읽을 수 없으면 버그도 못 찾음
4. **팀 협업 불가** — 작성자 외에 누구도 코드를 이해 못 함
**Five는 이 문제를 근본적으로 해결합니다.**
## 같은 일, 다른 가독성
### 고객 목록 조회
```prg
// Five (PRG)
USE customers NEW
SET FILTER TO balance > 10000
GO TOP
DO WHILE !Eof()
? name, city, balance
SKIP
ENDDO
```
```go
// Go
func listCustomers() {
db, err := sql.Open("sqlite3", "customers.db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
rows, err := db.Query(
"SELECT name, city, balance FROM customers WHERE balance > $1",
10000,
)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var name, city string
var balance float64
if err := rows.Scan(&name, &city, &balance); err != nil {
log.Fatal(err)
}
fmt.Println(name, city, balance)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
}
```
```python
# Python
import sqlite3
def list_customers():
conn = sqlite3.connect('customers.db')
cursor = conn.cursor()
cursor.execute(
'SELECT name, city, balance FROM customers WHERE balance > ?',
(10000,)
)
for row in cursor.fetchall():
print(row[0], row[1], row[2])
conn.close()
```
```java
// Java
public void listCustomers() throws SQLException {
try (Connection conn = DriverManager.getConnection("jdbc:sqlite:customers.db");
PreparedStatement stmt = conn.prepareStatement(
"SELECT name, city, balance FROM customers WHERE balance > ?")) {
stmt.setDouble(1, 10000);
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
System.out.println(
rs.getString("name") + " " +
rs.getString("city") + " " +
rs.getDouble("balance")
);
}
}
}
}
```
| 언어 | 줄 수 | 에러 처리 | 비개발자 이해 |
|------|------|----------|:---:|
| **Five (PRG)** | **8** | 내장 | **✅ 가능** |
| Python | 12 | 수동 | △ |
| Go | 27 | 필수 | ❌ |
| Java | 15 | 필수 | ❌ |
## PRG가 읽기 쉬운 이유
### 1. 영어 문장처럼 읽힌다
```prg
USE customers NEW // 고객 파일 열어
GO TOP // 처음으로 가
DO WHILE !Eof() // 끝까지 반복해
IF balance > 10000 // 잔액이 만 넘으면
? name, balance // 이름이랑 잔액 출력해
ENDIF // 조건 끝
SKIP // 다음으로
ENDDO // 반복 끝
```
프로그래밍을 모르는 사람도 흐름이 보입니다.
`{`, `}`, `:=`, `->`, `func`, `defer` 같은 기호가 없습니다.
### 2. 모든 것이 명시적이다
```prg
// Five — 끝이 명확함
IF condition
...
ENDIF // IF가 여기서 끝남
FOR i := 1 TO 10
...
NEXT // FOR가 여기서 끝남
DO WHILE condition
...
ENDDO // WHILE이 여기서 끝남
```
```go
// Go — } 가 뭘 닫는 건지 세어야 함
if condition {
for i := 0; i < 10; i++ {
if another {
// ...
} // ← 이 } 는 inner if
} // ← 이 } 는 for
} // ← 이 } 는 outer if
```
### 3. 변수명이 길어도 자연스럽다
```prg
LOCAL cCustomerName, nTotalBalance, dLastPurchase, lIsActive
cCustomerName := "Charles Kwon"
nTotalBalance := 15000.50
dLastPurchase := Date()
lIsActive := .T.
```
헝가리안 표기법으로 변수 타입이 이름에 보입니다:
- `c` = Character (문자열)
- `n` = Numeric (숫자)
- `d` = Date (날짜)
- `l` = Logical (논리값)
- `a` = Array (배열)
- `o` = Object (객체)
AI가 코드를 작성해도, 변수명만 보면 타입을 알 수 있습니다.
### 4. 에러 처리가 코드를 오염시키지 않는다
```go
// Go — 비즈니스 로직보다 에러 처리가 더 많음
result, err := doSomething()
if err != nil {
return fmt.Errorf("doSomething failed: %w", err)
}
result2, err := doAnother(result)
if err != nil {
return fmt.Errorf("doAnother failed: %w", err)
}
```
```prg
// Five — 비즈니스 로직에 집중
result := doSomething()
result2 := doAnother(result)
// 에러는 BEGIN SEQUENCE나 ErrorBlock으로 한 곳에서 처리
```
## AI 시대 시나리오
### 시나리오 1: AI 서비스가 중단됨
**Go/Python/Java 프로젝트:**
- 10만 줄 코드 — 구조 파악에 수일
- 복잡한 타입 시스템, 제네릭, 인터페이스
- 프레임워크 의존성 파악 필요
- 신규 개발자가 인수하려면 수주일
**Five 프로젝트:**
- 같은 기능이 3만 줄 — 코드량 자체가 적음
- `USE`, `SKIP`, `SEEK` — 명령어가 의미 그대로
- 경험 없는 개발자도 하루 만에 코드 읽기 가능
### 시나리오 2: 긴급 버그 수정
```prg
// 버그가 여기 있다고 가정
USE orders NEW
SET FILTER TO date >= Date() - 30
GO TOP
DO WHILE !Eof()
IF amount > 0
nTotal += amount // ← 여기가 문제: += 대신 = 써야 함?
ENDIF
SKIP
ENDDO
```
비개발자(영업팀, 관리자)도 코드를 읽고 "nTotal이 누적되는 것 같다"를 이해합니다.
Go 코드에서는 이 수준의 이해가 불가능합니다.
### 시나리오 3: AI가 만든 코드 검증
```prg
// AI가 생성한 Five 코드 — 사람이 검증 가능
FUNCTION CalcDiscount(nPrice, nQuantity)
LOCAL nDiscount
IF nQuantity >= 100
nDiscount := nPrice * 0.15 // 100개 이상 15% 할인
ELSEIF nQuantity >= 50
nDiscount := nPrice * 0.10 // 50개 이상 10% 할인
ELSE
nDiscount := 0 // 할인 없음
ENDIF
RETURN nDiscount
```
비즈니스 담당자가 이 코드를 보고 "100개 이상이면 15% 맞아?"라고 확인할 수 있습니다.
## Five + Go = 최적의 조합
Five가 쉬운 것만으로 충분한 게 아닙니다.
**쉬운 코드로 강력한 기능**을 쓸 수 있어야 합니다.
```prg
IMPORT "database/sql"
IMPORT _ "modernc.org/sqlite"
PROCEDURE Main()
LOCAL db, aRows, i
// SQL — 쉬운 PRG 문법으로
db := sql.Open("sqlite", ":memory:")
DEFER db:Close()
db:Exec("CREATE TABLE orders (id INTEGER, amount REAL)")
db:Exec("INSERT INTO orders VALUES (1, 15000)")
// 결과를 Harbour 배열로 받아서 xBase 스타일로 처리
aRows := SqlScan(db, "SELECT * FROM orders")
FOR i := 1 TO Len(aRows)
? aRows[i]["id"], aRows[i]["amount"]
NEXT
RETURN
```
PRG 문법으로 SQL 데이터베이스를 씁니다.
Go의 `database/sql` 패키지가 뒤에서 동작하지만,
코드를 읽는 사람은 **Go를 몰라도** 됩니다.
## 한 줄 요약
> **AI가 코드를 만들어주는 시대에,
> 사람이 읽을 수 있는 코드가 진짜 자산입니다.
> Five는 AI가 만들어도 사람이 검증할 수 있는 유일한 시스템 언어입니다.**