Raku에서 나만의 연산자 정의하기

Raku에서 나만의 연산자 정의하기 (Operator tutorial)

Raku에서는 sub 키워드 뒤에 prefix, infix, postfix, circumfix, postcircumfix 중 하나를 붙이고, 콜론 다음에 연산자 이름을 따옴표 구문으로 적어서 연산자를 직접 선언할 수 있어요. (post-)circumfix 연산자는 두 부분을 공백으로 구분해요.

출처: Raku 공식 문서 — Operator tutorial

본문

sub hello {
    say "Hello, world!";
}

say &hello.^name;   # OUTPUT: «Sub␤»
hello;              # OUTPUT: «Hello, world!␤»

my $s = sub ($a, $b) { $a + $b };
say $s.^name;       # OUTPUT: «Sub␤»
say $s(2, 5);       # OUTPUT: «7␤»

# 더 일반적으로 n개 숫자를 합하는 연산자를 만들 수도 있어요
sub prefix:<Σ>( *@number-list ) {
    [+] @number-list
}

say Σ (13, 16, 1); # OUTPUT: «30␤»

sub infix:<:=:>( $a is rw, $b is rw ) {
    ($a, $b) = ($b, $a)
}

my ($num, $letter) = ('A', 3);
say $num;          # OUTPUT: «A␤»
say $letter;       # OUTPUT: «3␤»

# 두 변수의 값을 맞바꾸기
$num :=: $letter;

say $num;          # OUTPUT: «3␤»
say $letter;       # OUTPUT: «A␤»

sub postfix:<!>( Int $num where * >= 0 ) { [*] 1..$num }
say 0!;            # OUTPUT: «1␤»
say 5!;            # OUTPUT: «120␤»

sub postfix:<♥>( $a ) { say „I love $a!“ }
42♥;               # OUTPUT: «I love 42!␤»

sub postcircumfix:<⸨ ⸩>( Positional $a, Whatever ) {
    say $a[0], '…', $a[*-1]
}

[1,2,3,4]⸨*⸩;      # OUTPUT: «1…4␤»

constant term:<♥> = "♥"; # "love"를 따옴표로 감싸고 싶지 않잖아요?
sub circumfix:<α ω>( $a ) {
    say „$a is the beginning and the end.“
};

α♥ω;               # OUTPUT: «♥ is the beginning and the end.␤»

여기서 우선 눈에 띄는 건 Σ처럼 그리스 문자나 처럼 이모지까지 연산자 이름으로 쓸 수 있다는 점이에요. prefix:<Σ>는 여러 숫자를 받아서 전부 더해 주는 연산자를 만들고, infix:<:=:>는 두 변수의 값을 맞바꾸는 연산자예요. postfix:<!>는 팩토리얼(factorial)처럼 뒤에 붙는 연산자이고, postcircumfix:<⸨ ⸩>[1,2,3,4]⸨*⸩처럼 값 뒤에 붙어 첫 원소와 마지막 원소를 출력해 줘요.

마지막의 circumfix:<α ω>는 앞뒤로 감싸는 연산자라 α♥ω처럼 쓰면 가운데 값에 대해 동작하는 구조예요.

이 연산자들은 모두 확장 식별자(extended identifier) 문법을 사용해요. 그래서 어떤 유니코드 코드포인트든 연산자 이름으로 쓸 수 있는 거예요.

더 알아보기 (Learn more)