Soppo - Go에 빠진 기능을 더한 언어
요약
Go 언어의 단점을 보완하기 위해 제안된 새로운 언어 Soppo의 특징과 개선 사항을 분석합니다. 문자열 보간, 오류 처리 문법, nil 안전성 및 대수적 데이터 타입(ADT) 도입에 대한 기술적 견해를 다룹니다.
핵심 포인트
- 문자열 보간 및 ?? 연산자를 통한 간결한 오류 처리 제안
- nil 안전성 확보를 위한 타입 시스템 및 nil 검사 방식 개선
- 패턴 매칭과 대수적 데이터 타입(ADT) 도입의 필요성
- Go의 단순성을 유지하면서도 개발자 경험을 높이는 문법적 접근
처음엔 회의적이었지만 전반적으로 놀랄 만큼 합리적임. 다만 문자열 보간이 선택 사항이 아니라 항상 적용되는 점, 매끄러운 상호 운용성과 nil 안전성을 동시에 달성하는 방식, 여전히 번거로운 오류 처리는 아쉬움 문서의 ? 문법은 기존 if err != nil보다 거의 짧지 않으므로, port := parsePort(config) ?? "port parsing failed"처럼 기존 오류를 fmt.Errorf("port parsing failed: %w", err)로 감싸 반환하는 ?? 단축 문법이 더 유용해 보임. 형식 인수와 (T, error) 반환형도 지원할 수 있음
그 외에는 Go의 날카로운 모서리를 잘 다듬었음. 거의 모든 값을 const로 선언하고 실제 변경할 때만 var나 :=를 쓰면 정확성, 최적화, 가독성이 좋아질 것임. 더 나은 패턴 매칭과 nil 검사도 불필요한 정신적 부담을 줄여줌
문자열 보간은 Swift의 "Time: (t) seconds"나 Java 제안의 STR."Time: {t} seconds"처럼 백슬래시로 시작하면 좋겠음. {} 자체를 출력할 때 {{, }}라는 새 이스케이프 규칙을 만들 필요 없이 기존 백슬래시 규칙과 일관되기 때문임
Go의 핵심은 단순함과 명시성이므로 한두 줄을 줄이는 데 큰 가치는 없음. 진짜 문제는 실패 가능한 작업마다 오류 처리 세 줄이 반복되어 고루틴·채널 코드의 잡음과 실수를 키운다는 데 있음
현실적인 선택지는 기존 방식을 유지하거나, return err, 문맥을 붙인 오류 반환, 형식화된 문맥을 붙인 오류 반환이라는 세 가지 일반 사례를 한 줄로 처리하는 문법을 추가하는 것임. 키워드와 문법은 신중히 정해야 하며 (T, U, ..., error)처럼 마지막 값이 오류인 형태까지 지원할 만함
?는 바깥 범위에 새 변수를 만들 때 기존 Go보다 낫기도 함. if port, err := parsePort(config); err != nil에서는 port가 내부 범위에 갇히지만, ?가 기대대로 범위를 처리하면 두 단계짜리 기존 코드보다 깔끔함
그래도 대부분은 기존 오류에 지역 문맥만 덧붙이면 되므로 ?? 제안이 더 유용해 보임
외부 Go 패키지의 포인터는 모두 nil 가능하다고 가정해 검사를 강제하고, 검사 후에는 타입을 좁힘. Go에는 nil 가능성 표기가 없으므로 Soppo의 nil 불가 타입에 전달할 때 nil 검사나 .(!nil)을 사용해야 함
Go에 태그드 유니온을 추가할 때 가장 먼저 생기는 문제는 모든 값이 기본값으로 초기화된다는 사실임. Soppo에서는 빈 열거형을 필드로 가진 구조체도 생성되어 {<nil>}이 출력되며, 홈페이지의 Shape 같은 열거형도 비슷하게 동작하는 듯함
Haskell의 지연 평가 타입도 정의되지 않은 값이 될 수 있지만 엄격한 언어에서는 실망스러운 결과임. Go API에 기본값이 널리 쓰이는 만큼 상당한 함정이 될 수 있으니 최소한 문서화해야 함. Go를 고친다면 모든 타입에 기본값을 요구하지 않고, 사용 전에 완전히 초기화됐는지 컴파일 시점 분석으로 보장하는 방향을 택하겠음
이 합 타입 Go 제안은 첫 번째 선택지를 영값으로 삼는 가장 단순한 방식을 제안함. nil 가능 포인터의 의미를 바꾸는 것보다 추론하기 쉬움
영값처럼 언어 전반에 영향을 주는 핵심을 건드리면서 나머지 언어 요소와 어떻게 맞물릴지 다루지 않는 점은 의외임
열거형에 다소 이상한 기본값이 남더라도 기존 Go를 유지하는 편이, 영값을 없애려고 거의 모든 기존 코드를 다시 쓰는 것보다 나음. nil 처리 안전성만 조금 개선돼도 큰 도움이 됨
동료들과 Go가 점점 선호하는 언어가 된다고 이야기했지만, 대수적 데이터 타입과 패턴 매칭이 없다는 데 모두 동의했음. 그래서 Soppo에 큰 관심이 생김
Soppo와 Lisette를 보면 Go 런타임을 대상으로 하는 언어의 미래가 밝아 보임
Soppo와 Lisette가 Go에 더한 개선점은 문법을 제외하면 거의 동일하다는 점이 흥미로움
Go 팀이 이런 변경을 직접 받아들이면 Go가 완벽한 언어가 될 수 있음. Soppo는 훌륭하지만 광범위한 채택 가능성이 낮고, 결국 이런 프로젝트가 사라지는 원인이 되기 쉬움
이런 개선에 대한 수요는 상당하지만 모두가 하나의 프로젝트에 모이게 하려면 큰 노력이 필요함. Dafny와 Go처럼 목표가 상호 보완적이고 어느 정도 자리 잡은 공동체들과 상호 운용하는 프로젝트라면 양쪽 모두의 채택을 촉진할 수 있음
Soppo가 읽을 수 있는 Go 코드를 생성한다면 광범위한 채택이 꼭 필요하지는 않음. 개발자 개인 도구로 남아도 충분히 유용할 수 있음
오류 처리용 후행 ?와 오류 변수를 포착하는 ?는 최근 GitHub의 Go 제안에서도 논의되다가 폐기됐음. ?를 놓치기 쉬워 오류 경로와 정상 경로를 구분하며 읽기 어려워진다는 비판이 있었음
이전의 try·check 제안은 새 키워드라 더 잘 보이고 읽기 쉬웠지만, Go 자체에는 하위 호환성을 유지하며 추가하기 어려웠음. 개선된 오류 처리를 설계하려면 과거의 많은 제안과 논의를 검토하고 비교할 필요가 있음
AI 자동 생성 콘텐츠
본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기