본문 바로가기

23년 1학기 학교공부/프로그래밍언어개론

[OCaml] Module system

목차

    728x90
    반응형
    SMALL

    📁 모듈 시스템(Module system)

    📌 모듈은 자료(변수)와 행동(함수)로 구성되는데, 함수형 언어에서 행동은 곧 자료이므로 모듈은 자료의 모음이다.

     

    OCaml은 모듈 시스템을 지원하며, 프로그램은 여러개의 모듈로 구성된다.

    JAVA/C++의 클래스와 유사하다.

     

    🔎 모듈과 클래스의 차이점

    모듈은 그 자체로 타입이 아니다. 때문에 객체화할 수 없으며, 상태(state)를 지니지 않는다.

     

    클래스는 instance를 가질 수 있으며 각 객체마다 상태를 지니지만,

    모듈은 단순히 자료들의 모음일뿐이므로 함수를 호출하거나 자료를 읽는 행위만 가능하다.

     

    이때 state란, class를 instance화 했을때 볼 수 있다.

    예를 들어 아래와 같은 class A가 존재하고, x, y라는 instance가 존재한다고 가정하자.

    class A { int v; }
    
    A x; A y;

    이 때 x라는 객체 안에 v가 있고, y라는 객체 안에 v가 존재한다. 두 v는 각 객체마다 달라질 수 있으며, 이를 상태라고 한다.

     

    OCaml의 모듈은 위와 같이 어떤 상태가 객체에 귀속되지 않으므로 static과 유사하다고 볼 수 있다.

     

     

    📁 OCaml에서의 module system 예시

    모든 소스코드 파일은 그 자체로 모듈이 된다.

     

    모듈이름은 파일 이름을 그대로 따오되, 맨 앞글자를 대문자로 바꾸어 사용한다.

    모듈 이름의 맨 앞글자가 대문자가 아닌 경우 compiler error가 발생한다.

     

    예를 들어 operation.ml이라는 파일이 있을 때, 이를 모듈로 사용하기 위해서 Operation과 같이 바꿀 수 있다.

     

    모듈 이름을 이용하여 모듈 내의 변수 또는 함수에 접근할 수 있다.

    [moduel_name].[var_name]

     

    📝 사용 예시

    operation.ml에 definition이 나열되어있어 오류가 날 것 같아 보일 수 있지만, 파일 내에서 사용하지 않는 definition은 컴파일시 오류가 나지 않는다.

     

     

    📁 Nested Module

    Nested Module이란, 모듈 내에 정의된 모듈을 뜻한다.

    module [module_name] = struct [defs] end

    * defs : definition들의 나열

    위 코드는 definition이다.

     

    파일이 곧 모듈이므로, 위 definition으로 생성된 모듈은 모두 파일이라는 모듈 내에서 생긴 모듈이기 때문에 nested module이다.

    C++ / Java의 inner class와 유사한 기능이다.

     

    Nested module에 접근하는 방법은 다음과 같다.

    [module_name].[nested_module_name].[var_name]

     

    📝 사용 예시

    모듈 안의 모듈 안의 모듈을 만드는 것도 가능하다.

     

     

    📁 Module opening

    모듈을 개방(open)하여 모듈의 변수를 접근할 때 모듈 이름을 생략할 수 있다.

    open [module_name]

    위와 같은 방법으로 현 scope에서 모듈 내 변수를 모듈 이름 없이 접근할 수 있다.

    모듈 내의 definition들을 해당 위치에 붙여넣기 한 효과를 낸다.

    위 코드도 definition이다.

    open 코드 아래부터 해당되는 모듈이름을 생략할 수 있다.

    C++의 using namespace와 유사하다.

     

     

    🔎 주의사항

    여러 모듈에 같은 이름이 있다면 confilct가 발생할 수 있다.

    open FloatOp 코드가 open IntOp보다 아래에 있어서 add가 shadowing된다.

    FloatOp.add의 인자로 int가 전달되는 것으로 판단되기 때문에 컴파일 오류가 발생한다.

     

    🔎 local module opening

    let-in expression을 사용하여 특정 scope 내에서만 모듈을 개방할 수 있다.

    let open [module_name] in [expression]

     

    📝 사용 예시

     

     

    📁 Module renaming

    모듈 이름이 긴 경우, "약자"를 이용하여 모듈을 저장할 수 있다.

    module [abbrevation] = [module_name]

    * abbreviation : 모듈의 이름을 지칭할 약자

    abbreviation에 와일드카드를 쓸 수는 없다.

     

    📝 사용 예시

     

    728x90
    반응형
    LIST