Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby의 함수형 프로그래밍(전체 가이드)

방금 함수형 프로그래밍에 대해 들었고 몇 가지 질문이 있을 수 있습니다.

좋아요...

  • 함수형 프로그래밍이란 정확히 무엇인가요?
  • 객체 지향 프로그래밍과 비교하면 어떤가요?
  • Ruby에서 함수형 프로그래밍을 사용해야 합니까?

어떻게 작동하는지 더 잘 이해할 수 있도록 이 질문에 답변해 드리겠습니다.

함수형 프로그래밍이란 무엇입니까?

단순한 유행어나 멋진 단어가 아니라 오래전부터 존재했지만 최근 다시 인기를 얻고 있는 실제 프로그래밍 패러다임입니다.

그리고 이 패러다임의 이면에 있는 기본 아이디어는 생각보다 이해하기 쉽습니다.

함수형 프로그래밍에서 우리는 상태 변경을 피합니다 &"순수한" 함수를 작성하려고 합니다. .

상태 변경을 피한다는 것은 이러한 함수가 함수 외부에서 아무 것도 변경하지 않고, 인스턴스 변수도 변경하지 않으며, 전달된 일부 개체를 변경하지 않는다는 것을 의미합니다...

그런 건 없어요!

Haskell과 같은 함수형 프로그래밍 언어에서 모든 데이터는 IMMUTABLE입니다.

변수와 같은 것이 있지만 수학적 세계에서처럼 행동합니다. 변수에 값이 주어지면 컴파일러는 이 변수를 다른 값으로 재정의하는 것을 허용하지 않습니다.

Ruby의 함수형 프로그래밍(전체 가이드)

함수형 프로그래밍의 이점

변경 가능한 데이터는 추적하기 어려운 미묘한 오류로 이어질 수 있기 때문에 불변성은 함수형 프로그래밍의 주요 이점입니다.

:

def all_different_from_first?(arr)
  first = arr.shift

  arr.all? { |n| n != first }
end

arr = [1,3,5,7,9]

p all_different_from_first?(arr)
# true

이 예에서는 배열의 모든 요소가 첫 번째 요소와 다른지 확인하고 싶습니다.

이 작업을 수행하려면 배열에서 첫 번째 요소를 제거하고 동시에 나머지 요소와 비교할 수 있도록 이 요소를 저장해야 합니다.

어떻게 하면 될까요?

우리는 배열로 작업하고 있으며 사용 가능한 방법 목록을 보면 Array#shift 방법이 우리가 원하는 것과 정확히 일치한다는 것을 알 수 있습니다.

다음까지는 잘 작동합니다...

... arr의 값을 봅니다. 메서드를 한 번 호출한 후:

all_different_from_first?(arr)
# true

arr
# [3,5,7,9]

깜짝!

배열에서 하나의 요소가 손실되었습니다(1 ) &우리는 눈치채지 못했습니다.

이것이 이러한 종류의 가변성 버그가 얼마나 교활할 수 있는지입니다.

고정 버전 :

def all_different_from_first?(arr)
  arr[1..-1].all? { |n| n != arr.first }
end

기능 대 OOP

우리 모두 함수형 프로그래밍을 채택해야 합니까?

이 모든 불변 상태가 함수형 프로그래밍을 OOP와 완전히 반대되는 것처럼 보일 수 있으며 어떤 의미에서는 그렇습니다. 그러나 두 프로그래밍 패러다임이 함께 ​​작동할 수 있는 방법이 여전히 있습니다. .

따라서 서두르거나 완전한 기능적 프로그래밍을 시작할 필요가 없습니다. Ruby는 어쨌든 OOP용으로 설계되었으므로 곡물에 맞서 싸울 것입니다.

좋은 소식 :

여전히 함수형 프로그래밍에서 최고의 아이디어를 사용하고 이를 Ruby 코드에 적용할 수 있습니다.

그 방법에 대해 이야기해 보겠습니다.

변동성을 최대한 줄이십시오

이를 수행하는 한 가지 방법은 attr_accessor를 사용하여 중지하는 것입니다. , attr_reader에만 충실 .

그런 다음 문자열, 배열 및 해시를 주시해야 합니다.

이러한 개체를 변경하는 메서드가 있습니다.

  • !로 끝나는 대부분의 메소드 (예:gsub! )
  • 삭제
  • 업데이트
  • 맑음
  • 시프트/시프트 해제/팝/푸시

첫 번째 단계는 이러한 방법을 인식하는 것입니다.

이러한 방법 중 하나를 사용해야 하는 경우 복제 개체에 대해 작업할 수 있습니다.

특정 문자열 및 해당 문자열의 복제본 :

str = "abcd"
dup = str.dup

clear하면 이러한 결과가 나타납니다. 중복된 문자열:

dup.clear

# str => "abcd"
# dup => ""

이렇게 하면 원래 문자열이 안전하게 유지됩니다.

부분 적용

함수형 프로그래밍에는 불변 데이터와 순수 함수보다 더 많은 것이 있습니다.

"커링"이라고도 하는 기능의 부분적 적용과 같습니다.

:

def add(a,b)
  a + b
end

add_five = method(:add).curry[5]

add_five.call(5)
# 10

add_five.call(20)
# 25

add하는 방법을 확인하세요. 메서드는 두 개의 인수를 사용하지만 curry를 사용하여 메서드는 인수 중 하나를 "미리 로드"할 수 있습니다.

그런 다음 두 번째 인수만으로 호출할 수 있는 람다를 얻습니다.

다음은 또 다른 예입니다. :

list = (1..10)

greater_than = ->(x,y) { y > x }.curry

list.select(&greater_than.(5))
# [6, 7, 8, 9, 10]

list.select(&greater_than.(8))
# [9, 10]

예시 하나 더 :

divisible_by = ->(x,y) { y % x == 0 }.curry

list.select(&divisible_by.(5))
# [5, 10]

list.select(&divisible_by.(2))
# [2, 4, 6, 8, 10]

요약

함수형 프로그래밍에 대해 배웠습니다. 그 핵심은 순수 함수와 불변 데이터입니다. 이것은 OOP와 완전히 호환되지 않는 코드에 대해 생각하는 방법일 뿐입니다.

읽어주셔서 감사합니다. 아직 뉴스레터를 구독하지 않았다면 구독하는 것을 잊지 마세요! 🙂