halk masalı ve ramda neden bu kadar farklı?


97

DrBoolean'ın kitabını okuyarak javascript FP öğreniyorum .

İşlevsel programlama kitaplığını araştırdım. Ramda ve Folktale'yi buldum. Her ikisi de işlevsel programlama kitaplığı olduğunu iddia ediyor.

Ama çok farklılar:

  • Ramda , liste ile uğraşmak için yardımcı fonksiyonlar içeriyor gibi görünüyor: eşleme, azaltma, filtreleme ve saf fonksiyonlar: curry, compose. Monad, functor ile başa çıkacak hiçbir şey içermiyor.

  • Folktale, ancak liste veya işlevler için herhangi bir yardımcı program içermez. Javascript'teki bazı cebirsel yapıları monad gibi uyguluyor gibi görünüyor: Belki, Görev ...

Aslında daha fazla kütüphane buldum, hepsi iki kategoriye ayrılıyor gibi görünüyor. Alt çizgi ve lodash, Ramda gibidir. Fantezi diyarı, noktasız fantazi halk masalı gibidir.

Bu çok farklı kitaplıkların her ikisi de işlevsel olarak adlandırılabilir mi ve öyleyse, her birini işlevsel bir kitaplık yapan nedir?


1
ihtiyaçlarınıza ve tarzınıza uyan ve iyi belgelenmiş olanı kullanın
charlietfl

1
"İşlevsel programlama" için, özellikle JS'de gerçekten üç ortak anlamın olduğunu buldum. 1. diziler gibi setlerinde yüksek mertebeden saf işlevleri kullanarak., Ex [1,2,3].map(fnSquare).reduce(fnSum)2. büyük oranda akademik "bir görünüm ma hiçbir var " Y-combinator-vari yapılar. 3. Function.prototypediğer işlevlerin davranışını değiştirmek için kullanma , örneğinvar isMissingID=fnContains.partial("id").negate();
dandavis

11
Burada bir Ramda yazarı: Ramda oldukça düşük seviyeli bir yardımcı program kitaplığıdır. JS'de belirli bir işlevsel stili daha basit hale getirmeyi, özellikle de işlevleri oluşturarak çalışmayı amaçlamaktadır. Ramda, Folktale gibi uygulamaları da dahil olmak üzere FantasyLand spesifikasyonuyla iyi çalışır. Bu kütüphaneler biraz farklı bir amaç için tasarlandı. Ortak soyut veri türlerini tanımak ve bunlara tutarlı erişim sağlamak etrafında inşa edilmiştir: Monoidler, Functors ve Monadlar gibi şeyler. Ramda onlarla birlikte çalışacak ve bazılarını yaratmak için bir yan projesi var, ama sizin de dediğiniz gibi, bu çok farklı bir odak noktası.
Scott Sauyet

1
@KeithNicholas: Evet, Gitter Odası var
Scott Sauyet

2
Sığınağa da bir göz atın - github.com/plaid/sanctuary Bu ramda'ya dayalıdır, ancak aynı zamanda fantezi-arazi türlerini de kapsar.
arcseldon

Yanıtlar:


182

Fonksiyonel Özellikler

İşlevsel programlamayı veya işlevsel bir kitaplığı neyin tanımladığına dair net bir sınır yoktur. İşlevsel dillerin bazı özellikleri Javascript'te yerleşiktir:

  • Birinci sınıf, üst düzey işlevler
  • Lambdas / Anonim işlevler, kapatmalarla

Diğerlerini Javascript'te biraz dikkatlice başarmak mümkündür:

  • Değişmezlik
  • İfade Şeffaflığı

Yine de diğerleri ES6'nın bir parçasıdır ve şu anda kısmen veya tamamen mevcuttur:

  • Kompakt, hatta kısa, işlevler
  • Kuyruk arama optimizasyonu yoluyla performans özyinelemesi

Ve Javascript'in normal erişiminin gerçekten ötesinde olan pek çok başkası var:

  • Desen eşleştirme
  • Tembel değerlendirme
  • Homoikonisite

Bir kütüphane, o halde, desteklemeye çalıştığı özelliklerin türünü seçebilir ve makul bir şekilde "işlevsel" olarak adlandırılabilir.

Fantezi arazi özellikleri

Fantasy-land , matematiksel Kategori Teorisi ve Soyut Cebirden fonksiyonel programlamaya, Monoid , Functor ve Monad gibi türlere taşınan bir dizi standart tür için bir belirtimdir . Bu türler oldukça soyuttur ve muhtemelen daha tanıdık kavramları genişletir. Funktorlar Örneğin, olabilir kaplardır mapbir fonksiyonu bir dizi olabilir şekilde fazla ped mapkullanarak üzerinde ped Array.prototype.map.

Halk Hikayesi

Folktale , Fantezi arazi şartnamesinin çeşitli kısımlarını ve yardımcı yardımcı program işlevlerinin küçük bir koleksiyonunu uygulayan bir tür koleksiyonudur. Bu türler Belki , Ya , Görev (başka bir yerde bir Gelecek olarak adlandırılana ve bir Sözün daha yasal bir kuzeni olana çok benzer) ve Doğrulama gibi şeylerdir.

Folktale, Fantazi arazi şartnamesinin belki de en iyi bilinen uygulamasıdır ve saygı duyulur. Ancak kesin veya varsayılan uygulama diye bir şey yoktur; fantasy-land yalnızca soyut türleri belirtir ve tabii ki bir uygulama bu tür somut türleri yaratmalıdır. Folktale'in işlevsel bir kütüphane olma iddiası açıktır: tipik olarak işlevsel programlama dillerinde bulunan ve işlevsel bir şekilde programlamayı önemli ölçüde kolaylaştıran veri türlerini sağlar.

Folktale belgelerinden alınan bu örnek ( not : belgelerin son sürümlerinde yoktur), nasıl kullanılabileceğini gösterir:

// 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

Ramda (sorumluluk reddi: Ben yazarlardan biriyim) çok farklı bir kitaplık türüdür. Size yeni tipler sağlamaz. 1 Bunun yerine, mevcut türler üzerinde çalışmayı kolaylaştıran işlevler sağlar. Daha küçük işlevleri daha büyük işlevlere dönüştürme, değişmez verilerle çalışma, yan etkilerden kaçınma kavramları üzerine inşa edilmiştir.

Ramda özellikle listeler üzerinde çalışır, aynı zamanda nesneler ve bazen de Dizeler üzerinde çalışır. Ayrıca çağrılarının çoğunu, Folktale veya diğer Fantasy-land uygulamalarıyla birlikte çalışacak şekilde yetkilendirir. Örneğin, Ramda en mapişlevi, üzerindeki birine benzer çalışırken Array.prototypeyüzden R.map(square, [1, 2, 3, 4]); //=> [1, 4, 9, 16]. Ancak Folktale, haritayı da belirten MaybeFantasy-land Functorspesifikasyonunu uyguladığından, Ramda'nın özelliklerini de kullanabilirsiniz map:

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

Ramda'nın işlevsel bir kütüphane olma iddiası, işlevler oluşturmayı kolaylaştırmada, verilerinizi asla değiştirmemede ve yalnızca saf işlevler sunmada yatar. Ramda'nın felsefesi üzerine bir makalede görüldüğü gibi, Ramda'nın tipik kullanımı, daha küçük işlevler oluşturarak daha karmaşık işlevler oluşturmak olacaktır.

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

Diğer Kitaplıklar

Aslında daha fazla kütüphane buldum, hepsi iki kategoriye ayrılıyor gibi görünüyor. alt çizgi, lodash Ramda'ya çok benziyor. Fantezi diyarı, noktasız fantazi halk masalı gibidir.

Bu gerçekten doğru değil. Her şeyden önce, Fantasy-land, kütüphanelerin çeşitli türler için uygulamaya karar verebilecekleri bir şartnamedir. Folktale, bu spesifikasyonun birçok uygulamasından biridir, muhtemelen en iyi olanı, kesinlikle en olgun olanlardan biridir. Noktasız-fantezi ve ramda-fantezi diğerleridir ve çok daha fazlası vardır .

Alt çizgi ve lodash , Folktale gibi bir şeye göre çok daha az uyum ile çok sayıda işlev sağlayan, kapma-torba kitaplıkları olmaları bakımından yüzeysel olarak Ramda'ya benzerler. Ve hatta belirli işlevler bile genellikle Ramda'nınkilerle örtüşüyor. Ancak daha derin bir düzeyde, Ramda'nın bu kütüphanelerden çok farklı endişeleri var. Ramda'nın en yakın kuzenleri muhtemelen FKit , Fnuc ve Wu.js gibi kütüphanelerdir .

Bilby , hem Ramda tarafından sağlananlar gibi bir dizi araç hem de Fantasy-land ile tutarlı bazı türler sağlayan kendi kategorisinde yer almaktadır. (Bilby'nin yazarı, Fantasy-land'ın da orijinal yazarıdır.)

Çağrınız

İşlevsel yaklaşım ve işlevsel bağlılık derecesi açısından büyük farklılıklar gösterse de, tüm bu kütüphaneler işlevsel olarak adlandırılma hakkına sahiptir.

Bu kütüphanelerden bazıları aslında birlikte iyi çalışıyor. Ramda, Folktale veya diğer Fantasy-land uygulamalarıyla iyi çalışmalıdır. Endişeleri çok az örtüştüğü için, gerçekten çatışmıyorlar, ancak Ramda, birlikte çalışmayı nispeten pürüzsüz hale getirmek için yeterli yapıyor. Bu, seçebileceğiniz diğer kombinasyonların bazıları için muhtemelen daha az doğrudur, ancak ES6'nın daha basit işlev sözdizimi, entegrasyonun bir kısmını da ortadan kaldırabilir.

Kitaplık seçimi ve hatta kullanılacak kitaplık stili , projenize ve tercihlerinize bağlı olacaktır. Kullanılabilir birçok iyi seçenek var ve sayılar artıyor ve çoğu büyük ölçüde gelişiyor. JS'de fonksiyonel programlama yapmanın tam zamanı.


1 Folktale'in yaptığına benzer bir şey yapan bir yan proje, ramda-fantazi var, ama bu çekirdek kütüphanenin bir parçası değil.


1
Yield'in tanıtılmasıyla birlikte ES6'nın tembel değerlendirme yeteneğine sahip olduğunu söylemek doğru olur mu? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Marcel Lamothe

8
Hayır . Veya yieldtarafından yapılan tembel liste işlemlerini kolaylaştırır . Ancak dil seviyesindeki tembelliğe yardımcı olmuyor. JS'de ilk önce değerlerini ekler ve sonra sonucu bir parametre olarak someFunc'a sağlar. Haskell'deki eşdeğeri bunu yapmaz. Çağrılan işlev bu değeri asla kullanmazsa, toplama işlemini asla gerçekleştirmez. Sonunda kullanırsa, sonuca ihtiyaç duyulana kadar hesaplanması gereken bir ifade olarak kabul edilir. Eğer onu zorlayacak bir şeyi asla yapmazsanız (IO gibi), aslında hesaplamayı asla gerçekleştirmez. Lazylz.jssomeFunc(a + b)ab
Scott Sauyet

@ScottSauyet, belki de "tembel değerlendirme" nin bazı biçimlerde ES6 üreteçleri aracılığıyla yapılabileceğini iddia edebilirsiniz - JS çerçevelerinin birçoğunun "tembellik" özellikleri vardır - RxJ'ler, ImmutableJ'ler vb.
arcseldon

9
Bu cevap DrBoolean'ın kitabındaki bir bölüm veya bölüm olmalıdır. :)
Seth

1
Ramda dokümantasyonu, JS'nin listelere, yoğun dizilere sunduğu en yakın şey için bir kısaltma olarak "list" kullanma eğilimindedir. Bunlar, saf listelerden farklı performans özelliklerine ve elbette biraz farklı bir API'ye sahiptir, ancak hemen hemen aynı amaçlar için kullanılabilirler ve Ramda'nın kullanabileceği en yakın yerel ( github.com/funkia/list'e bakın ) türleridir. Kavramsal olarak saf listelerle çalışmak isteyen API. C-tarzı diziler JS dizilerinden daha kanonik olmadığından ve hiçbiri matematiksel dizilere gerçekten yakın olmadığından, doğru olmayan dizileri işaret ediyorum, ama bu küçük bir nokta.
Scott Sauyet
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.