ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 함수와 함수의 입출력
    Elixir 프로그래밍 2019. 7. 27. 23:25

    함수는 입력을 받아 이에 대한 조작을 하여 출력을 생성합니다. 

    출처 : https://www.javatpoint.com/edp-full-form

     

    위의 그림에서 "Processing"이 함수가 됩니다. 

     

     

    위의 코드에서와 같이 Elixir의 함수는  

        def  functionname(parameters) do  

                code... 

                .......

        end의 형태를 가지고 있습니다. 

     

    주의해야 할 사항은 함수의 이름은 반드시 영대 문자로 또는 숫자, 특수문자로 시작하지 않아야 합니다.  

     

    위의 코드 예제에서와 같이 함수의 이름은 "add"일 수도 있고, "합계"일 수도 있습니다.  Elixir는 유니코드를 지원하므로, 영어가 아닌 다른 언어로 함수 이름을 지정하는 것도 가능합니다. 

     

    Elixir의 함수는 다른 언어의 함수와는 조금 다른 면이 있습니다. 

     

    • 함수는 입력은 없을 수 있지만, 항상 출력 값은 가집니다. 위의 코드에서 no_return 함수는 아무 코드도 없지만, 이 함수를 호출하면 출력 값은 nil을 가지게 됩니다. 
    • 함수의 코드 중간에서 함수를 빠져나가는 return 문을 사용할 수 없습니다. 상당히 이상하게 보일 수 있지만, 이게 code의 흐름을 파악하기 용이하게 하고, 함수를 side effect가 없는 pure function이 되도록 합니다.  함수 내에서 return을 사용하지 못하여 불편할 것 같은데 전혀 그렇지 않습니다. 어찌 보면 Elixir의 큰 사상 변화 중 하나가 함수의 중간에 return이 없는 부분이라 할 수 있습니다. 
    • 함수의 출력 값은 함수 내의 가장 마지막 코드의 실행 값이 됩니다. 마지막 코드가 함수를 호출한 것이면, 함수의 호출 결과이고 어떤 값을 명시하면 그 명시한 값입니다. 

     

    함수의 입력(Parameter)와 출력(return value)는 Elixir의 모든 데이터 타입을 사용할 수 있습니다. 

     

    함수의 출력이 모든 데이터 타입을 사용한다는 것은, 데이터의 집합체를 반환할 수 도 있다는 것을 의미합니다. 한 가지의 값이 아니라 복수개의 값을 가지는 집합체를 반환할 수 있으므로 프로그래밍의 구현이 무척 편리해집니다.  

     

    그리고, 위의 코드에서와 같이 함수를 정의할 때 , 출력 값의 타입을 정의하지 않습니다. 

    이는 함수의 출력이 경우에 따라서 다른 종류의 값을 반환할 수 있음을 의미합니다. 

    이를 두 수의 나눗셈을 구현하는 함수의 코드를 예로 들겠습니다. 

     

    위의 함수 div를 

    • div(1,2) 로 호출하면 0.5를 반환합니다. 
    • div(1,0) 로 호출하면  {:error, "divide by zero"} 를 반환합니다.

    함수 구현 코드의 로직에 따라서 다른 종류의 값을 반환한다는 것은 여러모로 확장성과 편의성을 제공합니다. 

    함수의 반환 값의 종류를 판별하는 방법도, 다른 언어에서와 같이 일일이 비교를 하지 않고 패턴 매칭이라는 방법을 이용하여 분기시킬 수 있으므로 코드의 흐름의 구현이나 파악에 편의성을 제공합니다. 

     

    추가적으로 위의 코드 예제에서는 if 문을 사용하였지만, 실제로 Elixir에서는 if 문을 거의 사용하지 않고도 코딩을 할 수 있습니다. 이 또한, 패턴 매칭이라는 기법을 이용합니다.  

     

    패턴 매칭은 Elixir에서 아주 중요하고 편한 기법으로 다른 글에 상세히 기술하도록 하겠습니다. 

     

    함수의 입력은 출력과 같이 어떤 데이터 타입을 사용하는 것도 가능합니다. 출력에서와 같이 입력에서 집합체를 사용할 수 있으므로 사실 하나의 파라미터만 두고 이 파라미터를 집합체로 이용하면, 다수의 정보를 입력으로 주는 것도 가능합니다. 하지만, 일반적인 언어와 같이 복수개의 파라미터를 줄 수 있습니다. 

     

    출력에서와 같이 입력 파라미터도 데이터의 타입을 정의하지 않습니다. 이는 정의된 함수를 호출할 때, 어떤 파라미터를 이용하여 호출할 수도 있음을 의미합니다.  그리고, 이는 함수의 구현내에서 각 파라미터의 타입에 따라 다른 로직의 흐름을 구성할 수도 있음을 의미합니다. 이는 코드의 함축성을 높일 수 있는 방법입니다. 

    함수의 호출 시 입력된 파라미터에 따라 다른 로직이 구현되게 할 수도 있으며, 이에 대해서도 패턴 매칭 기법을 이용할 수도 있고 가드(Guard)를 이용할 수도 있습니다. 

     

    아래의 코드는 위의 div 함수를 문자열에도 적용할 수 있도록 수정 한 코드입니다. 

     

    위의 코드를 

     

    div("abc", "bc") 로 호출하면, 결괏값은 "abc"에서 "bc"를 뺀 "a"를 반환하며 div(1,2) 를 호출하면, 0.5를 반환합니다. 

     

    이처럼, Elixir에서는 동일 이름의 함수를 여러 개 둘 수 있으며 이때 동일 이름의 함수는 호출되는 파라미터 값에 따라서 적합한 함수가 호출됩니다.  다른 언어의 function overloading과 유사합니다. 

     

    그리고, 함수의 입력에서 중요한 부분 중 하나는  Elixir의 함수는 call by reference가 없다는 점입니다. 

    즉, 함수 내부에서 함수를 호출한 측의 데이터를 변경할 수 없습니다.  call by reference가 없으므로, 함수를 호출한 측의 값을 변경하려면 함수의 반환 값을 이용해야 합니다. 이 또한 Side Effect를 없애기 위함입니다. 

     

    함수의 파라미터에 대해서 기술하면,   아래의 코드에서 

    def div(a, b) do

       if (b == 0) do

            {:error, "divide by zero"}

       else

            a / b

        end

    end

     

    입력 파라미터 a, b는 함수 내부에만 존재하는 변수로 동작을 합니다. 이 함수를 빠져나오는 즉시, a,b 변수는 없어지게 됩니다.  

    그리고, 함수의 입력 파라미터를 변수로 받기 위해서는 영소 문자로 표시해야 합니다. 

     

    def div(a, b) do  와  def dev(A,B) do 는 매우 큰 차이입니다. a,b는 변수가 되며   A, B는 각각 A와 B 라는 애텀(Atom)이 됩니다. 

    이에 대해서는, 다른 글(변수와 Atom)에서 좀 더 상세히 적도록 하겠습니다.  우선은 함수의 인자를 받기 위해서는 파라미터를 영소 문자로 사용해야 한다고 생각하시면 됩니다. 

     

    Elixir 함수를 C 함수와 비교를 해서 다시 한번 특정 사항을 정리해 보겠습니다. 

     

    C Fucntion Code

    Elixit Function Code

    • Elixir 함수는 반환 형 데이터의 타입을 지정하지 않는다.  그러므로, 함수 내의 로직에 따라 경우에 맞는 다른 종류의 값을 반환하는 것이 가능하다. 
    • Elixir 함수는 입력 파라미터의 데이터의 타입을 지정하지 않는다. 함수를 호출하는 경우에 여러 가지의 다른 타입의 값으로 호출하는 것이 가능하다.
    • Elixir 함수는 Call by Reference가 없다. 
    • Elixir 함수는  반드시 반환 형값을 가진다. 함수의 구현 내용이 없을 경우 nil 값을 반환한다.
    • Elixir 함수는 return 문이 없어서 함수 코드의 중간에서 빠져나갈 수 없으며, 함수 코드의 마지막 라인의 값을 반환 값으로 가진다.
    • Elixir 함수는 다른 종류의 파라미터를 입력으로 가지는 동일 이름의 함수를 여러 개 가질 수 있으며, 함수 호출 시 주어진 파라미터 값에 따라서 적절한 함수가 호출된다. (Fucntion Overloading) 

    지금까지의 내용을 생각하시면서 , 

     

    https://elixirschool.com/ko/lessons/basics/functions/ 의 내용을 읽어보시기 바랍니다.

    위 글의 내용 중 패턴 매칭에 대한 부분은 추후에 다시 기술할 내용이니,  지금은 이해가 안 되어도 크게 개념치 않으셔도 됩니다. 

     

Designed by Tistory.