[javascript] 민화와 람다는 왜 이렇게 다른가요?

나는 DrBoolean의 을 읽고 자바 스크립트 FP를 배우고 있습니다.

함수형 프로그래밍 라이브러리를 검색했습니다. Ramda와 Folktale을 찾았습니다. 둘 다 함수형 프로그래밍 라이브러리라고 주장합니다.

그러나 그들은 너무 다릅니다.

  • Ramda 는 목록을 처리하기위한 유틸리티 함수를 포함하는 것 같습니다 : 맵, 리 듀스, 필터 및 순수 함수 : 카레, 작성. 모나드, 펑터를 다룰 내용이 없습니다.

  • 그러나 Folktale 에는 목록이나 기능에 대한 유틸리티가 포함되어 있지 않습니다. 모나드와 같은 자바 스크립트에서 일부 대수 구조를 구현하는 것 같습니다 : Maybe, Task …

사실 더 많은 도서관을 찾았는데 모두 두 가지 범주에 속하는 것 같습니다. 밑줄과 lodash는 Ramda와 같습니다. Fantasy-land, pointfree-fantasy는 민화와 같습니다.

이 매우 다른 라이브러리를 모두 기능적 이라고 할 수 있습니까 ? 그렇다면 각각을 기능적 라이브러리로 만드는 것은 무엇입니까?



답변

기능적 특징

함수형 프로그래밍 또는 함수형 라이브러리를 정의하는 것에 대한 명확한 경계는 없습니다. 기능 언어의 일부 기능은 Javascript에 내장되어 있습니다.

  • 일류, 고차 함수
  • Lambda / 익명 함수, 클로저 포함

다른 것들은주의해서 자바 스크립트에서 수행 할 수 있습니다.

  • 불변성
  • 참조 투명성

나머지는 ES6의 일부이며 현재 부분적으로 또는 완전히 사용 가능합니다.

  • 컴팩트하고 간결한 기능
  • 꼬리 호출 최적화를 통한 성능 재귀

그리고 자바 스크립트의 정상적인 범위를 넘어서는 많은 것들이 있습니다.

  • 패턴 매칭
  • 게으른 평가
  • 동질성

그러면 라이브러리는 지원하려는 기능의 종류를 선택하고 선택할 수 있으며 여전히 “기능적”이라고 합리적으로 호출 할 수 있습니다.

판타지 랜드 사양

Fantasy-land 는 수학적 범주 이론 및 추상 대수에서 함수형 프로그래밍 (예 : Monoid , FunctorMonad)으로 이식 된 여러 표준 유형에 대한 사양입니다 . 이러한 유형은 상당히 추상적이며 더 친숙한 개념을 확장 할 수 있습니다. 예를 들어, Functor map는 함수 map를 사용하여 배열을 연결하는 방식 인 Array.prototype.map.

민화

Folktale 은 Fantasy-land 사양의 다양한 부분을 구현하는 유형 모음과 작은 동반 유틸리티 함수 모음입니다. 이러한 유형은 Maybe , Either , Task (다른 곳에서 Future라고 부르는 것과 매우 유사하며 Promise에 대한 더 합법적 인 사촌) 및 Validation과 같은 것입니다.

Folktale은 아마도 Fantasy-land 사양의 가장 잘 알려진 구현이며 잘 알려져 있습니다. 그러나 확정적 또는 기본 구현과 같은 것은 없습니다. fantasy-land는 추상 유형 만 지정하며 물론 구현은 이러한 구체적인 유형을 만들어야합니다. 기능적 라이브러리라는 Folktale의 주장은 분명합니다. 일반적으로 기능적 프로그래밍 언어에서 볼 수있는 데이터 유형을 제공하므로 기능적 방식으로 프로그래밍하는 것이 훨씬 더 쉽습니다.

Folktale 문서 ( 참고 : 문서의 최신 버전이 아님) 의이 예제 는 사용 방법을 보여줍니다.

// We load the library by "require"-ing it
var Maybe = require('data.maybe')

// Returns Maybe.Just(x) if some `x` passes the predicate test
// Otherwise returns Maybe.Nothing()
function find(predicate, xs) {
  return xs.reduce(function(result, x) {
    return result.orElse(function() {
      return predicate(x)?    Maybe.Just(x)
      :      /* otherwise */  Maybe.Nothing()
    })
  }, Maybe.Nothing())
}

var numbers = [1, 2, 3, 4, 5]

var anyGreaterThan2 = find(function(a) { return a > 2 }, numbers)
// => Maybe.Just(3)

var anyGreaterThan8 = find(function(a) { return a > 8 }, numbers)
// => Maybe.Nothing

람다

Ramda (면책 조항 : 저는 저자 중 한 명입니다)는 매우 다른 유형의 라이브러리입니다. 새로운 유형을 제공하지 않습니다. 1 대신 기존 유형에서보다 쉽게 ​​작동 할 수 있도록하는 기능을 제공합니다. 더 작은 함수를 더 큰 함수로 구성하고, 불변 데이터로 작업하고, 부작용을 피한다는 개념을 바탕으로 구축되었습니다.

Ramda는 특히 목록뿐만 아니라 객체, 때로는 문자열에서도 작동합니다. 또한 Folktale 또는 기타 Fantasy-land 구현과 상호 운용되는 방식으로 많은 호출을 위임합니다. 예를 들어, Ramda의 map함수는 의 함수와 유사하게 작동 Array.prototype하므로 R.map(square, [1, 2, 3, 4]); //=> [1, 4, 9, 16]. 그러나 Folktale은지 도를 지정 Maybe하는 Fantasy-land Functor사양을 구현 하기 때문에 Ramda를 map함께 사용할 수도 있습니다 .

R.map(square, Maybe.Just(5)); //=> Maybe.Just(25);
R.map(square, Maybe.Nothing); //=> Maybe.Nothing

함수 라이브러리라는 Ramda의 주장은 함수를 쉽게 구성하고 데이터를 변경하지 않으며 순수한 함수 만 제공하는 데 있습니다. Ramda의 일반적인 용도는 Ramda의 철학 에 대한 기사에서 볼 수 있듯이 더 작은 함수를 구성하여 더 복잡한 기능을 구축하는 것입니다.

// :: [Comment] -> [Number]  
var userRatingForComments = R.pipe(
    R.pluck('username')      // [Comment] -> [String]
    R.map(R.propOf(users)),  // [String] -> [User]
    R.pluck('rating'),       // [User] -> [Number]
);

기타 도서관

사실 더 많은 도서관을 찾았는데 모두 두 가지 범주에 속하는 것 같습니다. 밑줄, lodash는 Ramda와 매우 비슷합니다. Fantasy-land, pointfree-fantasy는 민화와 같습니다.

정말 정확하지 않습니다. 우선 Fantasy-land는 도서관이 다양한 유형에 대해 구현하기로 결정할 수있는 단순한 사양입니다. Folktale은 해당 사양의 많은 구현 중 하나이며 아마도 가장 둥근 사양이며 확실히 가장 성숙한 사양 중 하나입니다. Pointfree-fantasyramda-fantasy 는 다른 입니다.

Underscorelodash 는 Folktale과 같은 것보다 훨씬 적은 응집력으로 많은 함수를 제공하는 그랩 백 라이브러리라는 점에서 표면적으로 Ramda와 비슷합니다. 그리고 특정 기능조차도 종종 Ramda와 겹칩니다. 그러나 더 깊은 수준에서 Ramda는 이러한 라이브러리와 매우 다른 우려를 가지고 있습니다. Ramda의 가장 가까운 사촌은 아마도 FKit , FnucWu.js 와 같은 라이브러리 일 것입니다 .

Bilby 는 자체 범주에 속하며 Ramda에서 제공하는 도구와 같은 여러 도구와 Fantasy-land와 일치하는 일부 유형을 모두 제공합니다. (Bilby의 저자는 Fantasy-land의 원저자이기도합니다.)

당신의 전화

이러한 모든 라이브러리는 기능적 접근 방식과 기능적 헌신 정도가 크게 다르지만 기능적이라고 할 권리가 있습니다.

이러한 라이브러리 중 일부는 실제로 함께 잘 작동합니다. Ramda는 Folktale 또는 기타 Fantasy-land 구현에서 잘 작동합니다. 그들의 우려는 거의 겹치지 않기 때문에 실제로 충돌하지 않지만 Ramda는 상호 운용을 비교적 원활하게 만들기에 충분합니다. 이것은 당신이 선택할 수있는 다른 조합들에 대해서는 사실이 아닐 수 있지만, ES6의 더 간단한 함수 구문은 또한 통합의 고통을 덜어 줄 수 있습니다.

라이브러리의 선택 또는 사용할 라이브러리 스타일 은 프로젝트와 선호도에 따라 달라집니다. 사용할 수있는 좋은 옵션이 많이 있으며 그 수가 증가하고 있으며 그 중 상당수가 크게 개선되고 있습니다. JS로 함수형 프로그래밍을하기에 좋은시기입니다.


1 글쎄요, Folktale이하는 것과 비슷한 일을 하는 사이드 프로젝트, ramda-fantasy 가 있지만, 핵심 라이브러리의 일부는 아닙니다.


답변