ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [프언] #12. Manual Type Annotation
    2023-2학기/프로그래밍언어 2023. 12. 5. 01:37

    지난 글에서 다루었던 Type Checker를 Scala에서 구현한다고 생각해봅시다.

    def typeOf(env: Env, expr: Expr): Tpe = {
    	expr match {
    		case _: IntVal => IntType
    		case v: Var => env.get(v) match {...}

    이런 식으로 작성을 시작하겠죠. expr가 Add일 경우는 Recursion을 사용해서 구현할 수 있습니다.

    		case Add(l, r) => (typeOf(l), typeOf(r)) match {
    			case (IntType, IntType) => IntType
    			case _ => throw new TypeError(...)
    		}

    이렇게요. 그런데 문제가 있습니다. 바로 Proc Expression의 경우 단순 Recursion으로 구현할 수 없기 때문입니다.

    위와 같은 식에서 $t_2$가 무엇인지 알기 위해서는 $t_1$이 뭔지를 알아야 하는데, 그럴 수 없기 때문이죠. 이 문제를 해결하기 위해 사용되는 방식은 크게 2가지인데요, 이번 글에서는 그 중 하나인 Type Annotation에 대해 알아보겠습니다.

     

    Type Annotation

    Type Annotation이라는 기법은, 프로그래머들이 Procedure를 정의할 때 Procedure에 들어가는 인수들의 Type을 직접 설정하도록 하는 방식입니다. C, C++, Java 등의 언어에서 이 방식을 사용하고 있죠.

    proc (x: int) (x + 1)

    이렇게요. Int를 받아 1을 더하는 프로시져를 만들 때, "이 프로시져는 Int 하나를 인수로 받는다"라고 미리 프로시져를 정의할 때 못 박아 두는 겁니다.

    letrec (x: int): int = 
    	if iszero x then 0
    	else (double (x - 1)) + 2
    in double 2

    이런 식으로 letrec에도 똑같이 활용 가능합니다.

    이렇게 Type Annotation을 사용하면, 아래와 같이 Recursion을 이용해 Type Checker를 구현할 수 있습니다.

    def typeOf(env: Env, expr: Expr): Tpe = {
    	expr match {
    		case Proc(v, vtype, pbody, penv) => {
    			val new_env = env.updated(v, vtype)
    			ProcType(vtype, typeOf(new_env, pbody))
    		}
    	}
    }

     

    Type Checking Vs. Execution

    이런 Type Checker는 실제로 프로그램을 실행하지는 않습니다. 프로그램을 Execute(실행) 하기 위해서는 프로시져가 받는 모든 인수들을 전부 계산해야 하는데, Type Checking을 위해서는 그저 인수의 Type만 계산하면 되므로, 근본적인 차이가 있습니다.

     

    감사합니다.


    이 글은 컴퓨터공학과 학부생이 개인 공부 목적으로 작성한 글이므로, 부정확하거나 틀린 내용이 있을 수 있으니 참고용으로만 봐주시면 좋겠습니다. 레퍼런스 및 글에 대한 기본적인 정보는 이 글을 참고해 주세요.

     

Designed by Tistory.