Functions

함수는 프로그래밍의 핵심 구성 요소로, 특정 작업을 수행하는 독립적이고 재사용 가능한 코드 블록이다.
함수는 입력값(매개변수)을 받아 처리한 후 결과값을 반환할 수 있다.
함수는 코드의 가독성을 높이고 모듈화된 구조를 만들어 유지보수와 확장성을 크게 개선할 수 있다.

함수는 프로그래밍의 근본 개념으로, 다양한 언어에서 조금씩 다른 문법과 용법을 가지고 있지만 기본적인 원리는 동일하다.
각 언어의 특성과 장점을 이해하고 적재적소에 적용함으로써 더 효율적이고 관리하기 쉬운 소프트웨어를 개발할 수 있다.

함수의 기본 개념

  • 함수는 하나의 작업 또는 연산을 수행하기 위해 정의된 코드 집합이며, 필요에 따라 여러 번 호출하여 사용할 수 있다.
  • 함수는 입력 값(매개변수)을 받고, 이를 처리한 후 결과(반환 값)를 돌려줄 수 있어 코드 재사용과 분업에 용이하다.

함수 선언 및 구현

  • 함수 정의: 함수를 정의할 때는 함수 이름과 괄호 안에 입력 매개변수를 명시하며, 중괄호 또는 들여쓰기로 본문을 구분한다.

  • 예시 (Python):

    1
    2
    3
    4
    5
    6
    7
    8
    
    def 함수이름(매개변수1, 매개변수2, ):
      # 함수 본문 (실행될 코드)
      return 반환값  # 선택적
    
    def greet(name):
        print("Hello", name)
    
    greet("Alice")  # "Hello Alice" 출력
    

    이 예시는 매개변수를 받아 인사 메시지를 출력하는 간단한 함수이다.

  • 예시 (C):

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    #include 
    
    int add(int a, int b) {
        return a + b;
    }
    
    int main() {
        int result = add(5, 3);
        printf("Result: %d\n", result);
        return 0;
    }
    

    C언어에서는 함수 선언, 정의, 호출의 순서가 중요하며, main() 함수가 프로그램의 시작점 역할을 한다.

  • 예시 (JavaScript):

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    function 함수이름(매개변수1, 매개변수2, ) {
      // 함수 본문 (실행될 코드)
      return 반환값;  // 선택적
      }
    
    function greet(name) {
      console.log("Hello, " + name);
    }
    
    greet("Alice");  // "Hello, Alice" 출력
    

    JavaScript에서는 함수가 일급 객체로 취급되어 변수에 할당하거나 다른 함수의 인수로 전달할 수 있다.

함수의 주요 요소

  1. 함수 이름

    • 함수의 목적을 명확히 나타내는 이름을 사용해야 한다.
    • 일반적으로 동사 또는 동사구를 사용한다 (예: calculateTotal, getUserData)
    • 코드 가독성과 유지보수성을 높이는 데 중요하다.
  2. 매개변수(Parameters)

    • 함수에 전달되는 입력값이다.
    • 함수 내에서 사용할 수 있는 변수로 작동한다.
    • 함수의 유연성을 높여준다.
    • **매개변수(Parameters)**는 함수 정의 시 변수로 지정되어 호출 시 전달되는 값을 받아들이며, 인수와 매핑된다.
    • Python과 같은 언어에서는 기본 인수 값, 키워드 인수, 가변 인수 등 다양한 방식으로 매개변수를 사용할 수 있다.
    1
    2
    3
    4
    5
    
    def greet(name):  # name은 매개변수
        return f"안녕하세요, {name}님!"
    
    # 함수 호출 시 '김철수'라는 인수(argument)를 전달
    message = greet("김철수")
    
  3. 함수 본문

    • 실제로 실행될 코드가 포함된 부분이다.
    • 주어진 작업을 수행하는 명령문들의 집합이다.
  4. 반환값(Return Value)

    • 함수가 실행을 마친 후 호출한 곳으로 돌려주는 값이다.
    • return 문을 사용하여 지정한다.
    • 반환값이 없는 함수도 있으며, 이런 함수는 일반적으로 “프로시저” 또는 “void 함수"라고 부른다.
    • 함수는 return 문을 통해 결과 값을 반환할 수 있으며, 이를 이용해 계산된 값을 변수에 저장하거나 다른 함수 호출의 입력으로 사용할 수 있다.

함수의 유형

  • 내장 함수와 사용자 정의 함수: 대부분의 언어는 미리 정의된 내장 함수를 제공하며, 개발자는 필요에 따라 새로운 기능의 사용자 정의 함수를 구현할 수 있다.
  • 익명 함수: 이름 없이 정의되어 일회성으로 사용되거나 함수 내부에서 다른 함수의 인수로 사용되는 경우가 많으며, JavaScript의 화살표 함수(Arrow Function) 등이 이에 해당한다.
  • 순수 함수와 고차 함수: 순수 함수는 동일한 입력에 대해 항상 동일한 출력을 내며 부작용이 없고, 고차 함수는 함수를 인수로 받거나 함수를 반환하는 특징을 갖는다.

함수의 종류

  1. 사용자 정의 함수

    • 프로그래머가 직접 작성한 함수이다.
    • 특정 프로그램의 요구사항에 맞게 설계된다.
  2. 내장 함수(Built-in Functions)

    • 프로그래밍 언어에서 기본적으로 제공하는 함수이다.
    • Python의 print(), len(), JavaScript의 console.log(), parseInt() 등이 여기에 해당한다.
  3. 익명 함수(Anonymous Functions)

    • 이름이 없는 함수로, 주로 일회성으로 사용된다.
    • Python에서는 lambda 표현식, JavaScript에서는 화살표 함수로 구현된다.
    1
    2
    
    # Python lambda 함수
    double = lambda x: x * 2
    
    1
    2
    
    // JavaScript 화살표 함수
    const double = (x) => x * 2;
    
  4. 재귀 함수(Recursive Functions)

    • 자기 자신을 호출하는 함수이다.
    • 주로 문제를 더 작은 동일한 형태의의 문제로 나누어 해결할 때 사용된다.
    1
    2
    3
    4
    5
    
    def factorial(n):
        if n <= 1:
            return 1
        else:
            return n * factorial(n-1)
    
  5. 고차 함수(Higher-Order Functions)

    • 다른 함수를 매개변수로 받거나 함수를 반환하는 함수이다.
    • 함수형 프로그래밍의 핵심 개념이다.
    • JavaScript의 map(), filter(), reduce() 등이 대표적이다.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    
    // 함수를 매개변수로 받는 고차 함수
    function applyOperation(x, y, operation) {
        return operation(x, y);
    }
    
    // 함수를 반환하는 고차 함수
    function multiplyBy(factor) {
        return function(number) {
            return number * factor;
        };
    }
    
    const double = multiplyBy(2);
    console.log(double(5)); // 10
    

함수의 장점

  1. 코드 재사용성
    • 동일한 코드를 여러 번 작성할 필요 없이 함수로 정의하여 필요할 때마다 호출할 수 있다.
  2. 모듈화(Modularity)
    • 프로그램을 논리적 단위로 분리하여 복잡성을 관리할 수 있다.
    • 각 함수는 특정 작업만 담당하므로 코드 이해와 유지보수가 쉬워진다.
  3. 추상화(Abstraction)
    • 복잡한 구현 세부사항을 숨기고 사용자에게 간단한 인터페이스를 제공한다.
    • “어떻게(how)“보다 “무엇을(what)” 수행하는지에 집중할 수 있게 한다.
  4. 디버깅 용이성
    • 문제가 발생했을 때 관련 함수만 검사하면 되므로 디버깅이 쉬워진다.

함수 매개변수 전달 방식

  1. 값에 의한 전달(Pass by Value)
    • 매개변수로 값의 복사본이 전달된다.
    • 함수 내에서 매개변수를 변경해도 원본 값은 영향을 받지 않는다.
    • 기본 데이터 타입(숫자, 문자열 등)에 주로 적용된다.
  2. 참조에 의한 전달(Pass by Reference)
    • 매개변수로 값의 참조(메모리 주소)가 전달된다.
    • 함수 내에서 매개변수를 변경하면 원본 값도 변경된다.
    • 객체, 배열 등의 복합 데이터 타입에 주로 적용된다.

함수 스코프(Scope)와 변수 가시성

  1. 지역 변수(Local Variables)
    • 함수 내에서 선언된 변수로, 해당 함수 내에서만 접근 가능하다.
    • 함수 실행이 종료되면 메모리에서 제거된다.
  2. 전역 변수(Global Variables)
    • 함수 외부에서 선언된 변수로, 프로그램 어디서든 접근 가능하다.
    • 프로그램이 종료될 때까지 메모리에 유지된다.
  3. 클로저(Closures)
    • 함수가 자신이 생성된 환경(렉시컬 환경)을 기억하는 현상이다.
    • 내부 함수가 외부 함수의 변수에 접근할 수 있게 한다.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
function createCounter() {
    let count = 0;  // 외부 함수의 변수
    
    return function() {  // 내부 함수 (클로저)
        count++;  // 외부 함수의 변수에 접근
        return count;
    };
}

const counter = createCounter();
console.log(counter());  // 1
console.log(counter());  // 2

함수의 고급 개념

  1. 함수 오버로딩(Function Overloading)

    • 같은 이름의 함수가 다른 매개변수 타입이나 개수를 처리할 수 있는 기능이다.
    • Python은 기본적으로 지원하지 않지만, 다양한 방법으로 구현 가능하다.
    • Java, C++ 등의 언어에서 널리 사용된다.
  2. 기본 매개변수(Default Parameters)

    • 함수 호출 시 매개변수가 제공되지 않을 경우 사용할 기본값을 지정한다.
    1
    2
    3
    4
    5
    
    def greet(name, greeting="안녕하세요"):
        return f"{greeting}, {name}님!"
    
    print(greet("김철수"))  # "안녕하세요, 김철수님!"
    print(greet("김철수", "반갑습니다"))  # "반갑습니다, 김철수님!"
    
  3. 가변 인자(Variable Arguments)

    • 함수가 임의 개수의 인자를 받을 수 있게 한다.
    • Python에서는 *args(위치 인자)와 **kwargs(키워드 인자)를 사용한다.
    1
    2
    3
    4
    5
    6
    7
    
    def sum_all(*numbers):
        total = 0
        for num in numbers:
            total += num
        return total
    
    print(sum_all(1, 2, 3, 4, 5))  # 15
    
  4. 순수 함수(Pure Functions)

    • 동일한 입력에 대해 항상 동일한 출력을 반환한다.
    • 부작용(side effects)이 없다 (외부 상태 변경 없음)
    • 함수형 프로그래밍의 핵심 개념이다.

함수 설계 원칙

  1. 단일 책임 원칙(Single Responsibility Principle)

    • 함수는 한 가지 작업만 수행해야 한다.
    • 여러 작업을 수행하는 함수는 더 작은 함수로 분리하는 것이 좋다.
  2. DRY(Don’t Repeat Yourself) 원칙

    • 코드 중복을 피하고 재사용 가능한 함수를 작성해야 한다.
  3. KISS(Keep It Simple, Stupid) 원칙

    • 함수는 가능한 한 간단하고 이해하기 쉽게 작성해야 한다.
  4. 명확한 이름과 문서화

    • 함수 이름은 그 기능을 명확히 나타내야 한다.
    • 주석이나 문서 문자열(docstring)로 함수의 목적, 매개변수, 반환값을 설명해야 한다.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    def calculate_area(radius):
        """
        원의 면적을 계산합니다.
    
        매개변수:
            radius (float): 원의 반지름
    
        반환값:
            float: 원의 면적
        """
        import math
        return math.pi * (radius ** 2)
    

실제 사용 예시

  1. 데이터 처리 함수

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    def filter_adults(people):
        """
        사람들의 목록에서 성인(18세 이상)만 필터링합니다.
    
        매개변수:
            people (list): 사람 객체의 목록, 각 객체는 'age' 속성을 가짐
    
        반환값:
            list: 성인만 포함된 목록
        """
        return [person for person in people if person['age'] >= 18]
    
  2. 유틸리티 함수

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    /**
     * 주어진 문자열이 유효한 이메일 형식인지 확인합니다.
     * @param {string} email - 검사할 이메일 주소
     * @returns {boolean} 유효한 이메일이면 true, 아니면 false
     */
    function isValidEmail(email) {
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return emailRegex.test(email);
    }
    

참고 및 출처