- Raku는 Python, J, Frink, Excel의 수학 작업상 빈틈을 메울 계산기 언어 후보로 검토됐고, 짧은 실험만으로도 매우 강력하지만 기묘한 언어라는 인상을 줌
- Unicode 기호, 영숫자 중위 연산자, 리스트 곱·zip·리듀스·누적,
~~매처,...시퀀스처럼 연산자 중심 표현력이 넓음 - 사용자가 중위 연산자뿐 아니라 circumfix/postcircumfix 연산자까지 정의할 수 있고, 결합성도 좌·우 결합을 넘어 체인·리스트 결합까지 지정 가능함
- 다중 디스패치는 타입 시그니처뿐 아니라
where런타임 조건자로도 분기하며, 함수 시그니처와 그 안의 파라미터도 일급 값으로 다룰 수 있음 - 큰 코드베이스 유지보수에는 부담이 커 보이지만, 일회성 스크립트·계산·개인 도구 같은 작은 규모 프로그래밍에는 매력적이며 문서, Windows REPL, 컴파일 속도, sigil 실수가 주요 걸림돌임
Raku를 살펴본 계기와 첫인상
- Raku는 과거 Perl 6로 알려졌던 언어임
- 동적 언어에 대한 불만을 쓴 뒤 몇몇 사용자가 Raku를 추천했고, 수학 작업에 쓸 계산기 언어로 적합한지 확인하기 위해 살펴봄
- 기존에는 Python, J, Frink, Excel을 섞어 썼지만 각각 큰 단점이 있었음
- 며칠간 실험한 뒤 받은 인상은 “정말 똑똑한 그렘린들이, 다른 그렘린들의 피드백을 많이 모아 설계한 언어”에 가까웠음
특이한 연산자 체계
- Raku는 Unicode 연산자를 적극적으로 씀
- 집합 포함 여부는
∈로 확인함 ∉,∋,∌도 있음
- 집합 포함 여부는
- 영숫자 중위 연산자도 허용함
- 문자열 반복 연산자는
x - 함수 합성은
o
- 문자열 반복 연산자는
- 리스트 조합도 짧은 기호로 표현함
X는 리스트의 카테시안 곱을 만듦Xf는 카테시안 곱의 각 요소에f를 적용함Zf는 zip 방식으로 같은 일을 함
- 중위 연산자
f에 대해[f]는 리스트를 리듀스하고,[\f]는 누적 결과를 만듦[+] <1 2 3 4 5>는15[\+] <1 2 3 4 5>는(1 3 6 10 15)
~~ 매처와 ... 시퀀스
~~는 여러 종류의 비교를 한 문법으로 처리하는 매처로 쓰임"abc" ~~ "abc"는 문자열 일치를 확인함"abc" ~~ Str은 문자열 타입인지 확인함"abc" ~~ {.chars == 3}은 길이가 3인지 검사함"abc" ~~ /^b/는abc가b로 시작하는지 확인함
...는 앞의 값들에서 패턴을 잡아 시퀀스를 만듦0,1,2...10은0부터10까지 1씩 증가함0,2,4...10은 짝수 시퀀스가 됨1,2,4...10은1 2 4 8처럼 증가 패턴을 따름
사용자 정의 연산자
- Raku는 일부 언어처럼 중위 연산자만 정의하는 데 그치지 않고, circumfix와 postcircumfix 연산자도 만들 수 있음
- 예를 들어
sub circumfix:<[∀ zz>($inner){sum($inner)}처럼 둘러싸는 연산자를 정의해 내부 값을 합산할 수 있음 - 벡터 내적처럼 보이는 postcircumfix 연산자도 정의 가능함
sub postcircumfix:<| ⟩>(@left, @inside){[+] (@left Z* @inside)}<1 2 3>|<4 5 6>⟩는32
- 연산자 결합성도 다양하게 지정할 수 있음
- 일반적인 좌결합·우결합 중위 연산자를 정의 가능함
x < y < z가x < y && y < z처럼 해석되는 체인 결합을 지정할 수 있음a op b op c가op(a, b, c)가 되는 리스트 결합도 지원함
다중 디스패치와 런타임 조건 분기
- Raku는 다중 디스패치를 지원해, 서로 다른 타입 시그니처를 가진 여러 함수 정의 중 적절한 것을 고름
- 예시 함수
f는 인자 조합에 따라 다르게 동작함- 스칼라와 배열을 받으면 배열 각 요소에 스칼라를 더함
- 배열과 스칼라를 받는 경우도 지원함
- 두 배열을 받으면
Z+로 각 요소를 더함
- 더 특이한 점은 값의 런타임 조건자로도 디스패치할 수 있다는 점임
multi my_abs(Int $x where {$x > 0}) {$x}multi my_abs(Int $x) {-$x}
- 함수의 시그니처는 일급 값이며, 시그니처 안의 파라미터도 일급 값임
작은 기능들이 만드는 넓은 표면적
MAIN함수를 정의하면 그 파라미터가 자동으로 CLI 플래그로 변환됨- 객체에는 미리 제공되는 메서드가 매우 많음
- List object는 모든 순열, 모든 k-조합, 모든 슬라이딩 윈도를 얻는 메서드를 제공함
- Junctions는 한 번에 여러 비교를 하기 위한 특이한 값 형태임
1|2는any(1, 2)로 확장되어1 < 1|2가 성립함1&2는all(1, 2)로 확장되어1 !< 1&2가 성립함
- 어떤 중위 연산자든 앞에
!를 붙여 부정 연산자로 만들 수 있음 - Raku는
$kebab-case이름과 중위 뺄셈을 동시에 가진 언어로 보이며, sigil이x-y를 구분하게 해주는 것으로 추정됨 - regex syntax는 Perl 5와 하위 호환되지 않음
- 30년 동안 언어들이 PCRE “표준”을 따랐지만, Perl 6는 이를 버렸음
아직 보지 못한 영역과 작은 규모에서의 매력
- 살펴본 내용은 계산기 용도 중심의 일부 기능에 불과함
- 아직 객체 시스템, 패키지, grammars는 배우지 않았음
- 함수 본문에서
samewith가 같은 함수를 새 인자로 다시 호출하는 기능처럼, 빠진 기능도 많음 - Raku 레거시 코드베이스를 유지보수해야 한다면 매우 힘들 것 같지만, In The Small 프로그래밍에는 강력해 보임
- 일회성 스크립트
- 계산
- 개인 도구
- 처음에 원했던 종류의 작업
불만과 기대
- 문서가 매우 부족하고, 기호 의존도가 높아 검색이 어려움
- 문서가 부족한 언어를 여럿 배운 경험이 있어도, Raku는 그보다 훨씬 크고 복잡해 동기부여가 떨어질 수 있음
- Windows에서 REPL에 Unicode를 입력하면 크래시가 남
- 컴파일러도 꽤 느려 작은 파일도 0.5초 이상 걸리며, 반복 작업이 고통스러움
- sigil 체계가 불편함
$x를@x대신 써서 문제를 디버깅하는 데 30분을 쓴 사례가 있음
- 전반적으로 Raku가 마음에 들고 성공하길 바라지만, 시간이 지나며 컴파일 시간과 문서가 개선되길 기대함