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


96

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

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

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

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

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

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

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


1
사용자의 요구와 스타일에 맞는 잘 설명되어 있습니다 무엇을 사용
charlietfl

1
특히 JS에서 "기능적 프로그래밍"에 대해 일반적으로 의도 된 세 가지 의미가 있음을 발견했습니다. 1. 배열과 같은 집합에 고차 순수 함수 사용, 예 [1,2,3].map(fnSquare).reduce(fnSum). 2. 대체로 학술적인 "look ma no var "Y-combinator-esque 구조. 사용 3. Function.prototype같은 다른 기능의 동작을 수정하기는var isMissingID=fnContains.partial("id").negate();
dandavis

10
Ramda 작성자 : Ramda는 상당히 낮은 수준의 유틸리티 라이브러리입니다. 특히 함수를 구성하여 작업하는 JS에서 특정 기능 스타일을 더 단순하게 만들기위한 것입니다. Ramda는 Folktale과 같은 구현을 포함하여 FantasyLand 사양과 잘 작동합니다. 이러한 라이브러리는 다소 다른 목적으로 설계되었습니다. 그들은 일반적인 추상 데이터 유형을 인식하고 Monoids, Functors 및 Monads와 같은 것에 대한 일관된 액세스를 허용하기 위해 구축되었습니다. Ramda는 그들과 함께 일하고 일부를 만드는 부수적 인 프로젝트를 가지고 있지만, 당신이 말했듯이 그것은 매우 다른 초점입니다.
Scott Sauyet 2015 년


2
Sanctuary도 살펴보세요 -github.com/plaid/sanctuary 이것은 ramda 를 기반으로하지만 판타지 랜드 유형도 다룹니다.
arcseldon

답변:


180

기능적 특징

함수형 프로그래밍 또는 함수형 라이브러리를 정의하는 것에 대한 명확한 경계는 없습니다. 기능 언어의 일부 기능은 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 가 있지만, 핵심 라이브러리의 일부는 아닙니다.


1
ES6가 Yield의 도입으로 지연 평가 기능을 가지고 있다고 말하는 것이 공정할까요? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Marcel Lamothe

8
아니요 . 또는에 yield의해 수행되는 일종의 지연 목록 처리를 더 쉽게 수행 할 수 있습니다. 그러나 언어 수준의 게으름에는 도움이되지 않습니다. JS에서의 처음 값 추가 및 someFunc에 파라미터로서 발생 후 용품. Haskell의 동등한 것은 그렇게하지 않습니다. 호출 된 함수가 해당 값을 사용하지 않으면 더하기를 수행하지 않습니다. 결국 그것을 사용한다면, 그 결과가 필요할 때까지 계산 될 표현식으로 간주됩니다. 강제로 수행 할 작업을 수행하지 않으면 (예 : IO) 실제로 계산을 수행하지 않습니다. Lazylz.jssomeFunc(a + b)ab
Scott Sauyet 2015

@ScottSauyet 아마도 ES6 생성기를 통해 어떤 형태로든 "지연 평가"를 사용할 수 있다고 주장 할 수 있습니다. 많은 JS 프레임 워크에는 "게으름"특성이 있습니다-RxJs, ImmutableJs 등.
arcseldon

8
이 답변은 DrBoolean 책의 장 또는 섹션이어야합니다. :)
Seth

1
Ramda 문서는 JS가 목록, 조밀 한 배열에 제공하는 가장 가까운 것을 약어로 "목록"을 사용하는 경향이 있습니다. 이것들은 순수한 목록과는 다른 성능 특성을 가지고 있으며 물론 약간 다른 API이지만 거의 동일한 목적으로 사용할 수 있으며 Ramda에서 사용할 수 있는 가장 가까운 네이티브 (그러나 github.com/funkia/list 참조 ) 유형입니다. 개념적으로 순수 목록 작업을 원하는 API. 나는 C 스타일 배열이 JS 배열보다 더 표준 적이 지 않고 수학적 배열에 실제로 가깝지 않기 때문에 사실이 아닌 배열이 포인트라고 주장 할 것입니다. 그러나 그것은 사소한 포인트입니다.
Scott Sauyet
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.