racket/load 언어

racket/load 언어

racket/load 언어는 모듈 본문의 각 최상위 형식을 load에서와 똑같이 개별적으로 eval에 넘겨 평가하는 방식을 지원해요. 상호작용적으로 최상위 형식을 실험해 볼 때 쓰기 좋습니다.

출처: Racket Reference - The racket/load Language

본문

#lang racket/load — 패키지: base

racket/load 언어는 모듈 본문에 있는 각 최상위 형식을 load에서와 같은 방식으로 개별적으로 eval에 넘겨 평가하는 것을 지원해요.

평가에 쓰이는 네임스페이스(namespace)는 racket/load 모듈 인스턴스와 모듈 레지스트리를 공유하지만, 최상위 환경은 별도로 가지며 racket의 바인딩으로 초기화됩니다. racket/load 모듈 인스턴스마다 네임스페이스가 하나씩 만들어져요. 즉 racket/load 언어를 쓰는 여러 모듈은 네임스페이스를 공유하죠. racket/load 라이브러리는 #%module-begin#%top-interaction 형식만 내보내는데, 이 형식들이 실질적으로 평가 네임스페이스를 교체하고 eval을 호출합니다.

예를 들어 racket/load를 쓰는 모듈의 본문에는 module 형식이 들어갈 수 있어요. 그래서 다음 모듈을 실행하면 5가 출력됩니다:

#lang racket/load
 
(module m racket/base
    (provide x)
    (define x 5))
 
(module n racket/base
    (require 'm)
    (display x))
 
(require 'n)

racket/load를 쓰는 모듈의 정의는 현재 네임스페이스에서 평가돼요. 그 말은 loadeval이 그 정의들을 볼 수 있다는 뜻이죠. 예를 들어 다음 모듈을 실행하면 6이 출력됩니다:

#lang racket/load
 
(define x 6)
(display (eval 'x))

racket/load 모듈 안의 모든 형식이 최상위에서 평가되기 때문에, provide를 써서 바인딩을 모듈 밖으로 내보낼 수는 없어요. 마찬가지로 모듈 본문 형식의 평가가 본질적으로 동적이어서, 모듈을 컴파일해도 실질적인 이득이 거의 없습니다. 이런 이유 때문에 racket/load는 최상위 형식을 상호작용적으로 탐구하는 용도로만 쓰고, 더 큰 프로그램을 구성하는 데는 쓰지 않는 게 좋아요.

더 알아보기