Closure

이성준·2023년 7월 17일

Java Notes

목록 보기
3/5

Closure ?

Closure Wikipedia

In programming languages, a closure, also lexical closure or function closure, is a technique for implementing lexically scoped name binding in a language with first-class functions.
Operationally, a closure is a record storing a function together with an environment.
The environment is a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or reference to which the name was bound when the closure was created.
Unlike a plain function, a closure allows the function to access those captured variables through the closure's copies of their values or references, even when the function is invoked outside their scope.

프로그래밍 언어에서 클로져 -- 어휘 클로져와 함수 클로져 -- 는 일급 함수를 사용하는 언어에서 어휘 범위의 이름 바인딩 구현을 위한 기술이다.
운영상, 클로저는 함수와 함께 환경을 저장하는 기록이다.
환경은 각 함수의 자유 변수(둘러싸인 범위에서 정의되고 지역적으로 사용되는 변수)에 값 혹은 참조를 클로저가 생성될 때 이름에 매핑하는 것이다.
일반 함수와는 달리, 클로저는 함수가 범위 밖에서 호출되는 경우에도 클로져들의 값 혹은 참조 복사본을 통해 그것들의 캡쳐된 변수들에 접근을 허락한다.


def f(x):
    def g(y):
        return x + y
    return g  # Return a closure.

def h(x):
    return lambda y: x + y  # Return a closure.

# Assigning specific closures to variables.
a = f(1)
b = h(1)

# Using the closures stored in variables.
assert a(5) == 6
assert b(5) == 6

# Using closures without binding them to variables first.
assert f(1)(5) == 6  # f(1) is the closure.
assert h(1)(5) == 6  # h(1) is the closure.

링크한 위키피디아 문서에 따르면 위의 파이썬 코드가 간단한 클로져의 구현을 보여주고 있다.

f(x), h(x) 둘 다 하나의 정수를 입력받는 함수 --또 다른 하나의 정수를 받아 앞서 받은 정수와의 합을 구하는 함수를 리턴하는-- 이다.

이때 f(x)와 h(x)을 클로져라고 하는데, 첫 문단에서 읽었듯이 클로저는 함수와 함께 환경을 저장하는 기록이다. 여기서 말하는 환경이란 f(x) 에서 x 를 이야기하며, a 에서는 x=1 이 환경이 된다.

따라서 a(5) = x + 5 이지만 a 에는 x=1 이라는 환경이 존재하기 때문에 a(5) = 6 이라는 결과가 나온다.

아래는 파이썬 코드를 자바 코드로 바꿔본 것이다.

import java.util.function.UnaryOperator;

public class Closure{

    public static void main(String[] args) {
        UnaryOperator<Integer> a = f(1);
        UnaryOperator<Integer> b = h(1);

        assert a.apply(5) == 6;
        assert b.apply(5) == 6;

        assert f(1).apply(5) == 6;
        assert h(1).apply(5) == 6;

        System.out.println(a.apply(5));
        System.out.println(b.apply(5));        

        System.out.println(f(1).apply(5));
        System.out.println(h(1).apply(5));

    }

    static UnaryOperator<Integer> f(int x){
        return new UnaryOperator<Integer>() {
            @Override
            public Integer apply(Integer y) {
                return x + y;
            }
        };
    }

    static UnaryOperator<Integer> h(int x){
        return y -> x + y;
    }
}

자바는 함수라는 개념이 존재하지 않기 때문에, Function 인터페이스를 상속받는 함수형 인터페이스, UnaryOperator 인터페이스를 사용하였다.

profile
기록

0개의 댓글