Fonksiyonel programlamada neden kalıcı veri yapılarını kullanıyoruz?


22

İşlevsel programlama kalıcı veri yapıları ve değişken nesneler kullanır. Sorum şu ki, burada bu tür veri yapılarına sahip olmak neden önemlidir? Düşük bir seviyede veri yapısı kalıcı değilse ne olacağını anlamak istiyorum. Program daha sık çöküyor mu?


Yanıtlar:


19

Değişmez veri nesneleriyle çalıştığınızda, işlevler onları aynı girdilerle çağırdığınızda, aynı çıktıları üretme özelliğine sahiptir. Bu, hesaplamaların kavramsallaştırılmasını ve doğru yapılmasını kolaylaştırır. Ayrıca test etmelerini kolaylaştırır.

Bu sadece bir başlangıç. Matematiğin uzun süredir fonksiyonlarla çalıştığı için, matematikten ödünç alabileceğimiz ve bunları programlar hakkında titiz bir akıl yürütme için kullanabileceğimiz birçok akıl yürütme tekniği vardır. Benim açımdan en önemli avantaj, işlevsel programlar için tip sistemlerinin iyi gelişmiş olmasıdır. Yani, bir yerde bir hata yaparsanız, bir tür uyuşmazlığı olarak ortaya çıkma olasılığı çok yüksektir. Bu yüzden, yazılan fonksiyonel programlar, zorunlu programlardan çok daha güvenilir olma eğilimindedir.

Değişken veri nesneleriyle çalışırken, aksine, öncelikle bir hesaplama sırasında nesnenin geçtiği birden fazla durumu hatırlama ve yönetme bilişsel yüküne sahipsiniz. Belirli bir adım için ihtiyacınız olan tüm özelliklerin bu noktada karşılandığından emin olarak, işleri doğru sırayla yapmaya özen göstermelisiniz. Hata yapmak kolaydır ve tip sistemleri bu hataları yakalayacak kadar güçlü değildir.

Matematik hiçbir zaman değişken veri nesneleriyle çalışmadı. Dolayısıyla, onlardan ödünç alabileceğimiz hiçbir akıl yürütme tekniği yok. Bilgisayar Bilimi alanında, özellikle Floyd-Hoare Logic'te geliştirilen birçok teknik var . Ancak, bunlar standart matematik tekniklerinden daha ustalaşmak için daha zordur, çoğu öğrenci bunları idare edemez ve bu yüzden nadiren öğretilir.

İki paradigmanın nasıl değiştiğine dair hızlı bir genel bakış için , Programlama Dilleri Prensipleri hakkındaki ders notlarımın ilk birkaç sunumuna bakabilirsiniz .


Bu bana çok mantıklı geliyor. PPT'lerinizi paylaştığınız için teşekkür ederiz. Aynı video kayıtlarını paylaşıyor musunuz?
gpuguy

@gpuguy. Powerpoint'i o kadar kullanmıyorum. Beyaz tahta en sevdiğim ortam. Ancak bildiriler kendileri tarafından okunabilir olmalıdır.
Uday Reddy,

+1 Matematik hiçbir zaman değişken veri nesneleriyle çalışmadı. Ayrıca ders notlarına bağlantı.
Guy Coder,

15

İse daha kolay bu değişken veri yapıları ile çalışmak için daha kalıcı veri yapıları ile doğru bir şekilde çalışma için. Bu, ana avantaj olduğunu söyleyebilirim.

Elbette, teorik olarak konuşursak, kalıcı veri yapıları ile yaptığımız her şeyi değişebilir olanlarla da yapabiliriz ve bunun tersi de geçerlidir. Pek çok durumda, kalıcı veri yapıları, genellikle bunların bir kısmının kopyalanması gerektiğinden, ekstra maliyetlere neden olur. Bu düşünceler, kalıcı bilgisayar yapılarını 30 yıl önce süper bilgisayarların cep telefonunuzdan daha az belleğe sahip olması durumunda daha az çekici hale getirecekti. Ancak günümüzde yazılım üretimindeki ana tıkanıklıklar geliştirme zamanı ve bakım maliyetleri gibi görünmektedir. Bu nedenle, kalkınmada verimlilik için uygulamada bir miktar verimlilik feda etmeye istekliyiz.

Kalıcı veri yapılarını kullanmak neden daha kolaydır? Çünkü insanlar programın farklı bölümleri arasında takma isimleri ve diğer beklenmedik etkileşimleri takip etmede gerçekten kötü . Bunu otomatik olarak düşünürler çünkü iki şeyin çağrıldığı xve ydaha sonra ortak bir şey bulunmadığı için. Her şeyden önce, "sabah yıldızı" ve "akşam yıldızı" nın aynı şey olduğunu anlamak için çaba sarfediyor. Benzer şekilde, bir veri yapısının değişebileceğini unutmak kolaydır, çünkü diğer iş parçacıkları onunla birlikte çalışır, ya da veri yapısını değiştiren bir yöntem olarak adlandırırız, vb. kalıcı veri yapıları.

Kalıcı veri yapılarının başka teknik avantajları da vardır. Bunları optimize etmek genellikle daha kolaydır. Örneğin, kalıcı bir veri yapısını, isterseniz bulutunuzdaki başka bir düğüme kopyalamakta özgürsünüz, eşitleme endişesi yoktur.


o zaman pek çok avantajı olduğunda, neden zorunlu veri yapısını zorunlu dillerde de kullanmıyorsun?
gpuguy

4
Belki yakında "Neden zorunlu diller kullanıyorsunuz?" Diye soracaksınız.
Andrej Bauer

4
Ancak cidden, kalıcı olanlarla değiştirilmesi zor olan veri yapıları vardır; örneğin, dizileri ve matrisleri kullanan sayı sıkıştırma programları, geleneksel veri yapılarında çok daha hızlıdır, çünkü donanım bu tür şeyler için optimize edilmiştir.
Andrej Bauer

1
@gpuguy. Kalıcı veri yapıları, zorunlu ve ne zaman uygulanabilir ve uygunsa, zorunlu dillerde de kullanılabilir ve kullanılmalıdır. Bunları kullanabilmek için, dilin çöp toplama tabanlı bellek yönetimini desteklemesi gerekir. Birçok modern dilde var: Java, C #, Scala, Python, Ruby, Javascript vb.
Uday Reddy

Muhtemelen, büyük bir avantaj, değişken veri yapılarına kıyasla daha soyut bir arayüzdür. Sen edebilirsiniz kaputun (refential bütünlüğü vs cf değişmezlik) kapsamında şeyler değiştirmek ancak gerekmez.
Raphael

2

Başkalarının cevaplarına ekleyen ve matematiksel bir yaklaşımı pekiştiren fonksiyonel programlama, ayrıca İlişkisel Cebir ve Galois Bağlantıları ile hoş bir sinerjiye sahiptir.

Bu, Formal Metodlar alanında oldukça faydalıdır.
Örneğin:

  • Program doğrulamadaki resmi kanıtlar Genişletilmiş Statik Kontrol ile basitleştirilmiştir;
  • İlişkisel Cebir'deki bazı özellikler SAT çözümlerinde Alaşım gibi araçlarla yararlıdır;
  • Galois Connections, bu blogda görüldüğü gibi , bir makaleye atıfta bulunarak , Shin-Cheng Mu ve José Nuno Oliveira tarafından yazılan yazılım özelliklerine hesaplama yaklaşımı sağlar .
  • Galois Connections (ve Functional Programming), Design by Contract modasında kullanılabilir, çünkü Hoare Logic'ten daha genel bir kavramdır.

Örnek

Hoare üçlü {p}P{q}[P]φpφq[P]

  • [P]P
  • φpφq)pq

Bu yaklaşım aynı zamanda, bazı durumlarda kullanışlı olan en zayıf ön koşul ve en güçlü koşul sonrası hesaplamaya izin verir .


2

Düşük bir seviyede veri yapısı kalıcı değilse ne olacağını anlamak istiyorum.

Veri yapısı olarak devasa bir boşluğa ( 2450 bayt hacmine sahip " Mersenne twister " gibi) takma numara üreticisine bakalım . Rastgele bir sayıyı bir kereden fazla kullanmak istemiyoruz, bu yüzden bunu değişmez kalıcı bir veri yapısı olarak uygulamak için çok az neden var gibi görünüyor. Şimdi aşağıdaki kodda neyin yanlış gidebileceğini kendimize soralım:

mt_gen = CreateMersenneTwisterPRNGen(seed)
integral = MonteCarloIntegral_Bulk(mt_gen) + MonteCarloIntegral_Boundary(mt_gen)

Çoğu programlama dilleri sırayı belirtmeyen MonteCarloIntegral_Bulkve MonteCarloIntegral_Boundarydeğerlendirilecektir. Her ikisi de değişken bir mt_gen'e bir argüman olarak gönderme yaparsa, bu hesaplamanın sonucu platforma bağlı olabilir. Daha da kötüsü, sonucun farklı işlemler arasında hiçbir zaman tekrarlanamayacağı platformlar olabilir.

Birisi mt_gen için etkin bir değişken veri yapısı tasarlayabilir, öyle ki, herhangi bir uygulamanın harmanlanması "doğru" bir sonuç verir MonteCarloIntegral_Bulkve MonteCarloIntegral_Boundaryverir, ancak farklı bir harmanlama genel olarak farklı bir "doğru" sonuç verir. Bu tekrar üretilemezlik karşılık gelen işlevi "saflaştırır" yapar ve ayrıca başka bazı problemlere de yol açar.

Sabit olmayan bir sıralı yürütme emri uygulanarak tekrarlanamazlıktan kaçınılabilir. Ancak bu durumda kod, herhangi bir zamanda yalnızca mt_gen'e tek bir referansın ulaşabileceği şekilde düzenlenebilir. Yazılı bir işlevsel programlama dilinde, bu kısıtlamayı zorlamak için benzersizlik türleri kullanılabilir, böylece saf işlevsel programlama dilleri bağlamında da güvenli değiştirilebilir güncellemeler sağlanır. Bütün bunlar kulağa hoş ve zekice gelebilir, ancak en azından teoride Monte Carlo simülasyonları utanç verici bir şekilde paralelve bizim "çözümümüz" sadece bu mülkü mahvetti. Bu sadece teorik bir problem değil, aynı zamanda gerçek bir pratik meseledir. Bununla birlikte, sözde rasgele sayı üretecimizi ve ürettiği rasgele sayıların sırasını değiştirmemiz (sunduğu işlevsellik) ve hiçbir programlama dili bizim için otomatik olarak yapamaz. (Tabii ki zaten gerekli işlevselliği sunan farklı bir sözde rasgele sayı kütüphanesi kullanabiliriz.)

Düşük seviyede, yürütme sırası sıralı ve sabit değilse, değişken veri yapıları kolayca tekrarlanamazlığa (ve dolayısıyla safsızlığa) yol açar. Bu sorunların üstesinden gelmek için tipik bir zorunlu strateji, değişebilir veri yapılarının değiştiği sabit yürütme sırasına sahip sıralı aşamalara ve tüm paylaşılabilir değişken veri yapılarının sabit kaldığı, keyfi yürütme sırasına sahip paralel aşamalara sahip olmaktır.


Andrej Bauer değişken veri yapıları için takma israf sorununu gündeme getirdi. İlginçtir ki, Fortran ve C gibi farklı emir dilleri, işlev argümanlarının izin verilen takma isimleri konusunda farklı varsayımlara sahiptir ve çoğu programcı, dillerinin bir takma modeline sahip olduğunun farkında değildir.

Ölçülebilirlik ve değer anlambilimi biraz abartılabilir. Daha da önemlisi, programlama dilinizin tip sistemi ve mantıksal çerçevesinin (soyut makine modeli, takma model, eşzamanlılık modeli veya bellek yönetimi modeli gibi), "verimli" verilerle "güvenle" çalışması için yeterli desteği sağlamasıdır. yapıları. "Hareketli anlambilim" in C ++ 11'e getirilmesi, teorik açıdan saflık ve "güvenlik" anlamında dev bir adım gibi görünebilir, ancak pratikte bunun tam tersi de geçerlidir. Tip sistemi ve dilin mantıksal çerçevesi, yeni anlambilimle ilişkili tehlikenin büyük kısımlarını kaldırmak için genişletildi. (Pürüzlü kenarlar kalsa bile, bu "daha iyi" bir durumla geliştirilemeyeceği anlamına gelmez


Uday Reddy, matematiğin hiçbir zaman değişken veri nesneleriyle çalışmadığı ve fonksiyonel programlar için tip sistemlerinin değişmez veri nesneleri için iyi bir şekilde geliştirildiği sorununu gündeme getirdi. Bu bana Jean-Yves Girard'ın matematiğin doğrusal mantığı motive etmeye çalıştığında değişken nesnelerle çalışmak için kullanılmadığını açıklamasını hatırlattı.

Biri, "etkin" değişken olmayan kalıcı veri yapılarıyla "güvenli bir şekilde" çalışmayı mümkün kılmak üzere, işlevsel programlama dillerinin tip sisteminin ve mantıksal çerçevesinin nasıl genişletilebileceğini sorabilir. Buradaki bir problem, klasik mantık ve boolean cebirlerinin değişken veri yapılarıyla çalışmak için en iyi mantıksal çerçeve olmayabilir. Belki de doğrusal mantık ve değişmeli monoidler bu görev için daha uygun olabilir mi? Belki de fonksiyonel programlama dilleri için Philip Wadler'in lineer mantık üzerine tür sistemi olarak söylediklerini okumalıyım ? Fakat doğrusal mantık bu problemi çözemezse bile, bu, işlevsel bir programlama dilinin tip sisteminin ve mantıksal çerçevesinin "güvenli" ve "verimli" olmasını sağlayacak şekilde genişletilemeyeceği anlamına gelmez.


@DW Muhtemelen bu cevabın tek başına bir cevap olmadığı konusunda haklısınız. Halen Uday Reddy ve Andrej Bauer tarafından verilen cevaplarda dile getirilen bazı noktaları genişletmektedir. Tek başıma durması ve doğrudan "Ben düşük bir seviyede anlamak istiyorum, veri yapısı kalıcı değilse ne olur?" Diye cevaplayabileceğimi düşünüyorum. sorunun bir parçası. Bir veri yapısı olarak devasa bir durum alanı (2450 bayt eyaleti ile "Mersenne twister" gibi) olan sahte bir sayı üretecine bakar ve yanlış gidebilecek şeyleri açıklardım.
Thomas Klimpel

@DW Bu sorunun cevabından herhangi birinin soruyu gerçekten cevapladığını sanmıyorum. Özellikle, kalıcı veri yapılarının gerçekte ne olduğu (değişmez olmaktan başka) ve nasıl uygulandıkları hakkında çok fazla bir şey yoktur.
Guildenstern
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.