계정: 로그인
AA 📝
Racket

http://www.racket-lang.org/

Scheme 언어의 구현물 중 하나.

다운로드 및 설치

항상 http://download.racket-lang.org/에서 최신 버전의 공식 설치 파일을 내려받으실 수 있습니다. 두 드롭다운 메뉴 중

선택하신 후 파일명 버튼을 누르시면 됩니다.
download-platform.png

단, 리눅스 사용자의 경우, 달리 특별한 이유가 없는 한 여기에서 다운받지 마시고 자신이 사용하고있는 리눅스 배포판에서 공식적으로 패키징하여 배포하는 것을 설치하시기를 (비록 이쪽이 더 오래된 버전이더라도) 추천합니다. 예를 들어, 데비안이나 우분투 사용자의 경우

$ sudo apt-get install racket

명령으로 설치하실 수 있습니다.

SICP 교재를 위한 실습 환경 설정: 초간단 요약

이 절은 2014년 2학기 건국대학교 인터넷·미디어공학부 프로그래밍 언어론 강좌 수강생들을 위한 실습 환경을 설정하는 방법을 가능한 한 짧게 축약하여 안내하고 있으며, 모든 학생들은 1차 숙제를 제출하시기 전에 이 절의 내용 만큼은 반드시 수행하셔야 합니다.

시간이 없는 학생들을 위해 이유는 일체 설명하지 않은 채 진행하므로, 왜 이렇게 설정해야 하는지 이유를 좀 더 제대로 이해하고자 하는 학생들은 이 절 다음에 이어지는 절들도 모두 읽어보실 것을 권합니다만, 강제 사항은 아닙니다.

  1. Racket을 설치하고 "DrRacket"을 실행한 후, 상단 메뉴 중 "언어" → "언어 고르기"를 누릅니다.
    menu-langsel.png

  2. "언어를 고르십시오."라는 창이 열리면 맨 위의 "The Racket Language"를 선택하고 맨 아래 좌측의 "상세히 보기"를 누릅니다.
    lang-sharp.png

  3. 확장되어 열린 오른쪽 부분 중, "출력 스타일"을 "write"로 바꾸고 맨 아래 "자동 #lang 줄"을 "#lang planet neil/sicp"로 바꾼 후 (철자를 틀리지 않도록 주의) 확인을 누릅니다.
    langsel-autolang.png

  4. 우상단의 "실행"을 누릅니다.
    run.png

  5. 대화 창의 프롬프트(">")가 사라지고, 맨 아래에 "PLaneT: neil/sicp 설치 중..."이라는 메세지가 나오면서 SICP 언어 모듈 설치가 시작됩니다.
    sicp-start.png

  6. 진행 과정에서 대화 창에 붉은 색으로 경고 메세지들이 나타나는데, 수업 진행에는 영향이 없으니 무시하고 기다리면 됩니다. 약 십수 초 ~ 수 분 정도 후에 대화 창의 프롬프트가 다시 나타나고 맨 아래에 "PLaneT: neil/sicp 완료."라고 나타나면, DrRacket을 종료합니다.
    sicp-finish.png

  7. 이후로는 DrRacket을 실행시키기만 하면 별도의 설정 없이 수업 교재와 호환되는 실습 환경이 갖춰져있게 됩니다. 이제 그냥 상단의 정의 창에 프로그램을 작성하시거나 하단의 대화 창에 값을 확인해볼 표현식을 입력하시면 됩니다. 단, 정의 창 맨 첫줄의 "#lang planet neil/sicp"라는 내용은 이 강좌가 끝날 때까지 절대 지우거나 수정하거나 더 위에 (앞에) 무엇인가를 추가하시면 안됩니다.
    firstline.png

부연: 언어 설정

C 언어의 실제 명세에도 ISO C 89나 ISO C 99, K&R C 등 몇가지 변종들이 있듯이, Scheme 언어의 실제 명세에도 여러가지 변종들이 있다. C 언어의 구현물 중 하나인 Gnu Compiler Collection (GCC)의 C 컴파일러 CC가 여러가지 C 명세 변종들을 지원하듯이, Scheme 언어의 구현물 중 하나인 Racket도 Scheme 언어의 여러가지 명세들을 지원한다. 이 절은 이 기능과 설정 방법에 관해 설명한다.

기본 개념

Racket의 기본 인터페이스는 두 개의 창으로 나뉘어 있다. 위쪽 (혹은 설정에 따라 왼쪽) 창은 "정의 창 (definition window)"이라고 하여 소스 코드(즉, 정의들을 모은 텍스트 파일)를 새로 편집하거나 기존 소스 코드를 읽어들여 편집하는 창이고, 아래쪽 (혹은 오른쪽) "대화 창 (interaction window)"이라고 하여 표현식(expression)을 읽어들여 그 평가치를 출력하는 REPL (Read-Eval-Print Loop) 프롬프트 창이다.

대화 창의 상단에는 "언어: XXXXX;"라고 표시된 부분이 있는데, Scheme 언어 명세들 중에서 현재 대화 창에 적용되어있는 언어 명세를 표시한다.

Racket을 설치하고 처음 실행시켰을 때에는 이부분에 다음 스크린샷과 같이 "언어: 언어가 선택되지 않았습니다"라고 표시된다:
racket-010-initial.png

이 상태에서는 대화 창에 표현식을 입력해도 Racket이 값을 평가하지 못한다. 어떤 언어 명세를 기준으로 평가해야하는지 모르기 때문이다:
racket-020-initial-error.png

언어를 선택해보자. Racket의 상단 메뉴에서 "언어 → 언어 고르기"를 누른다:
racket-030-initial-menu-langsel.png

처음에는 아래 스크린샷처럼 아무 언어도 선택되어있지 않다:
racket-040-initial-langsel-none.png

Scheme 언어의 실질적인 표준 명세인 R5RS (Revised Revised Revised Revised Revised Report on Scheme) 명세를 선택해보자:
racket-050-initial-langsel-R5RS.png

이제 Racket 창 좌측 최하단에 "R5RS"라고 표시된다. 여기에 표시되는 값은 "메뉴 상에서 선택된 언어 명세"이며, 이 부분이 노랗게 칠해져있는 것은 아직 이 내용이 대화 창에는 반영되어있지 않다는 뜻이다. 실제로, 대화 창 상단에는 여전히 "언어: 언어가 선택되지 않았습니다"라고 표시되어있다:
racket-060-initial-R5RS-pre.png

이제 우측 상단의 "실행" 버튼을 눌러서 메뉴의 선택 사항을 대화 창에 반영해보자:
racket-070-initial-R5RS.png

이제 대화 창에서 여러가지 표현식들을 R5RS 명세를 기준으로 평가해볼 수 있고, R5RS 명세에 포함된 프로시져들을 사용할 수도 있다:
racket-080-initial-R5RS-interaction.png

언어를 선택하는 또다른 방법은 소스 코드 상에 언어를 지정해주는 것이다. 이 기능을 사용하려면 언어 고르기 메뉴에서 맨 위쪽의 "소스에 정의된 언어를 이용합니다"를 선택해야한다:
racket-090-langsel-src.png

물론, 좌측 최하단에 "소스를 통해서 언어를 결정합니다"라고 노란 바탕색 위에 표시된 것만으로는 아직 대화 창에는 제대로 반영되지 않은 것이다. (이때 위쪽 정의 창에 자동적으로 처음 한 줄이 작성되어있는 것에 주목하라. 나중에 이 값을 바꿔볼 것이다):
racket-100-src-pre.png

마찬가지로, 여기서 우측 상단의 "실행" 버튼을 눌러주면 소스 코드 상의 (위쪽 정의 창의 첫 줄에 쓰여있는) "#lang racket"이 반영되어 대화창 초반에 "언어: racket;"이라고 표시된다:
racket-110-src.png

이 방식(소스를 통해 언어 결정)을 통해 다른 언어 명세로 바꿔보자. 위쪽 정의창에서 "racket"을 지우고 다른 언어 이름을 입력해본다. 수정하는 과정에서 이 행이 갑자기 붉은색으로 보이는건 Racket이 "그런 이름의 언어 명세를 모른다"는 뜻이므로, 아래 스크린샷은 정상이다:
09-racket-src-R5.png

반면에, 이 행이 아래와 같이 검은색으로 보이는건 Racket이 그런 이름의 언어 명세를 알고 있다는 뜻이다. 이 상태에서 우측 상단의 "실행" 버튼을 누르면 대화창에 반영된다:
10-racket-src-R5RS.png

SICP 언어 명세 설치

그럼 SICP 교재로 실습을 진행하려면 어떻게 해야할까? 원래 SICP는 Racket이 아니라 MIT Scheme이라는 또다른 구현물을 기준으로 쓰여있으며, 따라서 SICP 교재를 실습해보기에 가장 잘 호환되는 환경은 단연 MIT Scheme이다. 하지만 MIT Scheme이라는 구현물은 (Racket에 비해 상대적으로) 사용법이 다소 불친절하고 비직관적이며, 특히 Emacs에 익숙하지 않은 사람들로서는 다루기가 꽤 까다롭니다. 또한, 문법 검사 등 여러가지 부가적인 편의 기능들도 Racket 쪽이 압도적으로 강력하다. 즉, SICP 교재를 따라가며 실습하는 데에 있어서, 호환성을 생각한다면 MIT Scheme이고 편의성을 생각한다면 Racket이라는 뜻이다.

두 가지 이익을 모두 취하는 방법으로서 MIT Scheme의 편의성을 높이는건 어려울 듯하고, 여기서는 Racket의 SICP 호환성을 높이는 방법을 설명한다. 지금까지 설명한 "언어 명세 선택 기능"을 활용하여, 이른바 "Racket용 SICP 명세 모듈"을 설치하는 것이다. 물론, Racket의 기본 배포본에는 SICP 모듈이 들어있지 않으며, 이는 third-party 모듈로서 따로 개발되어 있다:

이 모듈을 설치하는 방법은 간단하다:

  1. 다음과 같이 "소스를 통해 언어를 결정합니다" 상태에서 소스 코드 상단에 "#lang planet neil/sicp"라고 (따옴표 없이) 입력한다. 이때, 이 문장이 붉은색으로 표시되는게 정상이다. 아직 Racket에 SICP 언어 명세 모듈이 설치되기 전이므로, Racket은 아직 이 언어를 모른다:
    11-racket-planet-pre.png

  2. 인터넷 연결 상태를 확인한다. 처음 한 번(언어 모듈 설치 시)에 한하여 반드시 인터넷에 연결되어있어야 한다.

  3. 이 상태에서 우측 상단의 "실행" 버튼을 누르면 아래와 같이 하단에 "설치중"이라는 메세지가 나오며, 대화창의 프롬프트가 잠시 사라진다:
    12-racket-planet-installing01.png

  4. 설치에는 (네트웍과 PC 성능에 따라 다르지만) 대략 1~2분 정도가 소요된다. 만일 설치 중 대화창에 붉은 색으로 오류나 경고 메세지가 뜨더라도 일단은 무시한다. (현재까지 확인된 바로는, 큰 문제 없이 작동한다.)
  5. 아래와 같이 "완료" 메세지가 나오고 대화창의 프롬프트가 다시 보이면 설치 완료:
    13-racket-planet-installing02.png

  6. Racket을 종료했다가 다시 실행한다.

SICP 언어 명세 사용

Racket을 다시 실행시켜보면 아마 정의창에는 여전히 "#lang racket"이라고 적혀있고, 대화창에도 "언어: racket;"이라고 나올 것이다. 이게 아직은 정상이며, 이 이유는 곧 알게된다:
racket-110-src.png

정의 창의 첫번째 줄을 "#lang planet neil/sicp"로 바꿔본다. 이게 검은색으로 표시된다는건, 이제 Racket이 이런 이름의 언어를 안다는 뜻이다:
14-racket-planet-installed-pre.png

"실행" 버튼을 눌러 대화창에 반영한다:
15-racket-planet-installed.png

이제 SICP 교재의 내용과 거의 완전히 호환되는 상태로 Racket을 사용할 수 있다.

그런데, 매번 Racket을 껐다가 켤 때마다 이렇게 정의 창 첫 줄을 수정해주어야 하나? 아니다. 아예 SICP 호환 상태를 기본 값으로 설정하는 두 가지 방법이 있다.

SICP를 기본 값으로 설정하는 방법 #1 (비추천)

지금부터 설명할 첫번째 방법은 추천하지 않는 방법으며, 특별한 이유가 없는 한 이 방법을 쓰지 말라는 뜻으로 여기에 잠시만 예시한다.

아래와 같이 언어 선택 창에 새로 등장한 "SICP (PLaneT 1.17)"을 골라준다:
16-racket-SICP-langsel.png

"실행" 버튼까지 눌러서 대화창에 반영해주고 나면 뭔가 아주 제대로 된 것 같지만, 한 가지 문제가 있다. 아래와 같이 정의 창에 간단한 정의를 입력한 후 우측 상단의 "문법 검사" 기능을 사용하면:
17-racket-SICP-langsel-code.png

아래와 같이 오류가 발생한다. 이는 (어쩌면 유저 불량일지도 모르지만) 아마도 SICP 언어 모듈의 버그인 것으로 보인다:
18-racket-SICP-langsel-error.png

SICP를 기본 값으로 설정하는 방법 #2 (추천)

그럼 SICP 언어 모듈을 쓰는 한 문법 검사 기능은 못 쓰는건가? 아니다. 아래와 같이 두 번째 방법을 쓰면 되며, 모든 학생들에게 이 방법을 추천한다.

언어 선택 창에서 맨 위의 "소스에 정의된 언어를 이용합니다"를 고른 후, 하단의 "상세히 보기"를 누른다. 우측에 나오는 패널의 맨 아래에 있는 "자동 #lang 줄"이라는 항목의 값을 #lang planet neil/sicp로 수정한다:
19-racket-planet-auto.png

이제 매번 Racket을 껐다 켤 때마다 다음과 같이 모든 환경이 자동적으로 SICP 호환 모드로 설정되고:
20-racket-planet-auto-restart.png

물론 이 상태에서는 문법 검사도 제대로 작동한다:
success-planet.png

참고

부연: 출력 스타일

대화 창의 REPL이 읽어들인 표현식에 대한 평가치를 출력할 때 정확히 어떤 형식으로 출력하는가 하는 것을 '출력 스타일 (output style)'이라고 합니다. 평가치가 같더라도 출력 스타일이 바뀌면 다르게 출력될 수 있습니다. 예를 들어, 아래 세 스크린샷은 두 표현식 (cons 1 2)(list 1 2 3)서로 다른 세 가지 출력 스타일로 각각 출력한 장면입니다:
racket-outputstyle-example-r5rs.png racket-outputstyle-example-sicpprint.png racket-outputstyle-example-sicpwrite.png

일단 기본적으로, 언어 설정을 바꾸면 출력 스타일도 바뀔 수 있습니다. 위의 세 스크린샷들 중 첫번째는 R5RS 언어의 기본값이었고 두번째는 SICP (#lang planet neil/sicp) 언어의 기본값이었습니다. 즉, 모든 언어들은 자신의 기본적인 출력 스타일을 정해두고 있습니다.

하지만, 원한다면 설정된 언어를 바꾸지 않은 채로 출력 스타일을 조정할 수도 있습니다. "언어 고르기" 창에서 "상세히 보기"를 누르면 나오는 "출력 문법" 부분을 보면 "출력 스타일" 항목이 있습니다. 언어에 따라 허용되는 추가 설정값들이 제한되는 경우도 많지만, 최대로 허용될 경우 '생성자', 'Quasiquote', 'write', 'print' 중 하나를 선택할 수 있습니다:
racket-outputstyle-sel.png

물론, 그렇다고 해서 Racket이 보여줄 수 있는 다양한 출력 스타일들이 결국 총 네 가지로 귀결된다는 뜻은 아닙니다. 예를 들어, R5RS 언어의 (기본값인) 'write' 스타일과 SICP 언어의 (허용되는 추가 설정값들 중 하나인) 'write' 스타일은 아래와 같이 서로 조금 다릅니다:
racket-outputstyle-example-r5rs.png racket-outputstyle-example-sicpwrite.png

SICP 교재

SICP 교재는 다음과 같은 출력 스타일을 상정하고 있고:

> (cons 1 2)
(1 . 2)
> (list 1 2 3)
(1 2 3)
> '(1 2 3)
(1 2 3)

이는 R5RS 언어 모듈의 기본 출력 스타일인 'write 스타일'과 거의 동일합니다.즉, SICP 교재는 출력 스타일에 있어서 만큼은 R5RS를 충실히 따르고있다는 뜻입니다:
racket-outputstyle-example-r5rs.png

반면에, 이 문서의 위쪽에서도 소개한 바 있는 Racket 용 SICP 언어 모듈은 의외로 전혀 다른 출력 스타일인 'print 스타일'이 기본값입니다. 물론 읽고있는 교재와 사용하는 도구(언어 구현물)의 출력 스타일이 서로 다르다고 해서 학습에 큰 지장이 발생할 리야 없겠지만, 아무래도 눈에 거슬리는 건 사실입니다:
racket-outputstyle-example-sicpprint.png

Racket 용 SICP 언어 모듈의 출력 스타일을 SICP 교재의 출력 스타일과 똑같아지도록 조정하려면 다음과 같은 두 가지 작업을 해야합니다. 하나는 한 번만 설정해두면 향후 다른 소스 코드를 load하거나 Racket을 아예 껐다가 켜도 계속 적용되는 사항이고, 나머지 하나는 매 번 "실행" 버튼을 누를 때마다 (혹은, 최소한 Racket을 껐다 켜거나 새로운 소스 코드를 작성할 때마다) 한 번 씩 반복해야 하는 작업입니다.

Write 스타일로 변경 (1회만 설정)

이 문서의 윗 부분에서 소개하고 안내해드렸던 대로 SICP 언어 모듈을 설치하고 설정하셨다면, 출력 스타일이 기본값인 print 스타일로 지정되어있습니다. 이를 write 스타일로 바꿔둡니다:
racket-outputstyle-sel.png

이제 mcons 같은 내부 구성자가 드러나는 대신 좀 더 "직관적이고 기호적인" 표기로 바뀌게 됩니다:
racket-outputstyle-example-sicpwrite.png

하지만, 위 스크린샷에서 보시다시피 아직 SICP 교재의 출력 스타일과 완전히 동일하지는 않습니다. 괄호 대신 중괄호(curly braces)가 쓰인건 이 자료 구조가 '변경 가능함(mutable)'을 구별해서 나타내기 위함이라고 합니다. 즉, 어쩌면 이것이 SICP 교재의 출력 스타일보다 더 개선된(?) 스타일일지도 모릅니다. (참고: http://stackoverflow.com/questions/9347294/mcons-in-dr-racket)

R5RS 호환성 향상 (매번 설정)

아무튼, 이 중괄호마저 교재와 완전히 똑같은 괄호로 바꾸고자 한다면, 기본적으로 SICP 언어 모듈을 사용하되 R5RS 언어의 특성 일부도 받아들임으로써 R5RS 호환성을 다소 향상시켜두어야 합니다. 이를 수행하기 위한 명령은
(#%require r5rs/init)
인데, 이 명령을 어디에서 수행하느냐에 따라 다음 두 가지 방법 중 하나를 선택할 수 있습니다: