Tür Silme İyi
Gerçeklere bağlı kalalım
Şimdiye kadarki cevapların çoğu, Twitter kullanıcısı ile aşırı derecede ilgileniyor. Haberciye değil mesajlara odaklanmak faydalı olacaktır. Şimdiye kadar bahsedilen alıntılarla bile oldukça tutarlı bir mesaj var:
Java kullanıcılarının tür silme işleminden şikayet etmeleri komiktir ki bu, Java'nın yanlış yaptığı her şeyi görmezden gelirken doğru yaptığı tek şeydir.
Büyük faydalar (örneğin parametriklik) ve sıfır maliyet (iddia edilen maliyet hayal gücümün bir sınırıdır) elde ediyorum.
yeni T bozuk bir programdır. "Bütün önermeler doğrudur" iddiası izomorfiktir. Ben bu kadar büyük değilim.
Bir hedef: makul programlar
Bu tweetler, makineye bir şey yaptırıp yaptıramayacağımızla ilgilenmeyen bir perspektifi yansıtıyor , daha çok, makinenin gerçekten istediğimiz bir şeyi yapmasını isteyip istemediğimizle ilgileniyor . İyi muhakeme bir kanıttır. Kanıtlar resmi gösterimle veya daha az resmi bir şekilde belirtilebilir. Şartname diline bakılmaksızın, açık ve titiz olmaları gerekir. Resmi olmayan spesifikasyonların doğru şekilde yapılandırılması imkansız değildir, ancak pratik programlamada genellikle kusurludur. Resmi olmayan muhakeme ile karşılaştığımız sorunları telafi etmek için otomatik ve keşif testleri gibi iyileştirmeler yapıyoruz. Bu, testin özünde kötü bir fikir olduğu anlamına gelmez, ancak alıntı yapılan Twitter kullanıcısı çok daha iyi bir yol olduğunu öne sürüyor.
Dolayısıyla amacımız, makinenin programı gerçekte nasıl çalıştıracağına karşılık gelecek şekilde açık ve titiz bir şekilde akıl yürütebileceğimiz doğru programlara sahip olmaktır. Yine de tek amaç bu değil. Ayrıca mantığımızın bir dereceye kadar anlamlı olmasını da istiyoruz. Örneğin, önermesel mantıkla ifade edebileceğimiz çok şey var. Birinci dereceden mantık gibi bir şeyden evrensel (∀) ve varoluşsal (∃) nicelemeye sahip olmak güzel.
Muhakeme için tip sistemlerini kullanma
Bu hedefler, tip sistemler tarafından çok güzel bir şekilde ele alınabilir. Bu, özellikle Curry-Howard yazışmaları nedeniyle nettir . Bu uyuşma genellikle aşağıdaki benzetmeyle ifade edilir: teoremler ispat için olduğu gibi türler programlardır.
Bu yazışma biraz derin. Mantıksal ifadeler alabilir ve bunları yazışmalar yoluyla türlere çevirebiliriz. Daha sonra, derleyen aynı tip imzaya sahip bir programımız varsa, mantıksal ifadenin evrensel olarak doğru olduğunu (bir totoloji) kanıtlamış oluruz. Bunun nedeni, yazışmanın iki yönlü olmasıdır. Tür / program ve teorem / ispat dünyaları arasındaki dönüşüm mekaniktir ve çoğu durumda otomatikleştirilebilir.
Curry-Howard, bir programın spesifikasyonlarıyla yapmak istediklerimizi güzel bir şekilde oynuyor.
Tür sistemleri Java'da kullanışlı mı?
Curry-Howard anlayışına rağmen, bazı insanlar bir tür sistemin değerini göz ardı etmeyi kolay buluyor.
- çalışmak son derece zor
- (Curry-Howard aracılığıyla) sınırlı ifade gücüne sahip bir mantığa karşılık gelir
- bozuk (sistemlerin "zayıf" veya "güçlü" olarak nitelendirilmesine ulaşır).
İlk noktaya gelince, belki de IDE'ler Java'nın yazı sistemini çalışmayı yeterince kolaylaştırır (bu oldukça özneldir).
İkinci nokta ile ilgili olarak, Java neredeyse birinci dereceden bir mantığa karşılık gelir. Jenerikler, evrensel nicelemenin tip sistemi eşdeğerini kullanır. Ne yazık ki, joker karakterler bize varoluşsal niceliğin yalnızca küçük bir bölümünü verir. Ancak evrensel niceleme oldukça iyi bir başlangıçtır. Tüm olası listeler List<A>
için evrensel olarak çalıştığını söyleyebilmek güzel çünkü A tamamen sınırsızdır. Bu, Twitter kullanıcısının "parametriklik" açısından ne hakkında konuştuğuna götürür.
Parametriklik hakkında sık sık alıntılanan bir makale, Philip Wadler'in Teoremleridir! . Bu makaleyle ilgili ilginç olan şey, sadece tip imzasından yola çıkarak, bazı çok ilginç değişmezleri kanıtlayabilmemizdir. Bu değişmezler için otomatik testler yazacak olsaydık, zamanımızı çok boşa harcardık. Örneğin, List<A>
yalnızca tür imzasındanflatten
<A> List<A> flatten(List<List<A>> nestedLists);
buna sebep olabiliriz
flatten(nestedList.map(l -> l.map(any_function)))
≡ flatten(nestList).map(any_function)
Bu basit bir örnek ve muhtemelen gayri resmi olarak akıl yürütebilirsiniz, ancak bu tür kanıtları resmi olarak tür sisteminden ücretsiz olarak aldığımızda ve derleyici tarafından kontrol edildiğinde daha da güzel.
Silmemek kötüye kullanımlara yol açabilir
Dil uygulaması perspektifinden bakıldığında, Java'nın jenerikleri (evrensel türlere karşılık gelir), programlarımızın ne yaptığına dair kanıtlar elde etmek için kullanılan parametrikliğe çok fazla etki eder. Bu, bahsedilen üçüncü soruna ulaşır. Tüm bu kanıt ve doğruluk kazanımları, hatasız uygulanan sağlam bir sistem gerektirir. Java, muhakememizi parçalamamıza izin veren bazı dil özelliklerine kesinlikle sahiptir. Bunlar aşağıdakileri içerir ancak bunlarla sınırlı değildir:
- harici bir sistemle yan etkiler
- yansıma
Silinmemiş jenerikler birçok yönden yansıma ile ilgilidir. Silinmeden, algoritmalarımızı tasarlamak için kullanabileceğimiz uygulama ile taşınan çalışma zamanı bilgisi vardır. Bunun anlamı, statik olarak, programlar hakkında mantık yürüttüğümüzde, resmin tamamına sahip değilizdir. Düşünme, statik olarak akıl yürüttüğümüz herhangi bir ispatın doğruluğunu ciddi şekilde tehdit eder. Tesadüf değil yansıması, çeşitli hileli kusurlara da yol açar.
Öyleyse silinmemiş jeneriklerin "yararlı" olabileceği yollar nelerdir? Tweet'te bahsedilen kullanımı düşünelim:
<T> T broken { return new T(); }
T'nin argüman içermeyen bir kurucusu yoksa ne olur? Bazı dillerde aldığınız şey boştur. Ya da belki boş değeri atlarsınız ve doğrudan bir istisna oluşturmaya gidersiniz (null değerler yine de sonuçlanır gibi görünür). Dilimiz Turing tamamlandığından, hangi çağrıların broken
"güvenli" türleri içereceği ve argümansız kurucularla hangilerinin olmayacağı hakkında mantık yürütmek imkansızdır . Programımızın evrensel olarak çalıştığına dair kesinliği yitirdik.
Silme, gerekçelendirdiğimiz anlamına gelir (öyleyse hadi silelim)
Bu nedenle, programlarımız hakkında mantık yürütmek istiyorsak, muhakememizi şiddetle tehdit eden dil özelliklerini kullanmamamız şiddetle tavsiye edilir. Bunu yaptıktan sonra, o zaman neden türleri çalışma zamanında bırakmıyoruz? Bunlara gerek yok. Hiçbir yayınlamanın başarısız olmayacağı veya yöntemlerin çağrı üzerine eksik olabileceği memnuniyetiyle biraz verimlilik ve basitlik elde edebiliriz.
Silme akıl yürütmeyi teşvik eder.