İşlevsel Dillerde Asenkron Programlama


31

Ben çoğunlukla bir C / C ++ programcısıyım, bu da deneyimimin çoğunun usule dayalı ve nesne yönelimli paradigmalar ile yapıldığı anlamına geliyor. Bununla birlikte, birçok C ++ programcısının farkında olduğu gibi, C ++ yıllar içinde vurgusuyla fonksiyonel esque tarzına kaymış, sonunda C ++ 0x'deki lambda ve kapakların eklenmesiyle sonuçlanmıştır.

Ne olursa olsun, C ++ kullanarak işlevsel bir tarzda kodlama konusunda önemli bir deneyime sahip olsam da, Lisp, Haskell, vb. Gibi gerçek işlevsel dillerle ilgili çok az deneyimim var.

Son zamanlarda bu dilleri incelemeye başladım, çünkü tamamen işlevsel dillerde "yan etki yok" fikri, özellikle eşzamanlılık ve dağıtılmış hesaplama konusundaki uygulamaları konusunda beni her zaman etkiledi.

Ancak, bir C ++ arkaplanından gelince, bu "yan etki yok" felsefesinin asenkron programlama ile nasıl çalıştığı konusunda kafam karıştı. Eşzamansız programlama ile, eşzamanlı olmayan olayları (programın akışı dışında) işlemek için kullanıcı tarafından sağlanan olay işleyicilerini gönderen herhangi bir çerçeve / API / kodlama stilini kastediyorum. Bu, Boost.ASIO veya hatta sadece düz eski C gibi eşzamansız olmayan kütüphaneleri içerir sinyal işleyicileri veya Java GUI olay işleyicileri.

Bunların hepsinde ortak olan tek şey, asenkron programlamanın doğasının , programın ana akışının asenkron bir olay işleyicisinin başlatıldığının farkına varması için yan etkilerin (durum) yaratılmasını gerektiriyor görünmesidir . Tipik olarak, Boost.ASIO gibi bir çerçevede, bir olay işleyicisi bir nesnenin durumunu değiştirir , böylece olayın etkisi olay işleyicisi işlevinin ömrünün ötesine yayılır. Gerçekten, bir olay işleyicisi başka ne yapabilir? Çağrı noktasına bir değer döndüremez, çünkü çağrı noktası yoktur. Olay işleyicisi, programın ana akışının bir parçası değildir, bu nedenle asıl program üzerinde herhangi bir etkiye sahip olabilmesinin tek yolu bir durumu (veya başka longjmpbir yürütme noktasına) değiştirmektir.

Öyle görünüyor ki, asenkron programlama, asenkron olarak yan etkiler üretmekle ilgilidir. Bu tamamen işlevsel programlamanın amaçlarına aykırı görünüyor. Bu iki paradigma fonksiyonel uygulamalarda (pratikte) nasıl uzlaştırıldı?


3
Vay be, ben tam da böyle bir soru yazmak üzereydim ve bunu nasıl koyacağımı bilmiyordum ve sonra bunu önerilerde gördüm!
Amogh Talpallikar

Yanıtlar:


11

İşlevsel programlama anlayışınızın biraz fazla aşırı olduğunu düşünmem dışında, tüm mantığınız sağlam. Gerçek dünyada işlevsel programlama, tıpkı nesne yönelimli veya zorunlu programlama gibi zihniyet ve soruna nasıl yaklaşacağınızla ilgilidir. Uygulama durumunu değiştirirken yine de işlevsel programlama ruhunda programlar yazabilirsiniz.

Aslında, uygulama durumunu değiştirmek için gerçekte bir şey yapmalısınız . Haskell adamları size programlarının 'saf' olduğunu söyleyecektir, çünkü bütün devlet değişikliklerini bir monata sardılar. Ancak, programları hala dış dünyayla etkileşime giriyor. (Aksi halde konu nedir!)

İşlevsel programlama, anlam ifade ettiğinde "hiçbir yan etkisi" vurgulamamaktadır. Ancak, gerçek dünya programlaması yapmak için, dediğiniz gibi, dünyanın durumunu değiştirmeniz gerekir. (Örneğin, olaylara yanıt verme, diske yazma vb.)

Fonksiyonel dillerde asenkron programlama hakkında daha fazla bilgi için, F # 'ın Asenkron İş Akışı programlama modeline bakmanızı şiddetle tavsiye ediyorum . Bir kütüphane içindeki evre geçişinin tüm dağınık ayrıntılarını gizlerken işlevsel programlar yazmanıza olanak sağlar. (Haskell tarzı monadlara çok benzer şekilde.)

Eğer ipliğin 'gövdesi' basitçe bir değer hesaplarsa, o zaman birden fazla ipliğin ortaya çıkması ve değerlerin paralel olarak hesaplanması hala işlevsel paradigma içindedir.


5
Ayrıca: Erlang'a bakmak yardımcı olur. Dili (tüm veriler değişmez), çok basit, saf, ve olan tüm asenkron işlem hakkında.
9000

Temel olarak, fonksiyonel yaklaşımın yararlarını ve durumun yalnızca önemli olduğu durumlarda değişen durumu anladıktan sonra, Java gibi bir şey söyleseniz bile, durumu ne zaman değiştireceğinizi ve böyle şeyleri nasıl kontrol altında tutacağınızı bildiğinizden emin olun.
Amogh Talpallikar

Anlaşmazlık - programın 'saf' işlevlerden oluşması, dış dünya ile yinelenmediği anlamına gelmez, bir programdaki her bir fonksiyonun bir argüman kümesi için her bir fonksiyonun daima aynı sonucu vereceği anlamına gelir. (saflık) büyük bir mesele, çünkü pratik açıdan - böyle bir program daha az sıkıcı, daha 'test edilebilir' olacaktır, fonksiyonların başarılı bir şekilde yürütülmesi matematiksel olarak kanıtlanabilirdi.
Gill Bates,

8

Bu büyüleyici bir soru. En ilgimi çeken, benim görüşüme göre, Clojure'de kabul edilen ve bu videoda açıklanan yaklaşım:

http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey

Temel olarak önerilen "çözüm" aşağıdaki gibidir:

  • Kodunuzun çoğunu, değişken veri yapılarına sahip ve yan etkisi olmayan klasik "saf" işlevler olarak yazıyorsunuz
  • Yan etkiler, yazılım işlemsel bellek kurallarına bağlı olarak değişimi kontrol eden yönetilen referanslar kullanılarak izole edilir (yani değişken durumdaki tüm güncellemeleriniz uygun bir izole edilmiş işlem içinde gerçekleşir)
  • Dünyanın bu görüşüne bakarsanız, güncellemenin saf bir işlev olduğu, değişken durumlu bir işlemsel güncellemenin tetikleyicileri olarak eşzamansız "olayları" görebilirsiniz.

Muhtemelen fikri, diğerlerinin yaptığı gibi net bir şekilde ifade etmedim, ancak umarım bu genel bir fikir verir - temelde saf işlevsel programlama ve asenkron olayı işleme arasında "köprü" sağlamak için eş zamanlı bir STM sistemi kullanıyordur.


6

Bir not: işlevsel bir dil saf, ancak çalışma zamanı değil.

Örneğin, Haskell çalışma süreleri, hepsi saf olmayan sıraları, iplik çoğullama, çöp toplama vb.

İyi bir örnek tembelliktir. Haskell tembel değerlendirmeyi destekler (bu varsayılan, aslında). Bir işlem hazırlayarak tembel bir değer yaratırsınız, daha sonra bu değerin birden çok kopyasını oluşturabilirsiniz ve bu gerekli olmadıkça hala "tembeldir". Sonuç gerektiğinde veya çalışma zamanı bir süre bulursa, değer gerçekte hesaplanır ve tembel nesnenin durumu, sonucu elde etmek için artık hesaplamanın (bir kez daha) yapılması gerekmediğini yansıtmak üzere değişir. Şimdi tüm referanslar üzerinden ulaşılabilir durumda olduğundan, saf bir dil olmasına rağmen nesnenin durumu değişti.


2

Bu "yan etki yok" felsefesinin asenkron programlama ile nasıl çalıştığı konusunda kafam karıştı. Asenkron programlama ile demek istediğim ...

Öyleyse konu bu olurdu.

Ses, hiçbir yan etki stili, duruma bağlı çerçevelerle uyumsuzdur. Yeni bir çerçeve bulun.

Python'un WSGI standardı, örneğin hiçbir yan etki uygulaması oluşturmamıza izin vermiyor.

Buradaki fikir, çeşitli “durum değişikliklerinin”, kademeli olarak oluşturulabilecek değerler ortamından yansıdığıdır. Her talep bir dönüşüm hattıdır.


"hiçbir yan etki uygulaması kurulmasına izin verilmez" bence içinde bir yerde eksik bir kelime var.
Christopher Mahan

1

C öğrendikten sonra Borland C ++ 'dan enkapsülasyonu öğrendikten sonra, Borland C ++ jenerikliği sağlayan şablonlardan yoksun olduğunda, nesne yönelimi paradigması beni rahatsız etti. Hesaplamak için biraz daha doğal bir yol borularla filtreleme verisi gibiydi. Dışa doğru olan akım, yan etki olarak düşünülmek yerine içe aktarılabilir girdi akışından ayrı ve bağımsız bir kimliğe sahipti, yani her veri kaynağı (veya filtre) diğerlerinden özerkti. Tuşa basma (örnek olay), eşzamansız kullanıcı girişi kombinasyonlarını kullanılabilir tuş kodlarıyla sınırlandırdı. İşlevler, giriş parametresi argümanları üzerinde çalışır ve sınıf tarafından kapsanan durum, işlevlerin herhangi bir rasgele işlevden kötüye kullanılmasını önleyen sınırlı bağlamlara karşı tedbirli olmanın yanı sıra, küçük işlev alt grupları arasında tekrarlı argümanların açıkça iletilmesinden kaçınmak için kısa yoldur.

Belirli paradigmaya katı bir şekilde yapıştırmak, örneğin sızdıran soyutlamalarla başa çıkmada sakıncaya neden olur. JRE, DirectX, .net gibi ticari çalışma süreleri her şeyden önce hedef nesneye yönelik destekçileri hedef alır. Rahatsızlığı sınırlamak için, diller ya Haskell gibi bilimsel olarak sofistike monadları tercih ediyor ya da F # gibi esnek çoklu paradigma desteğini alıyor. Kapsülleme bazı çoklu kalıtım kullanım durumundan yararlı olmadıkça, çoklu paradigma yaklaşımı bazı, bazen karmaşık, paradigmaya özgü programlama modellerine göre daha üstün bir alternatif olabilir.

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.