Bir programlama dilinin dikgenliği nasıl doğrulanır / kanıtlanır?


10

Diklik kavramını biliyorum, ama programlama dili açısından bunu doğrulamanın / kanıtlamanın bir yolu var mı?

Örneğin C # ' publicda static, bir yöntem imzası için veya kullanılabilir . İkisinden birini veya her ikisini de kullanabilirsiniz ve birbirlerine müdahale etmezler, bu yüzden birbirlerine diktirler, değil mi?

Sorum şu, geri kalan özellikler, özellikle de birbiriyle ilgili olmayan özellikler hakkında nasıl konuşurum?

Tüm özelliklerin bir arada var olması / yığınlanması gerekiyor mu?

% 100 dikey olan bir programlama dili var mı?


(Yakın) başından başla: montaj dili?
Matthew Flynn

1
Aslında bir şeyi kanıtlamak için bunun resmi bir tanımına ihtiyacınız vardır. Ve tanımınız C # spec kadar büyük bir şey olacaksa, herhangi bir şeyin kanıtlanması çok iş alacaktır.
svick

Yanıtlar:


4

“Operasyonlar” ve “işlenenler” - dilin kolay kolay olmayan küçük kısımları - ayrımı gerektirdiğinden, dikeyliğin C # gibi genel amaçlı yüksek dereceli diller durumunda faydalı veya geçerli bir metrik olarak kullanılabileceğinden emin değilim. C # gibi üst düzey dillerde ayırt edilebilir.

Diklik konusundaki anlayışım, belirli bir CPU veya mikrodenetleyicinin komut kümesinin dikliğinin veri türlerine bağlı olarak bu CPU veya denetleyici tarafından gerçekleştirilen işlemlerde bazı kısıtlamalar olup olmadığını belirlediği Assembler diline dayanmaktadır . İlk zamanlarda bu önemliydi çünkü her CPU kesirli sayılar veya farklı uzunluktaki sayılardaki işlemleri desteklemiyordu.

Bu bakımdan, Yığın Makine dilini C # derleyicisi için değil, C # için hedef olarak kullanarak Ortak Ara Dilin dikeyliğini kontrol ederim .

Eğer gerçekten C # dikeyliği ile ilgileniyorsanız ve burada yanılmıyorsam (herhangi bir amaçla) bazı genetik programlama algoritmalarına bakmanızı öneririm . Bunları, verilen anahtar kelime kümesinden (anlamsız olanları bile) farklı programlar oluşturmak için kullanabilirsiniz ve bunların derlenebilir olup olmadığını otomatik olarak kontrol edebilirsiniz. Bu, dilin hangi öğelerinin birleştirilebileceğini otomatik olarak görmenize ve dikeylik metriğinizin bazı yönlerini türetmenize yardımcı olur.


6

"Diklik" terimi kesin bir matematiksel kavram için bir layman terimidir: dil terimleri bir ilk cebir oluşturur (Wikipedia'da bakın).

Temel olarak "sözdizimi ve anlam arasında 1-1 bir yazışma var" anlamına gelir. Bu şu anlama gelir: bir şeyleri ifade etmenin tam bir yolu vardır ve eğer belirli bir yere biraz ifade koyabilirseniz, oraya başka bir ifade de koyabilirsiniz.

"Dik" düşünmenin başka bir yolu da sözdiziminin ikame ilkesine uymasıdır. Örneğin, bir ifade için yuvalı bir ifadeniz varsa, herhangi bir ifade oraya konabilir ve sonuç yine de sözdizimsel olarak geçerli bir programdır. Ayrıca,

Vurgulamak istiyorum ki, "anlam", hesaplama sonucu anlamına gelmez. Açıkçası, 1 + 2 ve 2 + 1 her ikisi de 3'e eşittir. Ancak, terimler farklıdır ve aynı sonuca sahip olsa bile farklı bir hesaplama gerektirir. İki sıralama algoritması farklı olduğu için anlam farklıdır.

"Soyut sözdizimi ağacı" (AST) duymuş olabilirsiniz. Burada "soyut" kelimesi tam olarak "dik" anlamına gelir. Teknik olarak çoğu AST, aslında soyut değildir!

Belki de "C" programlama dilini duydunuz? C tipi gösterim soyut değildir. Düşünmek:

int f(int);

İşte burada bir işlev bildirim döndürme türü int. Bu işleve bir işaretçinin türü şu şekilde verilir:

int (*)(int)

Not, fonksiyonun tipini yazamazsınız! C tipi gösterim büyük zaman berbat! Soyut değil. Dik değil. Şimdi, int yerine yukarıdaki türü kabul eden bir işlev yapmak istediğimizi varsayalım:

int (*) ( int (*)(int) )

Herşey yolunda .. ama .. ya geri dönmek istiyorsak:

int (*)(int) (*) (int)

Woops! Geçersiz. Parens ekleyelim:

(int (*)(int)) (*) (int)

Woops! Bu da işe yaramıyor. Bunu yapmak zorundayız (tek yol!):

typedef int (intintfunc*) (int);
intintfunc (*)(int)

Şimdi sorun değil, ama burada bir typedef kullanmak zorunda değilsiniz. C berbat. Soyut değil. Dik değil. Bunu ML'de şu şekilde yapabilirsiniz:

 int -> (int -> int)

C'yi sözdizimi düzeyinde kınıyoruz.

Tamam, şimdi f ++ C ++ 'ı alalım. Yukarıdaki aptallığı şablonlarla düzeltebilir ve ML benzeri gösterim (daha fazla veya daha az) alabiliriz:

fun<int, int>
fun< fun<int,int>, int>

ancak asıl yazım sistemi temelde referanslarla kusurludur: eğer Tbir tür ise, o zaman T&bir türdür? Cevap waffly: sözdizimi düzeyinde, bir U = T & tipine sahipseniz, U & izin verilir, ancak sadece T & anlamına gelir: bir referansa referans, orijinal referanstır. Bu berbat! Teklik gereksinimini anlamsal olarak kırar. Daha kötüsü: T & & sözdizimsel olarak izin verilmez: bu, ikame ilkesini ihlal eder. Dolayısıyla C ++ referansları, bağlama süresine (ayrıştırma veya tip analizi) bağlı olarak dikeyliği iki farklı şekilde keser. Bunu nasıl doğru yapacağınızı anlamak istiyorsanız .. işaretçilerle ilgili bir sorun yok!

Neredeyse hiçbir gerçek dil dik değildir. İfadenin netliğini taklit eden Şema bile değildir. Bununla birlikte, birçok iyi dilin "dik özellik özelliklerine makul ölçüde yakın" olduğu değerlendirilebilir ve bu, hem sözdizimine hem de temel anlambilime uygulanan bir dil için iyi bir tavsiye niteliğindedir.


Yani ML'nin diğerlerinden daha dik olduğunu mu düşünüyorsunuz? Lisp ve Haskell ne olacak?
Joan Venge

1
@joan: Peki, Lisp herhangi bir özelliğe sahip değil, bu yüzden vaccuuo'daki gereksinimi karşılar :)
Yttrill

@joan: Ben bir Haskell programcısı değilim, bu yüzden söylemesi biraz zor, ama Haskell'deki "son derece üst düzey işlevsellik" in varlığı güçlü bir diklik göstergesidir: Monad veya Okların tutarlı bir uygulamasına sahip olamazsınız dilin geri kalanında önemli bir "diklik" vardır
Yttrill

Pascal hakkında ne düşünüyorsun. C'den daha iyi yükler görünüyor
supercat

Yorumumun neredeyse 4 yıl geç olduğunu biliyorum ama ben de karşımıza çıkmıştı. Bu cevap hemen hemen her konuda yanlıştır. Hatta bütün bu "tek yol!" kısmı yanlış. Bir typedef örneği olmadan int (*intintfunc())(int) { ... }intintfunc'un hiçbir argüman almayan ve 1 int argümanı alan ve int değeri döndüren bir işleve bir işaretçi döndüren bir işlev olduğunu kolayca ifade edebilirsiniz .
Wiz

4

Dikliği kanıtlamak olumsuz bir sonuçtur. Size bir şeyler kanıtlamak için çok daha kolaydır, yani dik olmayan herhangi yapıları olmadığı anlamına gelir değil daha dik.

Uygulamada, çoğu insan programlama dillerinin dikgenliği hakkında ya tamamen dik ya da dik olmak yerine derece cinsinden bahseder. Bir bağlamda bir şey yapmanın bilgisi başka bir bağlama dönüştüğünde ve "beklediğinizi yaparsa", o dilin daha dik olduğu söylenir. LISP son derece dik olarak kabul edilir, çünkü her şey bir listedir, ancak kullanımını kolaylaştıran bazı fazlalıklar nedeniyle% 100 dik olduğu söylenebilir. C ++ çok dik olarak kabul edilmez çünkü pek çok küçük "gotchas" vardır ve burada düşündüğünüz gibi çalışmaz.


3

Uyarı, bu konu hakkında hiçbir şey bilmiyorum.

Wikipedia'ya hızlı bir bakış, Diklik'in çoğunlukla tasarım desenlerine ve sistem tasarımına yöneldiğini gösteriyor. Programlama dilleri açısından, giriş, olası her eylem için bir ve sadece bir talimat varsa veya başka bir komutla örtüşmüyorsa komut setlerinin dikey olduğunu gösterir.

C # için, sözdizimi hilelerinin ( foreachakla geliyor) temel yapının özel olarak oluşturulmuş sürümlerinin ( döngüler foreachhaline gelir for) ön uçları olduğunu dik olarak düşünürüm. Genel olarak, sözdizimsel şeker bunları yapmak için ek yollar sağlamasına rağmen, dil sadece bir şey yapmayı gerçekten destekler. Ve son olarak, MSILher şey (ya da bugünlerde ne denirse) derler ve MSILmuhtemelen diktir.

Eğer sözdizimsel şeker malzemesinin aslında onu "zor yol" yapmak için bir "sarıcı" olduğu konusunda uyarırsanız, dilin çeşitli özelliklerini analiz edebilir, şekeri atlayabilir ve gerçekten örtüşen herhangi bir yapı olup olmadığını görebilirsiniz. Değilse, dili dik olarak beyan edebileceğinizi hayal ediyorum.

Benim görüşüm.


Bence hem foreach hem de foreach bir dilin özellikleri ise, biri diğerinin sözdizimsel şekeriyse (foreach'in etkilerinin for kullanılarak kullanılarak elde edilebildiği yerlerde), dil ortogonitesini kaybeder.
vpit3833

İle do...whileaynı etkiyi sağlamak için kullanılamaz formı? Hiçbir zaman sözdizimsel şeker olarak da hiç duymadım.
Matthew Flynn

1
@MatthewFlynn: Bah! Her ikisi de sözdizimsel şekerler, yinelemenizi tekrarlayan bir işlevle değiştirebilirsiniz! ;)
SinirliWithFormsDesigner

2
@FrustratedWithFormsDesigner: Bu sadece GOTO'lar için sözdizimsel şeker değil mi?
Ivan

2
@ MatthewFlynn do whiletek bir döngü yürütmeyi garanti eder ve durumdan sonra durumu kontrol eder. forönce koşulu kontrol eder ve tek bir yürütmeyi garanti etmez.
digitlworld

2

Sorum şu, geri kalan özellikler, özellikle de birbiriyle ilgili olmayan özellikler hakkında nasıl konuşurum?

Yaptığınız şeyi yapmaya devam edersiniz, çalışan veya yasak olan tüm kombinasyonları numaralandırırsınız.

Bu kadar. Yapmak oldukça acı verici.

Tüm özelliklerin bir arada var olması / yığınlanması gerekiyor mu?

Eğer bütün özellikler birbirine engel yok ayrık alt kümeleri içine bölümlenmiş, sonra emin, tüm mantıklı olurdu.

Tüm veri yapıları tüm ilkel tiplerle çalışır. Tüm ifade işleçleri her türle çalışır. Bunlar, dikgenliğin ortak tanımlarıdır. Ama daha fazla (veya daha az) isteyebilirsiniz

Bununla birlikte, bazen, işletim sistemleri veya dikey olmayan eski kütüphaneler nedeniyle özel durumlar vardır.

Ayrıca, bazı türler gerçekten çok uygun değildir. Örneğin Python "sipariş" için iki sözlük nesnesini karşılaştırmanıza izin verir. Ancak sözlükler arasında "sıralamanın" neredeyse mantıklı bir tanımı yoktur. Python birini tanımlar, ama oldukça tartışmalıdır. Bu özel durum sözlükleri bir dikeylik testinde başarısız yapıyor mu?

"Yeterince dik" ne kadar diktir? Ne yapıyoruz sen kendi dilinizde diklik derecesi ile mutlu olmak görmeliyim.


2

Normal olmayan özelliklerin listesi aslında çoğu programlama dilinde uzundur, ör.

  • anonim sınıflar java yansıması ile çatışıyor
  • java yansıması ile genel ve tür silme çakışması
  • diziler, nesneler olsalar da, özel türleri nedeniyle diğer nesnelerden biraz farklıdır.
  • statik ve örnek yöntemleri aynı değildir, örneğin statik bir yöntemi geçersiz kılamazsınız
  • iç içe sınıf bir düşünce sonrasıdır
  • dinamik ve statik yazmanın ileti gönderme stratejisi üzerindeki etkisi (bkz . C # 'daki bu son durum )
  • vb.

Bunlar sadece aklıma gelen birkaç tane, ama diğerleri ve diğer dillerde de var.

Dil özellikleri arasında ince bir parazit olmamasını sağlamak zordur. CAR Hoare'nin "Dil Tasarımını Programlamaya İlişkin İpuçları" makalesinde belirttiği gibi:

Dil tasarımının bir kısmı inovasyondan oluşur. Bu etkinlik yalıtılmış yeni dil özelliklerine yol açar. Dil tasarımının en zor kısmı entegrasyonda yatmaktadır : sınırlı sayıda dil özelliği seçmek ve sonuç pürüzlü kenarları olmayan tutarlı ve basit bir çerçeveye kadar parlatmak.

Muhtemelen, dikliği artırmak için iyi bir hareket, kavramları birleştirmektir (@ karl-bielfeld cevabı yönünde gider). Her şey varsa, bir liste veya nesne söyleyin, daha az çatışma olması ihtimali vardır. Ya da dersi sonradan düşünmek yerine, onu temel özellikler haline getirin.

Çoğu programlama dili belgesi, resmileştirilmiş dilin bir alt kümesinde ("çekirdek") dilin belirli özelliklerini (örneğin ses sağlamlığı) kanıtlamaktadır. Burada tam tersini yapmalıyız, tüm özelliklerin güvenli bir şekilde oluşturulduğunu kanıtlamalıyız. Ayrıca bu, "bestelemenin" ne anlama geldiğini tanımlaması gerektiği anlamına gelir. "Koşmak" demek mi? (Bu durumda, dinamik ve statik yazarak kenar durumu hakkındaki yukarıdaki bağlantı güvenlidir). "Güvenli" demek mi? Geliştirici açısından öngörülebilir olmak mı demek?

Bütün bunlar çok ilginç - ama aynı zamanda çok zorlayıcı.

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.