용어(terms)
용어(terms) (terms)
Raku의 대부분의 구문 구조는 terms와 operators로 나눌 수 있어요. 이 문서에서는 여러 종류의 terms를 개괄적으로 살펴봅니다.
리터럴(Literals)
Int
42
12_300_00
:16<DEAD_BEEF>
Int 리터럴은 숫자로 이루어지고, 아무 두 숫자 사이에 밑줄을 넣을 수 있어요. 10진수 외의 진법을 쓰려면 콜론페어 형식 :radix<number>를 사용하세요.
Rat
12.34
1_200.345_678
Rat 리터럴(유리수)은 점으로 이어진 두 정수부로 이루어져요. 끝에 점을 붙이는 것은 허용되지 않아요. 즉 1. 대신 1.0이라고 써야 해요. 이 규칙이 중요한 이유는 점으로 시작하는 중위 연산자(예: .. Range 연산자)가 있기 때문이에요.
Num
12.3e-32
3e8
Num 리터럴(부동소수점)은 Rat 또는 Int 리터럴 뒤에 e와 (음수일 수도 있는) 지수가 붙은 형태예요. 3e8은 값이 3 * 10**8인 Num을 만들어요.
Str
'a string'
'I\'m escaped!'
"I don't need to be"
"\"But I still can be,\" he said."
q|Other delimiters can be used too!|
문자열 리터럴은 흔히 '나 "로 만들지만, 사실 문자열은 Raku의 강력한 하위 언어(sub-language)랍니다. 자세한 내용은 Quoting Constructs를 참고하세요.
Regex
/ match some text /
rx/slurp \s rest (.*) $/
이 형태들은 정규식 리터럴을 만들어요. quoting constructs를 참고하세요.
Pair
a => 1
'a' => 'b'
:identifier
:!identifier
:identifier<value>
:identifier<value1 value2>
:identifier($value)
:identifier['val1', 'val2']
:identifier{key1 => 'val1', key2 => 'value2'}
:valueidentifier
:$item
:@array
:%hash
:&callable
Pair 객체는 => 중위 연산자로 만들거나(왼쪽이 식별자면 자동으로 인용됨), 다양한 콜론페어 형태로 만들 수 있어요. 콜론페어는 거의 항상 콜론으로 시작하고, 그 뒤에 식별자 또는 이미 존재하는 변수의 이름이 와요(변수 이름은 시길을 뺀 키로, 변수 값은 페어의 값으로 쓰임). 콜론 바로 뒤에 정수 값이 오고 키가 값 바로 뒤에 오는 특별한 형태도 있어요.
콜론페어의 식별자 형태에서 선택적인 값은 어떤 원주형(circumfix)이든 될 수 있어요. 비워두면 값은 Bool::True가 돼요. :!identifier 형태의 값은 Bool::False예요.
인자 목록에서 쓰일 때 이 형태들 모두 명명된 인자(named arguments)로 취급되는데, 'quoted string' => $value만 예외예요.
List
()
1, 2, 3
<a b c>
«a b c»
qw/a b c/
List 리터럴은 빈 괄호 쌍 () , 쉼표로 구분된 목록, 또는 여러 quoting 구조입니다.
*
* 리터럴은 Whatever 타입의 객체를 만들어요. 자세한 내용은 Whatever 문서를 참고하세요. term으로 쓰이면, 그것을 포함한 표현식은 WhateverCode가 돼요.
say .^name with *; # OUTPUT: «Whatever»
say .^name with *+3; # OUTPUT: «WhateverCode»
식별자 terms(Identifier terms)
Raku에는 내장 식별자 term들이 있고, 아래에 나열해요. 게다가 새 식별자 term은 이런 문법으로 추가할 수 있어요.
sub term:<forty-two> { 42 };
say forty-two
또는 상수로:
constant forty-two = 42;
say forty-two;
term self
메서드 안에서 self는 호출자(invocant), 즉 그 메서드가 호출된 객체를 가리켜요. 의미가 없는 맥락에서 쓰면 X::Syntax::NoSelf 타입의 컴파일 타임 예외가 발생해요.
term now
현재 시간을 나타내는 Instant 객체를 돌려줘요. 윤초(leap seconds)를 포함하기 때문에 time보다 수십 초가 큽니다.
say (now - time).Int; # OUTPUT: «37»
term time
현재 POSIX 시간을 초 단위의 Int로 돌려줘요. 더 정밀한 값은 nano를 참고하세요. 윤초를 포함한 고해상도 타임스탬프는 now를 보세요.
term nano
현재 POSIX 시간을 나노초 단위의 Int로 돌려줘요. 윤초를 포함한 고해상도 타임스탬프는 now를 보세요.
6.e 언어 버전부터 사용할 수 있어요(초기 구현이 Rakudo 컴파일러 2022.12+에 존재). 2021.04부터의 Rakudo 릴리스에서는 nano 모듈로 같은 기능을 얻을 수 있어요.
term rand
0..^1 범위의 의사 난수 Num을 돌려줘요.
term π
코드포인트 U+03C0(GREEK SMALL LETTER PI)에 있는 숫자 π, 즉 원의 둘레와 지름의 비율을 돌려줘요. π의 ASCII 동격은 pi예요.
term pi
숫자 π, 즉 원의 둘레와 지름의 비율을 돌려줘요. pi는 π의 ASCII 동격입니다.
term τ
코드포인트 U+03C4(GREEK SMALL LETTER TAU)에 있는 숫자 τ, 즉 원의 둘레와 반지름의 비율을 돌려줘요. τ의 ASCII 동격은 tau예요.
term tau
숫자 τ, 즉 원의 둘레와 반지름의 비율을 돌려줘요. tau는 τ의 ASCII 동격입니다.
term 𝑒
코드포인트 U+1D452(MATHEMATICAL ITALIC SMALL E)에 있는 오일러 수를 돌려줘요. 𝑒의 ASCII 동격은 e입니다.
term e
오일러 수를 돌려줘요. e는 𝑒의 ASCII 동격입니다.
term i
(Complex 수를 위한) 허수 단위를 돌려줘요.
term ∅
코드포인트 U+2205(EMPTY SET)에 있는 set(), 즉 빈 집합을 돌려줘요.
변수(Variables)
변수는 variable 언어 문서에서 다뤄요.
상수(Constants)
상수는 컨테이너가 없는 변수와 비슷해서, 다시 바인딩할 수 없어요. 하지만 초기화식은 BEGIN 시점에 평가돼요.
constant speed-of-light = 299792458; # m/s
constant @foo = 1, 2, 3;
constant &talk = &say;
talk speed-of-light²; # OUTPUT: «89875517873681764»
talk @foo; # OUTPUT: «(1 2 3)»
컴파일 타임 평가라는 점은 모듈 안에서 상수를 쓸 때 주의해야 한다는 뜻이에요. 모듈은 자동으로 사전 컴파일(precompiled)되기 때문에, 상수 값은 프로그램을 여러 번 실행해도 변하지 않을 거예요.
# Foo.rakumod
unit module Foo;
constant comp-time = DateTime.now;
# The value of the constant remains the same even though our script
# is executed multiple times:
$ raku -I. -MFoo -e 'say Foo::comp-time'
2018-06-17T18:18:50.021484-04:00
$ raku -I. -MFoo -e 'say Foo::comp-time'
2018-06-17T18:18:50.021484-04:00
상수는 키워드 constant 뒤에 선택적인 시길이 붙은 식별자로 선언해요. 상수는 기본적으로 our 스코프예요.
constant foo = 42;
my constant $baz = rand;
our constant @foo = 1, 2, 3;
constant %bar = %(:42foo, :100bar);
참고: Rakudo 컴파일러를 쓴다면, 상수에 타입 제약과 자동 변환이 사용 가능한 릴리스 2018.08 이상이 필요해요. %-시길 상수의 자동 변환은 6.d가 필요합니다.
선택적인 타입 제약을 쓸 수 있는데, 그 경우 스코프 선언자를 반드시 사용해야 해요.
# !!WRONG!! missing scope declarator before type:
Int constant bar = 42;
# RIGHT:
our Int constant bar = 42;
변수와 달리 @-, %-, &-시길 상수는 선언자에서 파라미터화 타입을 지정해 파라미터화할 수 없어요.
# !!WRONG!! cannot parameterize @-sigiled constant with Int
# This will throw X::ParametricConstant
our Int constant @foo = 42;
# OK: parameterized types as values are fine
constant @foo = Array[Int].new: 42;
이 제한의 이유는 @와 % 시길 상수가 기본적으로 파라미터화할 수 없는 List와 Map 타입이기 때문이에요. 단순하고 일관되게 유지하기 위해, 이 구조에서는 파라미터화를 그냥 금지했어요.
@-, %-, &-시길 상수는 각각 Positional, Associative, Callable 역할에 대한 값의 암시적 타입 검사를 지정해요. @-시길 상수는(그리고 6.d 언어 버전부터는 %-시길 상수도) 값이 암시적 타입 검사를 통과하지 못하면 값의 자동 변환을 수행해요. @-시길 상수는 cache 메서드로, %-시길 상수는 Map 메서드로 변환합니다.
constant @foo = 42;
@foo.raku.say; # OUTPUT: «(42,)»
constant @bar = [<a b c>];
@bar.raku.say; # OUTPUT: «["a", "b", "c"]»
constant %foo = <foo bar>;
%foo.raku.say; # OUTPUT: «Map.new((:foo("bar")))»
constant %bar = {:10foo, :72bar};
%bar.raku.say; # OUTPUT: «{:bar(72), :foo(10)}»
# Pair is already Associative, so it remains a Pair
constant %baz = :72baz;
%baz.raku.say; # OUTPUT: «:baz(72)»
편의와 일관성을 위해 할당 연산자 대신 바인딩 연산자(:=)를 쓰거나, 시길 없는 상수 변수 이름 앞에 백슬래시를 붙이거나(시길 없는 변수와 같음), 아예 상수 이름을 생략해 익명 상수를 만들 수도 있어요. 익명 엔티티는 참조할 수 없으니, 명확성을 위해 BEGIN phaser를 쓰는 편이 나을 수 있어요.
constant %foo := :{:42foo};
constant \foo = 42;
constant = 'anon';