ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Recursion, Tail Recursion
    Elixir 프로그래밍 2019. 7. 30. 23:21

    무언가를 반복 처리해야 하는 경우 , Elixir에서는 recursiove 함수를 사용합니다. 

     

    for 문이 있기는 하지만, 다른 언어와의 for 문과는 좀 다르게 사용하는  Comprehensions 로 사용됩니다. 

    (https://elixirschool.com/ko/lessons/basics/comprehensions/

     

    다음의 코드는 1부터 주어지는 수까지의 합을 구하는 함수입니다.

    Recursion과 패턴 매칭으로 구현하였습니다. 

     

    동작은 잘 하지만, 위의 코드는 좋지 않은 코드 작성의 예입니다. 

    이유는 sum(n-1) + n 부분의 비효율성 때문입니다. 

     

    sum(n-1)은 다시 sum을 호출하는데, 이 sum 은 수행이 완료되는 시점에 다시 호출한 원래 sum 함수로 돌아와야 합니다. 

       sum(3)

           -> sum(2)

                 -> 1

           -> sum(2)

        sum(3) 

     

    n의 값이 작을 경우에야 별 문제가 없겠지만, n 값이 커지면, 함수 호출될 때 다마 호출한 함수로 돌아와야 하게 때문에 많은 스택을 사용해야 합니다. 

     

    이 코드는 다음과 같이 작성되어야 합니다. 

     

    앞의 코드와 다른 부분은 

    sum(n-1,acc) 로 recursive call이 이루어지는 부분이 함수의 가장 마지막이라는 겁니다. 

     

    누적 값은 acc에 계산이 되므로 sum(1, acc)  code에서는 그저 acc + 1을 return 합니다.

    sum(1,acc)가 수행되고 나서 바로 return을 하면되며, 이전의 코드 처럼 앞에 호출한 sum 함수로 다시 돌아갈 필요가 없습니다. 

     

    이런 식의 recursive call 을 tail recursion이라 합니다. 

     

    이런식으로 작성된 코드는  자기 자신을 호출하지만 가장 마지막 라인에서 호출이 되었으므로,  원래 호출한 위치로 돌아오지 않아도 됩니다. 

     

    혹시, recursive function을 작성해야 할 필요가 있으실 때는, 꼭 tail recursive 함수로 작성하시기 바랍니다.

    그리고, Elixir에서, 기본 제공하는 library 들은 모두 tail recursion으로 작성되어 있습니다. 

     

    아래의 Enum.reduce 함수가 대표적인 예입니다. 

     

               Enum.reduce([1, 2, 3], 0, fn x, acc -> x + acc end)

     

    여기서 reduce 함수의 두 번째 파라미터가 위의 코드 예와 같이 누적 값이 저장되는 변수가 되며, 누적 값의 초기 값을 0으로 지정한 것입니다. 

     

     

     

     

     

    'Elixir 프로그래밍' 카테고리의 다른 글

    예제 : 프로젝트 - JSON 을 가져와서 파싱 후 처리하기  (0) 2019.07.31
    Project, Application  (0) 2019.07.31
    패턴매칭  (0) 2019.07.30
    Function과 Module  (0) 2019.07.29
    변수와 애텀(Atom)  (0) 2019.07.28
Designed by Tistory.