πΎ [CS] ν¨μν νλ‘κ·Έλλ°(Function Programming, FP)μ΄λ 무μμΌκΉμ?
- ν¨μν νλ‘κ·Έλλ°(Function Programming, FP)μ ν¨μλ₯Ό κΈ°λ³Έ κ΅¬μ± μμλ‘ μ¬μ©νλ νλ‘κ·Έλλ° ν¨λ¬λ€μμ λλ€.
- ν¨μν νλ‘κ·Έλλ°(Function Programming, FP)μμλ μμ ν¨μμ λ°μ΄ν°μ λΆλ³μ±μ κ°μ‘°νλ©°, λΆμμ©(Side Effect)μ νΌνλ κ²μ λͺ©νλ‘ ν©λλ€.
- μ΄λ₯Ό ν΅ν΄ μ½λμ κ°λ μ±, μ μ§λ³΄μμ±, μ¬μ¬μ©μ±μ λμ΄κ³ , λ³λ ¬ μ²λ¦¬μ κ°μ μν©μμλ μμ μ μ΄κ³ μμΈ‘ κ°λ₯ν μ½λλ₯Ό μμ±ν μ μμ΅λλ€.
1οΈβ£ ν¨μν νλ‘κ·Έλλ°(Function Programming, FP)μ ν΅μ¬ κ°λ .
1οΈβ£ μμ ν¨μ(Pure Function)
- μμ ν¨μ(Pure Function)λ μ
λ ₯κ°μ΄ κ°μΌλ©΄ νμ κ°μ κ²°κ³Όλ₯Ό λ°ννλ ν¨μμ
λλ€.
- ν¨μμ μΆλ ₯μ΄ μΈλΆ μνμ μμ‘΄νμ§ μκ³ , ν¨μ λ΄λΆμμ μΈλΆ μνλ₯Ό λ³κ²½νμ§λ μμ΅λλ€.
- μμ ν¨μ(Pure Function)λ λΆμμ©(Side Effect)μ΄ μκΈ° λλ¬Έμ, ν μ€νΈνκΈ° μ½κ³ , ν¨μμ λμμ μμΈ‘ν μ μμ΅λλ€.
π μμ.
// μμ ν¨μ μμ
public int add(int a, int b) {
return a + b; // μ
λ ₯κ°μ΄ κ°μΌλ©΄ νμ κ°μ κ²°κ³Όλ₯Ό λ°ν
}
2οΈβ£ λΆλ³μ±(Immutability)
- ν¨μν νλ‘κ·Έλλ°μμλ λ°μ΄ν°μ λΆλ³μ±μ μ€μνκ² μκ°ν©λλ€.
- μ¦, λ°μ΄ν°κ° μμ±λ νμλ λ³κ²½λμ§ μμμΌ νλ©°, νμνλ©΄ μλ‘μ΄ λ°μ΄ν°λ₯Ό μμ±ν©λλ€.
- λΆλ³μ±μ μ½λμ μμ μ±μ λμ΄κ³ , λμμ± λ¬Έμ λ₯Ό νΌν μ μκ² ν΄μ€λλ€.
π μμ.
// Javaμμμ λΆλ³ κ°μ²΄
final String name = "Kobe"; // nameμ λ³κ²½ν μ μλ κ°
π λμμ± λ¬Έμ (Concurrency Issue)
μ¬λ¬ μμ μ΄ λμμ μ€νλ λ λ°μν μ μλ μ€λ₯λ λΉμ μμ μΈ λμμ λ§ν©λλ€.
νλ‘κ·Έλ¨μμ μ¬λ¬ μ€λ λλ νλ‘μΈμ€κ° λμμ λμΌν λ°μ΄ν°λ μμμ μ κ·Όνκ³ μμ νλ €κ³ ν λ λμμ± λ¬Έμ (Concurrency Issue)κ° λ°μν μ μμ΅λλ€.
νΉν λ°μ΄ν°μ μΌκ΄μ±κ³Ό μμ μ±μ μ μ§νλ κ²μ΄ μ΄λ €μμ§λ©°, μ΄λ νλ‘κ·Έλ¨μ λ²κ·Έ, μΆ©λ, μμΈ‘νμ§ λͺ»ν λμμ μ΄λν μ μμ΅λλ€.
π μ€λ λ(Thread)
νλ‘μΈμ€ λ΄μμ μ€νλλ κ°μ₯ μμ λ¨μμ μμ νλ¦μ μλ―Έν©λλ€.
νλ‘μΈμ€κ° λ©λͺ¨λ¦¬, νμΌ νΈλ€, λ€νΈμν¬ μ°κ²°κ³Ό κ°μ 리μμ€λ₯Ό ν¬ν¨νλ λ 립μ μΈ μ€ν λ¨μλΌλ©΄, μ€λ λ(Thread)λ νλ‘μΈμ€ λ΄λΆμμ μ€μ λ‘ μ½λκ° μ€νλλ μ€ν νλ¦μ λλ€.
νλμ νλ‘μΈμ€λ μ¬λ¬ κ°μ μ€λ λ(Thread)λ₯Ό ν¬ν¨ν μ μμΌλ©°, κ° μ€λ λ(Thread)λ λ 립μ μΌλ‘ μ€νλ μ μμ΅λλ€.
π νλ‘μΈμ€(Process)
μ»΄ν¨ν°μμ μ€ν μ€μΈ νλ‘κ·Έλ¨μ μΈμ€ν΄μ€λ₯Ό λ§ν©λλ€.
κ°λ¨ν λ§ν΄, νλ‘κ·Έλ¨μ΄ λ©λͺ¨λ¦¬μμ μ€νλ λ νλ‘μΈμ€(Process)κ° λ©λλ€.
μ»΄ν¨ν°μμ μ€νλλ λͺ¨λ μμ© νλ‘κ·Έλ¨(μ: μΉ λΈλΌμ°μ , ν μ€νΈ νΈμ§κΈ°, λ°±κ·ΈλΌμ΄λ μλΉμ€ λ±)μ κ°κ° νλμ νλ‘μΈμ€(Process)μ λλ€.
3οΈβ£ κ³ μ°¨ ν¨μ(Higher-Order Function)
- κ³ μ°¨ ν¨μ(Higher-Order Function)λ λ€λ₯Έ ν¨μλ₯Ό μΈμλ‘ λ°κ±°λ, κ²°κ³Όλ‘ ν¨μλ₯Ό λ°ννλ ν¨μμ λλ€.
- μ΄λ₯Ό ν΅ν΄ ν¨μλ₯Ό μ‘°ν©νκ±°λ, λμ μΌλ‘ ν¨μλ₯Ό μμ±ν μ μμΌλ©°, μ½λμ μ¬μ¬μ©μ±μ λμΌ μ μμ΅λλ€.
π μμ.
public static void main(String[] args) {
Function<Integer, Integer> square = X -> X * X;
System.out.println(applyFunction(square, 5)); // 25 μΆλ ₯
}
public static int applyFunction(Function<Integer, Integer> func, int value) {
return func.apply(value);
}
4οΈβ£ μΌκΈ μλ―Ό(First-Class Citizen)
- ν¨μν νλ‘κ·Έλλ°μμλ ν¨μκ° μΌκΈ μλ―Ό(First-Class Citizen)μΌλ‘ μ·¨κΈλ©λλ€.
- μ΄λ ν¨μλ₯Ό λ³μμ ν λΉνκ±°λ, ν¨μμ μΈμλ‘ μ λ¬νκ±°λ, ν¨μμ λ°νκ°μΌλ‘ μ¬μ©ν μ μλ€λ κ²μ μλ―Έν©λλ€.
- ν¨μκ° λ€λ₯Έ λ°μ΄ν° νμ (μ«μ, λ¬Έμμ΄ λ±)μ²λΌ μ·¨κΈλκΈ° λλ¬Έμ λμ μΌλ‘ ν¨μμ νλμ λ³κ²½ν μ μμ΅λλ€.
π μΌκΈ μλ―Ό(First-Class Citizen, λλ First-Class Object)
νλ‘κ·Έλλ° μΈμ΄μμ λ³μλ ν¨μκ° λ€λ₯Έ λ°μ΄ν° νμ κ³Ό λμΌνκ² μ·¨κΈλκ³ , μμ λ‘κ² μ¬μ©ν μ μλ κ°μ²΄λ₯Ό μλ―Έν©λλ€.
μΌκΈ μλ―Ό(First-Class Citizen λλ First-Class Object)μΌλ‘ κ°μ£Όλλ κ°μ²΄λ λ³μμ ν λΉλκ±°λ, ν¨μμ μΈμ(Arguments)λ‘ μ λ¬λκ±°λ, ν¨μμ λ°ν κ°μΌλ‘ μ¬μ©ν μ μλ λ± λ€μν λ°©μμΌλ‘ νμ©λ μ μμ΅λλ€.μ΄ κ°λ μ μ£Όλ‘ ν¨μν νλ‘κ·Έλλ°(Function Programming, FP)μμ μ¬μ©λλ©°, νΉν ν¨μλ₯Ό μΌκΈ μλ―Ό(First-Class Citizen λλ First-Class Object)μΌλ‘ μ·¨κΈν μ μλμ§ μ¬λΆκ° κ·Έ μΈμ΄μ ν¨μν νλ‘κ·Έλλ°(Function Programming, FP) μ§μ μμ€μ κ²°μ νλ μ€μν μμκ° λ©λλ€.
5οΈβ£ λΆμμ©(Side Effects) μλ μ½λ.
- ν¨μν νλ‘κ·Έλλ°(Function Programming, FP)μμλ ν¨μκ° λΆμμ©(Side Effect)μ μΌμΌν€μ§ μλλ‘ μμ±ν©λλ€.
- λΆμμ©(Side Effects)μ΄λ ν¨μκ° μΈλΆ μνλ₯Ό λ³κ²½νκ±°λ, μ μΆλ ₯ μμ μ μννλ κ²μ λ§ν©λλ€.
- λΆμμ©(Side Effects)μ΄ μκΈ° λλ¬Έμ, μ½λμ μμΈ‘ κ°λ₯μ±κ³Ό μ¬μ¬μ©μ±μ΄ λμμ§λλ€.
6οΈβ£ ν¨μ ν©μ±(Function Composition)
- ν¨μ ν©μ±(Function Composition)μ μ¬λ¬ ν¨μλ₯Ό κ²°ν©νμ¬ μλ‘μ΄ ν¨μλ₯Ό λ§λλ κ²μ λ§ν©λλ€.
- μμ ν¨μλ€μ μ‘°ν©νμ¬ λ³΅μ‘ν μ°μ°μ μ²λ¦¬ν μ μκ² ν©λλ€.
- μ΄λ μ¬μ¬μ© κ°λ₯ν μμ ν¨μλ₯Ό λ§λ€μ΄, λ ν° κΈ°λ₯μ ꡬνν λ μ μ©νκ² μ¬μ©ν μ μμ΅λλ€.
2οΈβ£ ν¨μν νλ‘κ·Έλλ°(Function Programming, FP)μ νΉμ§.
1οΈβ£ μ½λμ κ°λ μ±κ³Ό μ μ§λ³΄μμ±.
- ν¨μν νλ‘κ·Έλλ°(Function Programming, FP)μμλ μ§§κ³ κ°κ²°ν μ½λλ₯Ό μμ±ν μ μμΌλ©°, μ½λκ° λͺ
ννκ³ μ½κΈ° μ¬μμ§λλ€.
- κ° ν¨μκ° λ 립μ μΌλ‘ λμνκΈ° λλ¬Έμ, λͺ¨λν(Modularization)μ ν μ€νΈκ° μ©μ΄ν©λλ€.
πββοΈ λͺ¨λν(Modularization)λ 무μμΌκΉμ?
2οΈβ£ λ³λ ¬ μ²λ¦¬μ λμμ±.
- ν¨μν νλ‘κ·Έλλ°(Function Programmin, FP)μ λΆλ³μ± λλΆμ, μ¬λ¬ μ€λ λ(Thread)μμ λμ μ€ννλλΌλ λ°μ΄ν°μ μΌκ΄μ±μ΄ μ μ§λ©λλ€.
- λ°λΌμ λ³λ ¬ μ²λ¦¬λ₯Ό ν λ λ°μ΄ν° κ²½ν©(Race Condition) λ¬Έμ κ° λ°μνμ§ μμΌλ©°, μμ νκ² μ€νν μ μμ΅λλ€.
π λ°μ΄ν° κ²½ν© λλ λ μ΄μ€ 컨λμ (Race Condition).
λ κ° μ΄μμ μ€λ λ(Thread) λλ νλ‘μΈμ€(Process)κ° λμμ 곡μ μμμ μ κ·Όνκ³ , κ·Έ κ²°κ³Όκ° μ€ν μμμ λ°λΌ λ¬λΌμ§λ μν©μ λ§ν©λλ€.
μ¦, λμμ± νλ‘κ·Έλλ°(Concurrent Programming)μμ μ€λ λλ€μ΄ κ²½μμ μΌλ‘ μμμ μ κ·Όν λ λ°μνλ λ¬Έμ λ‘, νλ‘κ·Έλ¨μ μλμΉ μμ κ²°κ³Όλ₯Ό μ΄λν μ μμ΅λλ€.λ μ΄μ€ 컨λμ (Race Condition)μ νΉν 곡μ μμ(λ³μ, λ°μ΄ν° ꡬ쑰, νμΌ λ±)μ λν΄ μ½κΈ°μ μ°κΈ° μμ μ΄ λμμ μ΄λ£¨μ΄μ§λ κ²½μ°μ λ°μνλ©°, λκΈ°νκ° μ λλ‘ μ΄λ£¨μ΄μ§μ§ μμΌλ©΄ λ°μ΄ν°μ μΌκ΄μ±μ΄ κΉ¨μ§κ² λ©λλ€.
3οΈβ£ ν μ€νΈ μ©μ΄μ±.
- μμ ν¨μ(Pure Function)λ μ
λ ₯κ°κ³Ό μΆλ ₯κ°μ κ΄κ³κ° λͺ
ννκΈ° λλ¬Έμ ν
μ€νΈνκΈ° μ½μ΅λλ€.
- λν, λΆμμ©μ΄ μκΈ° λλ¬Έμ λ 립μ μΌλ‘ ν μ€νΈν μ μμ΄ λ¨μ ν μ€νΈ(Unit Testing)μ μ ν©ν©λλ€.
π λ¨μ ν μ€νΈ(Unit Testing)
μννΈμ¨μ΄μ κ°λ³ κ΅¬μ± μμ(ν¨μ, λ©μλ, ν΄λμ€ λ±)κ° μ¬λ°λ₯΄κ² λμνλμ§ κ²μ¦νλ ν μ€νΈ λ°©λ²μ λλ€.
λ¨μ ν μ€νΈ(Unit Testing)μ λͺ©μ μ νλ‘κ·Έλ¨μ κ°μ₯ μμ λ¨μ(λ¨μ, μ λ)κ° μμλλ‘ μλνλμ§ νμΈνλ κ²μ λλ€.
μ΄λ₯Ό ν΅ν΄ κ° κ΅¬μ± μμκ° λ 립μ μΌλ‘ μ ννκ² λμνλμ§λ₯Ό 보μ₯ν μ μμ΅λλ€.
3οΈβ£ ν¨μν νλ‘κ·Έλλ°μ μμ (Java)
- Java 8λΆν°λ ν¨μν νλ‘κ·Έλλ°(Function Programmig, FP) μ€νμΌμ μ§μνκΈ° μν΄ λλ€ ννμ(Lambda Expression)κ³Ό μ€νΈλ¦Ό(Stream) APIλ₯Ό λμ νμ΅λλ€.
π λλ€ ννμ(Lambda Expression)
μ΅λͺ ν¨μ(Anonymous Function)λ‘, μ΄λ¦μ΄ μλ κ°λ¨ν ν¨μλ₯Ό μλ―Έν©λλ€.
λλ€ ννμ(Lambda Expression)μ μ¬μ©νλ©΄ ν¨μλ₯Ό λ³΄λ€ κ°κ²°νκ³ μ§κ΄μ μΌλ‘ μ μν μ μμΌλ©°, μ½λμ κ°λ μ±μ λμ΄κ³ κ°λ¨ν μμ μ μννλ λ° μ μ©ν©λλ€.
λλ€ ννμ(Lambda Function)μ μ£Όλ‘ ν¨μν νλ‘κ·Έλλ°(Function Programming, FP) μ€νμΌμ μ§μνκΈ° μν΄ λμ λμμΌλ©°, Java 8λΆμ² Javaμμλ μ¬μ©ν μ μκ² λμμ΅λλ€.
πββοΈ Java Streamμ΄λ 무μμΌκΉμ?
1οΈβ£ λλ€ ννμ(Lambda Expression)
- λλ€ ννμ(Lambda Expression)μ μ¬μ©νλ©΄ κ°κ²°νκ² ν¨μλ₯Ό μ μν μ μμ΅λλ€.
// κΈ°μ‘΄ λ°©μ
public int add(int a, int b) {
return a + b;
}
// λλ€ ννμ
BinaryOperator<Integer> add = (a, b) -> a + b;
System.out.println(add.apply(3,4)); // 7 μΆλ ₯
2οΈβ£ μ€νΈλ¦Ό(Stream) API
- μ€νΈλ¦Όμ 컬λ μ μ λ°μ΄ν°λ₯Ό νν°λ§, λ³ν, μ λ ¬, μ§κ³ν μ μλ ν¨μν νλ‘κ·Έλλ° μ€νμΌμ APIμ λλ€.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
List<Integer> nnumbers = Arrays.asList(1, 2, 3, 4, 5);
// μ§μλ§ νν°λ§νκ³ , κ° μ«μμ 2λ₯Ό κ³±ν 리μ€νΈ μμ±
List<Integer> result = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * 2)
.collect(Collectors.toList());
System.out.println(result); // [4, 8] μΆλ ₯
}
}
4οΈβ£ ν¨μν νλ‘κ·Έλλ°μ μ₯μ .
1οΈβ£ μ½λμ κ°κ²°μ±.
- ν¨μν νλ‘κ·Έλλ°μμλ μ½λκ° μ§§κ³ μ§κ΄μ μ΄κΈ° λλ¬Έμ, μ½κΈ° μ½κ³ μ μ§λ³΄μκ° μ©μ΄ν©λλ€.
2οΈβ£ μ¬μ¬μ©μ±κ³Ό νμ₯μ±.
- μκ³ μ¬μ¬μ© κ°λ₯ν ν¨μλ₯Ό μμ±νμ¬, λ€λ₯Έ νλ‘κ·Έλ¨μ΄λ νλ‘μ νΈμμ μ¬μ¬μ©ν μ μμ΅λλ€.
3οΈβ£ λ³λ ¬ μ²λ¦¬μ μ©μ΄μ±.
- λΆλ³μ± λλΆμ λ³λ ¬ μ²λ¦¬ νκ²½μμλ μμ νκ² μ€νν μ μμΌλ©°, ν¨μ¨μ μΈ λ³λ ¬ μ²λ¦¬κ° κ°λ₯ν©λλ€.
4οΈβ£ λλ²κΉ κ³Ό ν μ€νΈμ μ©μ΄μ±
- μμ ν¨μλ λ 립μ μΌλ‘ ν μ€νΈν μ μμ΄, λλ²κΉ κ³Ό λ¨μ ν μ€νΈκ° μ½μ΅λλ€.
5οΈβ£ ν¨μν νλ‘κ·Έλλ°μ λ¨μ .
1οΈβ£ λ¬λ 컀λΈ.
- ν¨μν νλ‘κ·Έλλ°μ κ°λ
μ μ΅μνμ§ μμ κ°λ°μμκ²λ λ¬λ 컀λΈκ° μμ μ μμ΅λλ€.
- νΉν λλ€ ννμ(Lambda Expression)κ³Ό κ³ μ°¨ ν¨μ(Higher-Order Function)μ μ΅μν΄μ§λ λ° μκ°μ΄ νμν μ μμ΅λλ€.
2οΈβ£ νΌν¬λ¨Όμ€ μ΄μ.
-
λΆλ³μ± λλ¬Έμ μλ‘μ΄ κ°μ²΄λ₯Ό λ§€λ² μμ±ν΄μΌ νλ κ²½μ° λ©λͺ¨λ¦¬ μ¬μ©λμ΄ μ¦κ°ν μ μμΌλ©°, μ±λ₯μ μν₯μ λ―ΈμΉ μ μμ΅λλ€.
- λ°λΌμ μν©μ λ°λΌ μ±λ₯ μ΅μ νλ₯Ό κ³ λ €ν΄μΌ ν©λλ€.
6οΈβ£ μμ½.
- ν¨μν νλ‘κ·Έλλ°μ μμ ν¨μ, λΆλ³μ±, λΆμμ© μλ μ½λλ₯Ό κ°μ‘°νμ¬, κ°λ μ±κ³Ό μ μ§λ³΄μμ±, μ¬μ¬μ©μ±μ΄ λμ μ½λλ₯Ό μμ±νλ νλ‘κ·Έλλ° ν¨λ¬λ€μμ λλ€.
- Java 8 μ΄νμ λλ€ ννμ(Lambda Expression)κ³Ό μ€νΈλ¦Ό(Stream) APIλ ν¨μν νλ‘κ·Έλλ°(Function Programming ,FP) μ€νμΌμ λμ νμ¬, κ°λ°μκ° λμ± κ°κ²°νκ³ ν¨μ¨μ μΈ μ½λλ₯Ό μμ±ν μ μκ² ν΄μ€λλ€.
- ν¨μν νλ‘κ·Έλλ°μ λ³λ ¬ μ²λ¦¬μ λμμ± λ¬Έμ μ κ°μ μ κ°μ§λ©°, μμ ν¨μλ€μ μ‘°ν©νμ¬ λͺ¨λν(Modularization)λ μ½λλ₯Ό μμ±ν μ μμ΄, μ½λμ μ¬μ¬μ©μ±κ³Ό νμ₯μ±μ λμ΄λ λ° μ 리ν©λλ€.