Birinci sınıf devamlar modern nesne yönelimli programlama dillerinde faydalı mıdır?


10

Sürdürmeler, işlevsel programlama dillerinde (örn Cont. Haskell'deki monad) son derece kullanışlıdır, çünkü zorunluluk tarzı kod için basit ve düzenli bir gösterime izin verir. Bazı eski zorunlu dillerde de yararlıdırlar, çünkü eksik dil özelliklerini uygulamak için kullanılabilirler (örn. İstisnalar, koroutinler, yeşil iplikler). Ancak, bu özellikler için yerleşik destekli modern bir nesne yönelimli dil için, birinci sınıf süreklilikler için destek eklemek için hangi argümanlar olurdu (daha modern sınırlandırılmış stil resetve / shiftveya şema benzeri call-with-current-continuation)?

Performans ve uygulamanın karmaşıklığı dışında destek eklemeye yönelik argümanlar var mı?

Yanıtlar:


15

Eric Lippert'in buna cevap vermesine izin verelim:

Bu noktada açık olan soru şudur: CPS bu kadar harika ise neden her zaman kullanmıyoruz? Neden çoğu profesyonel geliştirici bunu hiç duymamış ya da sahip olanlar bunu sadece çılgın Şema programcılarının yaptığı bir şey olarak düşünmüşlerdir?

Her şeyden önce, altyordamlar, döngüler, deneme-yakala-son olarak düşünmeye alışkın olan çoğu insan için kontrol akışında bu şekilde kullanılan delegelerin akıl yürütmesi basitçe zordur. Şu anda CS442'den CPS ile ilgili notlarımı gözden geçiriyorum ve 1995'te bir profQUOTE yazdığımı görüyorum: “Sürekliliklerle kafanızda durup kendinizi dışarı çekmeniz gerekiyor”. Profesör Duggan (*) bunu söylerken kesinlikle doğruydu. Birkaç gün önce C # ifadesi M (B ()? C (): D ()) 'nin küçük CPS dönüşüm örneğimizin dört lambda içerdiğini hatırlayın. Herkes üst düzey işlevleri kullanan kodu okumakta iyi değildir. Büyük bir bilişsel yük getirir.

Ayrıca: belirli bir dilde belirli kontrol akışı ifadeleri oluşturmanın en güzel yanlarından biri, kodunuzun mekanizmaları gizlerken kontrol akışının anlamını açıkça ifade etmesidir - çağrı yığınları ve dönüş adresleri ve istisna işleyici listeleri ve korunan bölgeler ve bunun gibi. Devamlar kontrol akış mekanizmalarını kodun yapısında açık hale getirir. Tüm bu vurgu mekanizması korkutur anlam kodunun.

Bir sonraki makalede , eşzamansızlığın ve sürekliliklerin birbirine tam olarak nasıl eşdeğer olduğunu açıklıyor ve basit, (ancak engelleme) bir eşzamanlı ağ işlemi alıp, eşzamansız bir tarzda yeniden yazarak, tüm gizli doğru olması için örtülmesi gereken gotchas. Bu bir dönüşür masif kod karmaşa. Sonundaki özeti:

Kutsal iyilik, ne kadar iğrenç bir karmaşa yarattık. Gördüğünüz en godawful spagetti'nin iki düzine kodunu iki düzine genişlettik. Tabii ki hala derlenmiyor çünkü etiketler kapsamda değil ve kesin bir atama hatası var. Bu sorunları çözmek için kodu tekrar yazmamız gerekiyor.

CPS'in artıları ve eksileri hakkında ne söylediğimi hatırlıyor musunuz?

  • PRO: Basit parçalardan keyfi olarak karmaşık ve ilginç kontrol akışları oluşturulabilir - kontrol edin.
  • CON: Kontrol akışının sürekliliklerle yeniden ilişkilendirilmesi zor ve akıl yürütmesi zor.
  • CON: Kontrol akış mekanizmalarını temsil eden kod, kod kontrolünün anlamını tamamen aşar.
  • CON: Sıradan kod kontrol akışının CPS'ye dönüştürülmesi, derleyicilerin iyi olduğu ve neredeyse hiç kimsenin kontrol etmediği bir şeydir.

Bu bazı entelektüel bir egzersiz değildir. Gerçek insanlar, eşzamansızlık ile uğraşırken her zaman yukarıdakine ahlaki olarak kod yazıyorlar. Ve ironik bir şekilde, işlemciler daha hızlı ve daha ucuz hale gelse bile, zamanımızı giderek daha fazla işlemci bağlı olmayan şeyleri beklemek için harcıyoruz . Birçok programda, harcanan zamanın büyük bir kısmı, işlemcinin sıfıra ayarlanmasıdır ve ağ paketlerinin İngiltere'den Japonya'ya ve tekrar geri yolculuk yapmasını ya da disklerin dönmesini ya da her neyse beklemektir.

Ve eşzamansız işlemleri daha fazla oluşturmak isterseniz ne olacağı hakkında bile konuşmadım. ArchiveDocuments'i bir temsilci alan eşzamansız bir işlem yapmak istediğinizi varsayalım. Şimdi onu çağıran tüm kod CPS de yazılmalıdır. Boya sadece yayılır.

Eşzamansız mantığı doğru yapmak önemlidir, bu sadece gelecekte daha önemli olacaktır ve size verdiğimiz araçlar , Profesör Duggan'ın akıllıca söylediği gibi sizi “başınızın üzerinde durun ve kendinizi ters çevirin” .

Devam etme tarzı güçlü, evet, ancak bu gücü iyi kullanmanın yukarıdaki koddan daha iyi bir yolu olmalı.

Tüm makaleleri ve tüm bu karmaşayı derleyiciye taşıyan ve belirli bölümleri eşzamansız olarak işaretlemek için özel bir anahtar kelimeyle kodunuzu normal kontrol akışı olarak yazmanıza olanak tanıyan yeni bir C # dil özelliği üzerindeki aşağıdaki seriler , bir C # geliştiricisi değil. Değilim, ama ilk kez karşılaştığımda hala oldukça aydınlatıcı bir deneyimdi.


5
Diliniz makrolar gibi sözdizimi uzantılarını destekliyorsa, sözdizimi uzantılarının içinde çeşitli ilginç kontrol akışlarını uygulamak için mekanizmaları gizleyebileceğiniz için süreklilikler çok daha yararlı hale gelir . Temel olarak "beklemek" nasıl çalışır, çünkü C # sözdizimi uzantılarını kendiniz tanımlamak için araçlar sağlamadığından, sadece dilde tanımlanmıştır.
Jack

İyi bir makale, ancak CPS ve birinci sınıf devamların tam olarak aynı şey olmadığını not edeceğim (CPS, ihtiyaç duyduğunuzda süreklilik desteği olmayan bir dilde yaptığınız şeydir). C #, tam olarak düşündüğüm rotadan aşağıya iniyor gibi görünüyor (lastik dönüşümünü CPS'ye otomatikleştirmek mi yoksa tam gelişmiş yığın kopyalamalı sınırlandırılmış devamları uygulamak isteyip istemediğime rağmen).
Jules

@Jack - şu anda tam olarak düşündüğüm şey: tasarladığım dilin CPS dönüşümünü otomatik olarak destekleyebilecek bir makro özelliği var. Ancak tam yerel süreklilikler daha iyi performans verebilir ... soru şu ki, performans açısından kritik bir durumda ne sıklıkla kullanılırlar?
Jules
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.