Rebol, Factor, Shell, Go에서 영감을 받은 동형(호모아이코닉) 언어 Rye를 빠르게 익히기 위해, 최소한의 설명과 함께 компакт한 실용 코드를 보여준다.
Rye는 Rebol, Factor, Shell, Go에서 영감을 받은 역동적(dynamc)이며 동형(호모아이코닉) 언어입니다.
Rye의 핵심 주장은 유연한 문법을 가지면서도 상태(state)에 대해서는 엄격할 수 있다는 것입니다. Rye에는 Null이 없고, 기본이 상수(constant)이며, 모든 것을 표현식(expression)으로 다루고, 키워드가 없으며, 활성 요소(active element)는 모두 함수입니다. 단어(words)는 컨텍스트의 계층 구조 안에서 평가됩니다… 원칙 더 보기
하지만 이런 내용은 이미 여러곳에서 설명되었습니다. 여기서는 최소한의 코멘트로 компакт하고 실용적인 코드를 보여주며 빠르게 가르쳐 보려 합니다. 그럼 시작해 봅시다…
rye; # 20%의 시간으로 Rye 80% 배우기 [1/3] ; _Learn X in Y minutes_에서 영감을 받음 ; 이것은 주석입니다 ; ; 주의: 모든 Rye 토큰은 공백으로 구분되어야 합니다 ; ## 값(Values) ; 다음은 리터럴 값들입니다 1 ; 정수 3.14 ; 소수(부동소수) "hello" ; 문자열 { 1 2 "three" } ; 블록 ; null은 없습니다 ; 다음은 생성된 값들입니다(생성자 함수를 사용합니다) true ; 불리언 값을 반환하는 함수 dict { "name" "Jim" "age" 32 } table { "planet" "diameter" } { "Earth" 12756 "Mars" 6779 } fn { a b } { a + b } context { name: "Jim" age: 32 } ; 단어 값 타입이 여러 가지 있습니다 a-word ; 바인딩된 값으로 평가됩니다 set-word: ; 상수 바인딩을 생성합니다(오른쪽에서 왼쪽) mod-word:: ; 변수를 생성/수정합니다(오른쪽에서 왼쪽) ?get-word ; 함수인 경우에도 호출하지 않고 값을 반환합니다 :lset-word ; 상수를 생성합니다(왼쪽에서 오른쪽) ::lmod-word ; 변수를 수정합니다(왼쪽에서 오른쪽) 'lit-word ; 단어 자체로 평가됩니다 .op-word ; 왼쪽 값을 첫 번째 인자로 받습니다 |pipe-word ; 왼쪽 값을 함수로 파이프합니다 ; Rye에는 49가지 값 타입이 있습니다. 위 목록은 전부가 아닙니다 ; ## Rye 코드 ; Rye 데이터는 Rye 값의 블록으로 구성됩니다 { "some" 'data } { { some } { 'more } ?data |or .code } { print "Hello world" } { if hot { open 'main-window } } ; ## 평가기(Evaluator) ; Rye에는 여러 평가기가 있지만, 메인 평가기는 다음처럼 동작합니다: "literal values" ; 리터럴 값은 자기 자신으로 평가됩니다 123.45 303 { "blocks" don-t .eval } ; 블록도 자기 자신으로 평가됩니다 'lit-words ; lit-word도 마찬가지(단어로 평가됨) ; 단어의 동작은 타입에 의해 결정됩니다 word ; 바인딩된 값으로 평가됩니다 ; 또는 오류 print "Yello" ; 함수에 바인딩되어 있으면 그 함수를 호출합니다 set-word: "value" ; 상수 단어를 만들고 값을 바인딩합니다 mod-word:: 1 ; 정수 타입 변수를 수정하거나 생성합니다 "on the left" :lset-word ; set-word와 같지만 왼쪽에서 값을 받습니다 2 ::lmod-word ; lmod-word도 동일 ?print ; get-word는 함수인 경우에도 호출하지 않고 값을 반환합니다 ; 평가기에는 더 많은 동작이 있지만, 먼저 더 많은 값 타입을 알아야 합니다 ; ## 내장 함수(Built-in functions) ; 평가기는 Rye 값 블록을 평가하는 명확한 규칙만 가지고 있을 뿐입니다. ; 그 외에는 키워드나 특별한 폼(special form)이 없습니다. 그래서 무엇이든 하려면 ; 함수가 필요하고, 일단은 내장 함수가 필요합니다. ; 위에 설명한 동작을 갖고, 예를 들어 단 4개의 내장 함수만으로도 ; 최소한의 Rye 런타임을 만들 수 있습니다. ; true - 인자를 받지 않고 불리언 true를 반환 ; print - 어떤 Rye 값이든 받아 출력 ; if - 불리언과 코드 블록을 받음 ; loop - 정수와 코드 블록을 받음 ; 이제 첫 프로그램을 쓸 수 있습니다 if true { print "Hello world" } ; 두 번째 프로그램 loop 3 { print "Wah" } ; 출력: Wah ; Wah ; Wah ; 런타임에 더 많은 내장 함수를 등록해 봅시다: prns, range, for\, either ; 그리고 is-multiple-of for\ range 1 3 'i { print either is-multiple-of i 2 { "Tik" } { "Tok" } } ; 출력: Tok Tik Tok ; `for\`를 무서워하지 마세요. 이건 각 반복마다 설정할 단어를 추가로 받는 ; `for`의 변형일 뿐입니다. 일반 `for`는 그게 필요 없습니다. ; 위의 모든 것은 (내장) 함수를 적용한 결과입니다. 분해해 보면: for\ ; - 블록, 단어(i), 그리고 평가할 코드 블록을 받습니다 range ; - 두 정수를 받아 { 1 2 3 } 같은 블록을 만듭니다 print ; - 인자를 출력합니다 either ; - 불리언과 두 코드 블록을 받아, 블록 평가 결과를 반환합니다 is-multiple-of ; - 두 정수를 받아 불리언을 반환합니다 ; ## 더 많은 내장 함수 ; Rye에는 많은 내장 함수가 있습니다. 맛보기로 몇 가지를 보겠습니다: _+ 101 10 ; 111 _< 101 10 ; false ; _+ _< 역시 그냥 함수이며, 보통 op-word로 ; 사용합니다[이건 나중에 더 설명] and true false ; false any { false "Jim" 101 } ; Jim all { true _> 10 5 "Bob" } ; Bob _++ to-upper "ban" "ana" ; BANana index? "Joey" "e" ; 2 [관례: 명사? 는 get-명사] join\with { "uncle" "bob" } "," ; uncle,bob head { 11 22 33 } 2 ; { 11 22 } max { 48 256 127 } ; 256 length? union { 1 2 } { 2 3 } ; 3 transpose { { 1 2 } { "a" "b" } } ; { { 1 "a" } { 2 "b" } } ; 여기서는 op-word를 사용합니다. op-word는 [2/3]에서 충분히 소개합니다 sort\by { "abc" "cd" "e" } { .length? } ; { "e" "cd" "abc" } map { 1 2 3 } { * 10 } ; { 10 20 30 } reduce range 10 20 'acc { * acc } ; 6704425728000 for { 11 12 13 } { .prns } ; 출력: 11 12 13 var 'i 0 ; var 함수는 변수를 만듭니다 type? 123.4 ; decimal to-integer "404" ; 404 now .year? ; 2026 "[ 1, 2, 3 ]" |parse-json ; list { 1 2 3 } match-block { 1 2 3 } { a b c } , a + c ; 4 match { 7 5 3 } { { a : bb } { a - avg bb } } ; 3.0 ; 더 많은 내장 함수를 보려면 함수 레퍼런스를 방문하세요: ; ; https://ryelang.org/info/base.html ;
위에서 언급한 함수 레퍼런스입니다.
이 문서는 1/3에 해당합니다. 이 글은 기본을 보여줍니다. 다음 두 편은 더 흥미롭겠지만, 설명하기는 아마도 조금 더 어려울 겁니다. 계속 지켜봐 주세요!