파이썬으로 함수형프로그래밍 짜기

김기욱·2021년 1월 13일
3
post-custom-banner

FP의 장점

  1. 명료함
  2. 효율성
  3. 테스트 용이성
  4. 병렬처리
  5. 재미

FP의 정의

상태변화와 변경가능한 데이터는 가능한 피하면서 작성하는 프로그래밍

FP의 핵심

순수함수(Pure Function)

  • 출력은 매개변수에만 의존되며, 외부 상태에 상관없다
  • 사이드이펙트가 없다(외부내용을 수정하지않는다)
  • X(입력)가 같으면 Y(출력)도 같다

OOP vs FP

OOP는 캡슐화를 통해 사이드이펙트를 제어
FP는 사이드이펙트를 아예 배제

FP는 No Object 변수를 최대한 지양
(여기서 말하는 Object는 클래스가 아님)

파이썬 FP 기능들

파이썬은 멀티패러다임 언어지만 FP를 위한 기능들이 존재한다.

  • Map reduce
  • High order function
  • Lambda
  • Generator
  • Iterator

High Order Function ==> 함수를 데이터처럼 활용함

예제1

def highFunc(f, a, b):
	return f(a, b)
def add(A, B):
	return A+B

예제 2

def MakeAddFunc(add):
	def Add(A):
    	return A + add
	return Add      
#ex
Addfunction = MakeAddFunc(10)
Addfunction(30)
MakeAddFunc(10)(30)

이렇게 사용가능한 이유? => 파이썬 함수는 1급 객체

장점 ? 구현을 미룬다(다형성)
아직 구현되지 않은 기능이 있더라도 그것에 관한 signiture만 있다면 함수를 받아서 조합해 사용할 수 있다.

Closure(클로저) : 함수가 저장하는 데이터

예시3

value = 10
def func(a):
	value_copy = value
    def Add(b):
    	return value_copy + a + b
    return Add 
AddFuction = func(10)
value = 20
AddFuction(5) # 10 + 10 + 5
중간에 전역변수 value가 바뀌었지만 영향을 받지 않는다.

파이썬에서 FP를 할 때의 문제점

  • tail recursion optimnization X
  • Lambda의 불편함
  • immutable data을 직접 만들어야함
  • Curring이 안됨

tail recursion optimization 이슈

꼬리재귀를 만들면 자동적으로 최적화시켜주는 언어가있음(메모리공간최적화)
(파이썬은 없음)

def recursive(i):
	if(i==1000):
    	return print('done')
    recursive(i+1)
recursive(0)

RecursionError: maximum recursion depth exceeded while calling a Python object

파이썬은 Default Maximum Recursion Depth는 대략 1000임
옵션값 변경으로 제한을 풀기전까지 원활하게 사용이 힘듬

왜? 파이썬은 순수함수지향형 언어가 아니기 때문이다.
그러므로 일일히 만들어야 한다.

해결책? ==> @Decorator(Syntactic Sugar)

예시4

#꼬리재귀 최적화를 유도하는 함수
def tail_recursive(f):
	def decorated(*args, **kwargs):
    	while True:
        	try: 
            	return f(*args, **kwargs)
            except Recurse as r:
            	args = r.args
                kwargs = r.kwargs
                continue
 	return decorated

문제 : 하나하나 만들기 어려움

실제적인 적용

More FP-specific Code = Math + Library
Laguage Featur // Implementation

Functional하게 문제를 해결하는 순서

  1. 문제를 쪼갠다.
  2. 쪼개진 문제를 더 쪼갠다.
  3. 하나의 문제를 해결하는 순수함수를 만든다.
  4. 순수함수를 결합한다.

접근법에 대한 비교

OOP : 객체를 만들고 객체들끼리 협력시키는 방법으로 프로그래밍
FP : 쪼개고 모듈화함

FP is based on Math
Category Theory의 공부가 필요하다.
Monade, Functor, Lambda도 수학적 개념을 프로그래밍으로 가져온 것

Library helps Python

  • Pymonad
  • fn.py(2014년 이후로 이슈들이 반영되고 있지않음)
  • Coconut

추천자료 : Category theory for Programmers

To make better Code

for문을 없애야 할까?
For loop is Functional
굳이 모든 for문을 재귀함수로 바꿀 필요가 없다

Pythonic Code
파이썬스러운 코드와는 배치 될 가능성이 있다

FP는 만병통치약이 아니다(파이썬 FP의 단점)

  • 느리다
  • 모든 함수가 순수할 수 없다
  • 배울 것이 많다.

그럼에도 불구하고 여러 최적화 방법이 존재한다

속도문제

  • Lazy Evaluation
  • Memoization

순수성

  • 하스켈같은 함수지향 언어도 순수함수만 존재하는 것이 아니다

학습곡선

  • 데코레이터의 사용법을 정확히 숙지하면 여러 응용이 가능해진다.

결론

파이썬은 FP로 완전히 대체하기가 힘들다. 그러므로 적재적소에 사용하자.
객체로 디자인해서 사용하는게 좋은 경우에는 그렇게 쓰자.

출처 : https://www.youtube.com/watch?v=UPmQHHpS3cw&ab_channel=PyConKorea

profile
어려운 것은 없다, 다만 아직 익숙치않을뿐이다.
post-custom-banner

0개의 댓글