Beyanname programlama hayali [kapalı]


26

Neden bildirimsel programlama hayali gerçekleşmedi? Buna engel olan somut engeller neler? Basit bir örnek için neden söyleyemem

sort(A) is defined by sort(A) in perm(A) && asc(sort(A))

ve otomatik olarak bunun dışında bir sıralama algoritması olsun. permpermütasyonlar ve ascartan anlamına gelir.


4
Bu arada, sizin özel örneğiniz zaten mevcut: gkoberger.github.io/stacksort
Den

3
Prolog'u duydun mu? Sadece "Cevap Kümesi Programlama" bölümüne bakınız. Varsayılan mantık üzerine kurulu birçok sistem var.
schlingel

16
Peki, bu soru kolayca cevaplanabilir. Böyle bir sistemi uygulamaya çalışın . Seni başarılı bir şekilde yapmaktan ne alıkoydu? Her neyse, seni durduran her şeyin herkesi durdurmuş olması ihtimalleri iyi.
Eric Lippert

4
Bu sorunun elde ettiğinden daha fazla krediyi hakettiğine inanmak için can atıyorum. İlk bakışta baktığınızda, düşünebilirsiniz, Eh, bu basit! Bunun arkasındaki bütün mantığı programlamanız gerekiyor ve bilgisayarlar o kadar da akıllıca değil. ... Ama sonra geri dönüp bu soruya ikinci kez göz atarsınız ve bir kez daha düşünürsünüz, Eh, evet, bu basit ve tüm bu mantığı programlamanız gerekiyor - ve bilgisayarlar mutlaka en keskin araçlar değil kulübede, doğru - ama bu açıklamanın yüzeyde durduğundan çok daha fazla derinliği var.
Panzercrisis

3
Bir sıralama algoritması tanımınız bildirimde bulunur, evet, ama kesinlikle etkili olmadığı kesin. n!Bir dizinin permütasyonları vardır ve en kötü durumda, algoritmanızın sıralanmış bir tane bulmak için hepsini denemesi gerekecektir. Faktöriyel zaman, bir sekansın yapabileceği bir algoritma kadar kötüdür.
Benjamin Hodgson

Yanıtlar:


8

Çok iyi cevaplar var. Tartışmaya katkıda bulunmaya çalışacağım.

Prolog'da bildirimsel, mantıksal programlama konusunda, Richard O'Keefe'nin "The Prolog El Sanatları" adlı harika kitabı var . Verimsiz programlar yazmanıza izin veren bir programlama dili kullanarak verimli programlar yazmakla ilgilidir. Bu kitapta, çeşitli algoritmaların verimli uygulamaları tartışılırken ("Programlama Yöntemleri" bölümünde), yazar aşağıdaki yaklaşımı benimsemiştir:

  • sorunu ingilizce olarak tanımlayabilir
  • mümkün olduğunca bildirici olan bir çalışma çözümü yazınız; genellikle, bu tam olarak sorunuzda ne var demektir, sadece doğru Prolog
  • oradan, uygulamayı daha hızlı hale getirmek için uygulamayı geliştirmek

En aydınlatıcı (benim için) gözlem, yolumdan geçerken bunları yapabildim:

Evet, uygulamanın son hali, yazarın başladığı “bildirici” şartnameden çok daha verimli. Hala çok açıklayıcı, özlü ve anlaşılması kolaydır. Arada olan, nihai çözümün, başlangıç ​​çözümünün kayıtsız olduğu sorunun özelliklerini yakalamasıdır.

Başka bir deyişle, bir çözümü uygularken, sorunla ilgili bilgimizden olabildiğince faydalandık. Karşılaştırmak:

Tüm öğelerin artan düzende olacağı bir listenin permitasyonunu bulun

için:

İki sıralı listeyi birleştirmek sıralı bir listeye neden olur. Zaten sıralanmış olan alt listeler olabileceğinden, bunları uzunluk 1 olan alt listeler yerine başlangıç ​​noktası olarak kullanın.

Küçük bir kenara: Verdiğiniz gibi bir tanım çekici çünkü çok genel. Ancak, permütasyonların bir birleşimsel sorun olduğu gerçeğini bilerek yok saydığı duygusundan kaçamam. Bu zaten bildiğimiz bir şey ! Bu bir eleştiri değil, sadece bir gözlem.

Asıl soruya gelince: nasıl ilerlenir? Bir yolu, bilgisayara bildirdiğimiz sorun hakkında çok fazla bilgi vermektir.

Sorunu gerçekten çözmek için bildiğim en iyi girişim Alexander Stepanov, "Programlamanın Öğeleri" ve "Matematikten Jenerik Programlamaya" ortak yazılan kitaplarda sunulmuştur . Ne yazık ki bu kitaplardaki her şeyi özetleme (hatta tamamen anlama) görevine bağlı değilim. Bununla birlikte, buradaki yaklaşım, girdinin tüm ilgili özelliklerinin önceden bilinmesi şartıyla, verimli (veya hatta optimal) kütüphane algoritmalarını ve veri yapılarını tanımlamaktır. Nihai sonuç:

  • Her iyi tanımlanmış dönüşüm, zaten var olan kısıtlamaların (bilinen özellikler) iyileştirilmesidir;
  • Mevcut kısıtlamalara dayanarak bilgisayarın hangi dönüşümün optimal olduğuna karar vermesine izin veriyoruz.

Neden henüz tam olarak yaşanmadığına gelince, bilgisayar bilimi gerçekten genç bir alan ve hala çoğunun yeniliğini gerçekten takdir etmekle başa çıkıyoruz.

PS

"Uygulamayı ayrıntılandırmak" derken neyi kastettiğimin tadına varmak için: örneğin, Prolog'da bir listenin son unsurunu elde etmenin kolay sorununu alın. Kanonik bildirimsel çözüm şöyledir:

last(List, Last) :-
    append(_, [Last], List).

Burada, bildirimsel anlamı append/3şudur:

List1AndList2olduğu birleştirilmesi List1veList2

İkinci argüman için append/3sadece bir elementli bir listeye sahip olduğumuz ve ilk argüman dikkate alınmadığı için (alt çizgi), listenin önünü ( List1bağlamında append/3) ayıran ve talep eden orijinal listenin bir bölümünü alıyoruz . Geri ( List2bağlamında append/3) gerçekten sadece bir element içeren bir liste: yani, bu son element.

SWI-Prolog tarafından sağlanan fiili uygulama , ancak, diyor ki:

last([X|Xs], Last) :-
    last_(Xs, X, Last).

last_([], Last, Last).
last_([X|Xs], _, Last) :-
    last_(Xs, X, Last).

Bu hala hoş bir şekilde beyan edicidir. Yukarıdan aşağıya doğru okuyun, diyor ki:

Bir listenin son elemanı sadece en az bir elemanın listesi için anlamlıdır. Kuyruğun bir çifti için son eleman ve bir listenin başı, öyleyse: kuyruk, boşken veya boş olmayan kuyruğun sonuncusu.

Bu uygulamanın sağlanmasının nedeni Prolog'un yürütme modelini çevreleyen pratik meseleler üzerinde çalışmaktır . İdeal olarak, hangi uygulamanın kullanıldığı fark yaratmamalıdır. Benzer şekilde şöyle diyebilirdik:

last(List, Last) :-
    reverse(List, [Last|_]).

Bir listenin son elemanı, ters çevrilmiş listenin ilk elemanıdır.

Neyin iyi olduğu konusundaki sonuçsuz tartışmaları doldurmak istiyorsanız, bildirimdeki Prolog, Yığın Akışı üzerindeki Prolog etiketindeki bazı soru ve cevapları inceleyin .


2
Bildirim niteliğinde bir tasarımın basit bir soyutlamadan yinelemeli tasarım süreci yoluyla daha somut bir uygulamaya nasıl ilerleyebileceğini göstermek için +1.
saat

1
@ Boris Bu iyi bir cevap. Bu kitap benim rafımda oturuyor. Muhtemelen açmamın zamanı geldi.
davidk01

1
@ davidk01 Dışarıdaki en iyi kitaplardan biri. Genel olarak Prolog ve programlama konusunda oldukça rahat olduğunuzu varsayıyor, ancak programlamaya yönelik yaklaşım hem pragmatik hem de çok kapsamlı.
XXX

2
@Boris, örneğin karmaşık olmadığını biliyorum ama yinelemeli tasarım sürecinin üretkenliği - bildirim dillerinin gerçek gücü - ve bu çok pratik bir değer, çok önemli. Bildirici diller, yinelemeli iyileştirme herreğine açık, tutarlı, özyinelemeli bir yaklaşım sunar. Zorunlu diller yok.
saat

1
"Neyin iyi, bildirimsel Prolog" hakkındaki sonuçsuz tartışmaları doldurun + 1 için ... kesinlikle katılmıyorum eğiliminde!
Daniel Lyons

50

Mantıksal diller zaten bunu yapıyor. Sıralama işlemini, yaptığınız gibi benzer şekilde tanımlayabilirsiniz.

Asıl sorun performanstır. Bilgisayarlar bir çok şeyi hesaplamakta harika olabilirler, fakat özünde aptallar. Bir bilgisayarın verebileceği her "akıllı" karar bir programcı tarafından programlandı. Ve bu karar genellikle nihai sonucun nasıl göründüğü ile değil, adım adım bu nihai sonucun nasıl elde edileceği ile açıklanmaktadır.

Bir Golem'in hikayesini hayal edin . Ona soyut bir emir vermeye çalışırsanız, o zaman en iyi ihtimalle, o verimsiz ve en kötü ihtimalle yapar, kendinize, size veya başka birine zarar verir. Ancak, istediğinizi mümkün olan en ayrıntılı şekilde açıklarsanız, görevin etkin ve verimli bir şekilde tamamlanması garanti edilir.

Hangi düzeyde soyutlamanın kullanılacağına karar vermek programcının görevidir. Yaptığınız uygulama için üst seviyeye çıkacak ve onu soyut şekilde tanımlayacak ve performansı vuracak veya düşük ve kirlenecek, üzerinde 10 kat daha fazla zaman geçirecek, ancak 1000 kat daha fazla performans gösteren bir algoritma elde edecek misiniz?


6
Golem wordולם kelimesinin aslında "ham madde" anlamına geldiğini bilmek yardımcı olabilir - yani makinenin / varlığın olabileceği en temel durumdur.
dotancohen

2
Bildirici diller doğası gereği düşük soyutlama seviyelerinin önünde bir engel değildir. Haskell ve Standard ML, farklı biçimlerde, bir yerdeki türler / işlevler hakkında basit bildirici açıklamalar yapmanıza, ayrı bir yerde bir dizi somut ve belirli işlev uygulamaları sunmanıza ve başka bir türdeki uygulamalarla eşleştirme yollarına olanak sağlar. Bu arada, OO / Emperative dillerinde en iyi uygulama şimdi yüksek / basit başlayıp daha sonra uygulama detaylarını eklemekle ilgili. Fark, yüksek soyutlamanın FP'de daha kolay olması, düşük seviyenin zorunlu olarak daha kolay olmasıdır.
15'te

2
Söz konusu iki dilde de, OP'nin istediğini hemen hemen sağlayan kodlama spesifik eşleşmelerden ziyade, türün özelliklerine dayalı olarak özel uygulama seçimini çözmenin mümkün olduğunu söylemelidir. Haskell'de, tip sınıfları bunun için önemli bir araç olacaktır. Standart ML'de, işlevler.
15'de

22
! @BAR Golem = golum Golem Yahudi folklor dan
Euphoric

10
Bu cevaptaki paket servisim dizüstü bilgisayarıma is yazmak.
Dan J

45

Euphoric'in mükemmel noktasına ek olarak , iyi çalıştıkları birçok yerde bildirimsel diller kullandığımızı, yani bilgisayarın gerçekten etkili kod üretebileceği bir şeyi değiştirmesinin veya talep etmesinin istenmediğini açıklamak istediğimizi de eklemek isterim. kendi başına:

  • HTML, bir web sayfasının içeriğinin ne olduğunu açıklar.

  • CSS, bir web sayfasındaki çeşitli eleman türlerinin nasıl görünmesi gerektiğini açıklar.

  • Her ilişkisel veritabanı, veritabanının yapısının ne olduğunu bildiren bir veri tanımlama diline sahiptir.

  • Görmek istediğinizi anlattığınızdan ve veritabanının sorgu planlamacısının gerçekte nasıl gerçekleştirileceğini bulduğu için SQL, zorunluluktan daha açıklayıcıdır.

  • Bir çok konfigürasyon dosyasının (.vimrc, .profile, .bashrc, .gitconfig) büyük oranda bildirimde bulunan bir alana özgü dil kullandığı söylenebilir.


3
Ben GNU Make, XSLT, Angular.js 'i de geniş çapta kullanılan, aynı zamanda bildirimsel olan şeylerden bahsedeceğim (köşeli belki tanımı biraz zorlasa da).
Mark K Cowan

Bu listeye düzenli ifadeler ekleyeyim.
Schwern

7
İnsanlar, bildirici dillerin yaygın olduğunu unutma eğilimindedir . Sadece tipik dilleri tamamlamıyorlar. Bu listeye regex ekleyin.
Slebetman

Biraz bilgiçlik, ancak yine de: Her veritabanının bir DDL'si yok, sadece çok sayıda şema NoSQL veritabanını düşünün. Her ilişkisel veritabanı olabilir, ancak her veritabanı olmayabilir.
Monica'yı eski durumuna getirme - dirkk 10:15

1
@dirkk Bunu düşünmemiştim. Cevabım düzeltildi.
Ixrec

17

Soyutlamalar sızdırıyor

Ne istediğinizi beyan ettiğiniz bir bildirim sistemi uygulayabilirsiniz ve derleyici veya yorumlayıcı bir işlem emri çıkarır. Teorik fayda, sizi “nasıl” hakkında düşünmek zorunda kalmaması ve bu uygulamayı ayrıntılandırmanız gerekmemesidir. Ancak, genel amaçlı hesaplama için pratikte, bunun nasıl uygulanacağını göz önünde bulundurarak 'nasıl' hakkında düşünmeniz ve her türlü püf noktasını yazmanız gerekir, aksi takdirde derleyici olacak bir uygulama seçebilir (ve çoğu zaman) çok, çok, çok yavaş (örneğin n! 'nin yeterli olacağı operasyonlar).

Özel örneğinizde, bir sıralama algoritması elde edersiniz - bu iyi veya hatta biraz da kullanışlı bir şey elde edeceğiniz anlamına gelmez. Verilen tanım, kelimenin tam anlamıyla gerçekleştirilirse (muhtemelen bir derleyici olabilir) , daha büyük veri kümeleri için kullanılamayan http://en.wikipedia.org/wiki/Bogosort ile sonuçlanır - teknik olarak doğrudur, ancak bin sayıyı sıralamak için sonsuzluğa ihtiyaç duyar. .

Bazı sınırlı etki alanları için, örneğin SQL gibi iyi bir uygulama bulmakta hemen hemen her zaman işe yarayan sistemler yazabilirsiniz. Özellikle iyi çalışmayan genel amaçlı bilişim için Prolog'a sistemler yazabilirsiniz, ancak Prolog'a yazabilirsiniz, ancak beyannamelerinizin tam olarak nasıl bir zorunlu yürütme emrine dönüştürüleceğini ve beklenen beyannamenin çoğunu kaybedeceğini görmelisiniz. programlama faydaları.


Söyledikleriniz esasen doğru olmakla birlikte, arayüz / sözleşme size örneğin yürütme süresi hakkında garanti vermediği sürece kötü performans, sızdıran bir soyutlamanın işareti değildir.
valenterry

3
Peters, kötü performansın sızan bir soyutlamanın işareti olduğunu söylemez, @ valenterry. Bir şey varsa, tam tersini söylüyor: iyi bir performans elde etmek için uygulama detaylarında sızıntı yapmak zorunda kalıyor .
15'te

2
Bence, soyutlamanın sızdırmaz olduğunu söylemek yanıltıcı olduğunu düşünüyorum, çünkü performansı nasıl etkilediğini anlamak için uygulamayı anlamanız gerekiyor. Bir soyutlamanın amacı, sizi performans hakkında düşünmek zorunda kalmaktan korumak değildir.
Doval

1
@jamesqf Bildirimsel programlamada, yalnızca bir şeyin sıralandığını belirtirsiniz. Sıralama düzeninin bazı değişkenlere / özelliklere bağlı olduğunu beyan edebilirsiniz. Ve sonra böyle olurdu. Her yeni veri eklendiğinde açıkça sıralama çağırmaya veya sipariş değişiklikleri sıralamanıza gerek yoktur.
Hyde

1
@jamesqf Kendinizi gerçekten denemeden noktayı gerçekten göremezsiniz (bildirimsel fikirlerle oynamak için QML Qt'yi öneririm). Sadece zorunlu programlamayı bilen birisini hayal edin ve gerçekte denemeden OOP veya fonksiyonel programlamanın noktasını anlamaya çalıştıklarını düşünün.
Hyde

11

Hesaplamalı karar verilebilirlik, bildirimsel programlamanın göründüğü kadar kolay olduğunu kanıtlamamasının en önemli nedenidir.

Görmesi kolay olan birçok sorunun kararsız olduğu veya çözülmesi gereken NP-tam karmaşıklığa sahip olduğu kanıtlanmıştır. Bu genellikle olumsuz sınıfları ve sınıflandırma, sayılabilirlik ve özyinelemeyi hesaba kattığımızda meydana gelir.

Bunu iyi bilinen bazı alan adlarıyla örneklemek istiyorum.

Hangi CSS sınıfının kullanılacağına ilişkin karar, bilgi ve tüm CSS kurallarının dikkate alınmasını gerektirir. Yeni kurallar eklemek diğer tüm kararları geçersiz kılabilir. Negatif CSS sınıfları, NP-tamamlayıcı sorunlar nedeniyle kasıtlı olarak dile eklenmez, fakat negatif sınıfların eksikliği CSS tasarım kararlarını zorlaştırır.

Bir (SQL) sorgu iyileştiricisinde, hangi sırayla birleşeceğinize, hangi endekslerin kullanılacağına ve hangi geçici sonuçlara tahsis edilecek belleğe karar vermede sorun yoktur. Bu bilinen bir NP tamamlama problemidir ve veritabanı tasarımı ve sorgu formülasyonunu karmaşıklaştırır. Farklı bir şekilde formüle etmek için: bir veritabanı veya sorgu tasarlarken, tasarımcının, sorgu optimizerinin gerçekleştirmesi muhtemel eylemlerin eylemlerini ve sırasını bilmesi gerekir. Deneyimli bir mühendis, büyük veritabanı satıcıları tarafından kullanılan sezgisel bilgiler hakkında bilgiye ihtiyaç duyar.

Yapılandırma dosyaları bildirim amaçlıdır ancak belirli yapılandırmaları bildirmek zordur. Örneğin, özellikleri düzgün bir şekilde yapılandırmak için, sürüm oluşturma, dağıtım (ve dağıtım geçmişi), olası manuel geçersiz kılmalar ve diğer ayarlarla olası çakışmalar göz önünde bulundurulmalıdır. Bir konfigürasyonu doğru bir şekilde doğrulamak NP-problemi haline gelebilir.

Sonuç, bu komplikasyonların yeni başlayanları şaşırttığı, bildirimsel programlamanın 'güzelliğini' kırdığı ve bazı mühendislerin başka çözümler aramasına neden olduğu. Deneyimsiz mühendislerin SQL'den NoSQL'e geçişi, ilişkisel veritabanlarının altında yatan karmaşıklıklar tarafından tetiklenmiş olabilir.


2
"Olumsuz CSS sınıfları bilerek NP tamamlanmamış sorunlar nedeniyle dile eklenmedi" - detaylandırır mısın?
John Dvorak

Bu bir alıştırmadır, ancak negatif CSS seçicileri ile bunları, bir eşleşip eşleşmediğini görmek için tüm olası kombinasyonları denemeyi gerektiren 3SAT problemine (son cümlesi DOM olan) yeniden yazmak mümkündür.
Dibbeke

1
Küçük ekleme CSS 3 ve 4'te, negatif seçicilere izin verilir, ancak: sözde sınıflar yuvalanamayabilir.
Dibbeke

2

Dijital mantığın doğrulanmasında iyi kullanılmaya başlanan programlama dillerinin bildirilmesinde farklılık var .

Normal olarak dijital mantık, kayıtlar arasındaki sinyallerin mantık seviyesinin tanımlandığı kayıt aktarma seviyesinde (RTL) açıklanmaktadır . Daha soyut ve bildirimsel bir şekilde tanımlanan özellikleri giderek daha fazla eklediğimizi kontrol etmek için.

Daha fazla bildirim sağlayan dil / dil altkümelerinden birine, Özellik Belirtme Dili için PSL denir . Bir çarpanın bir RTL modelini test ederken , örneğin tüm kayma mantık işlemlerinin ve birden fazla saat döngüsü eklenmesi gerektiğinin belirtilmesi gerekir; şeklinde bir özellik yazabilirsiniz assert that when enable is high, this output will equal the multiplication of these two inputs after no more than 8 clock cycles. PSL açıklaması daha sonra bir simülasyonda RTL ile birlikte kontrol edilebilir veya PSL'nin RTL açıklaması için geçerli olduğu kanıtlanmıştır.

Daha açıklayıcı olan PSL modeli, birini RTL açıklamasıyla aynı davranışı tanımlamaya zorlar, ancak kabul edip etmediklerini görmek için RTL'ye göre otomatik olarak kontrol edilebilecek yeterince farklı bir şekilde zorlar.


1

Çoğunlukla sorun, verileri nasıl modellediğinizdir; ve bildirimsel programlama burada yardımcı olmuyor. Zorunlu dillerde, sizin için çok şey yapan tonlarca kütüphaneniz var, bu yüzden ne arayacağınızı bilmeniz yeterli. Belirli bir şekilde kimse bu bildirime programlama (muhtemelen bunun için en iyi örnektir düşünebilirsiniz Akış API içinde Java 8 ). Buna sahip, soyutlama zaten çözülmüş ve bildirimsel programlama gerekli değildir.

Ayrıca, söylendiği gibi, mantık programlama dilleri zaten tam olarak istediğiniz şeyi yapar. Birisi sorunun performans olduğunu söyleyebilir, ancak günümüzün bu alandaki donanım ve araştırmasıyla üretim kullanımına hazır olması için işler iyileştirilebilir; aslında Prolog AI işleri için kullanılıyor, ama ben sadece akademi tarafından inanıyorum.

Genel amaçlı programlama dilleri için geçerli olduğuna dikkat edilmelidir. Etki alanına özgü diller için, bildirim dilleri çok daha iyidir; SQL muhtemelen en iyi örnektir.


3
Veri modellemesi? Zorunlulukların en kötü olduğu şeyi seçtin. Haskell ve ML gibi bildirimsel işlevsel diller veri modellemede mükemmeldir. Cebirsel veri tipleri ve özyinelemeli veri tipleri, örneğin, genellikle bir veya iki satırda kapsamlı bir şekilde tanımlanabilir. Tabii ki, hala yazmak için işlevleriniz var ama kodları tür tanımından kaçınılmaz olarak geliyor ve onun tarafından sınırlandırılıyor. Tuhaf karşılaştırma yapmak.
15'de

1
@ itsbruce Önemli olan, gerçek verilerin ADT'ye kolayca eşleştirilemediği; Çoğu veritabanının nasıl çalıştığını düşünün. Prolog - Erlang olarak haklısın, onlar farklı diller. Birinin işlevsel, diğeri mantıklı olsa da, karşılaştırmanın tamamını silersem en iyisi olduğunu söyledim.
m3th0dman

1
@ m3th0dman Bir veritabanı sadece bir ton tote / kayıttır. Haskell orada biraz sakatlandı, çünkü kayıtlardan yoksun, ama tekilleri var ve ML'nin ikisi de var. Ve Haskell'in durumunda, yeni bir sahte kayıt veri tipini bildirmek için gereken kazan plakası miktarı, ortalama olarak yazılmış tipik OOP dilinde sahte bir yapı oluşturmak için gereken miktardan çok daha küçüktür. Verilerin çoğunun ADT'lerle kolayca eşleştirilemediğini açıklayabilir misiniz?
Doval

1
@ m3th0dman Ah, bu yüzden veritabanı şemaları bu göreve uygun olan zorunlu bir dilde tanımlanmıştır. Oh, hayır, bu bildirimsel DDL'ler olurdu. Aslında, veri modellemenin genel süreci, onunla çalışacak olan uygulama ile ilgilidir, veri akışı ve yapılanmalar, uygulamayı uygulayan dille değil. Bazen bunlar bir dilin OO özellikleriyle ve ORM'nin desteklediği şeylerle eşleşecek şekilde bozulur, ancak bu bir özellik değil, genellikle kötü bir şeydir. Bilgilendirici diller kavramsal / mantıksal veri modelini ifade etmek için daha uygundur.
15'te

1
@ itsbruce Prosedürel paradigmanın veri tanımlamadaki beyandan daha iyi olduğunu söylemedim; Bildirici paradigmanın, usule nazaran (genel amaçlı diller için) daha iyi (daha kötü değil) olduğunu söyledim. Verileri değiştirmek için SQL'in bildirimsel kısmı gerçek hayattaki uygulamalar için yeterli değildir; Aksi takdirde hiç kimse prosedürel uzantıları icat edip kullanmazdı. Makaleye gelince, Brooks'la çelişkili olduğu özetinden onunla aynı fikirde değilim; fikirlerini gerçek projelerden inşa ederken, bu adamlar teorilerini kanıtlamak için olağanüstü bir şey inşa etmediler.
m3th0dman,

0

Böyle bir şeye benzeyebilir .. {(whatever => bir dosyayı oku ve bir url çağır) | bir url çağırın ve bir dosyayı okuyun} Ancak, bunlar yürütülecek eylemlerdir ve sistemin durumu sonuç olarak değişir, ancak bu kaynaktan belli değildir.

Declaratives, sonlu bir durum makinesini ve geçişlerini tanımlayabilir. FSM, tek eylem durumu bir sonraki duruma değiştirmek olsa bile, eylemsiz bildirimlerin tam tersi gibidir.

Bu yöntemi kullanmanın avantajı, geçişlerin ve eylemlerin yalnızca bir tane yerine birden çok geçiş için geçerli olan tahminlerle belirtilebilmesidir.

Kulağa biraz garip geldiğini biliyorum, ancak 2008'de bu yöntemi kullanan bir program oluşturucu yazdım ve üretilen C ++ kaynak kadar 2 ila 15 kat daha fazla. Artık 20.000 satırlık girdiden 75.000'den fazla C ++ satırına sahibim. İki şey bununla gider: tutarlılık ve bütünlük.

Tutarlılık: Aynı anda doğru olabilecek hiçbir iki tahmin, hem x = 8 hem de x = 9 gibi ne de sonraki durumlarda olduğu gibi tutarsız eylemler anlamına gelmez.

Tamlık: Her durum geçişi için mantık belirtilmiştir. Bunların,> 2 ** N durumları olan, N toprak sistemli sistemleri kontrol etmesi zor olabilir, ancak her şeyi doğrulayabilecek ilginç kombinasyon yöntemleri vardır. 1962'de, bu tür koşullu kod üretme ve birleştirici hata ayıklamayı kullanarak, 7070 makineleri için bir sistem dizisinin 1. aşamasını yazdım. Sıralamadaki 8.000 satırdan, ilk sürümden sonsuza dek çıkan böcek sayısı sıfırdı!

İkinci aşamada, 12.000 satırdan oluşan ikinci faz, ilk iki ayda 60'tan fazla hata yaptı. Bu konuda söylenecek daha çok şey var, ama işe yarıyor. Eğer araç üreticileri bu yazılımı firmware'i kontrol etmek için kullanmışlarsa, şimdi gördüğümüz arızaları görmeyiz.


1
Bu gerçekten asıl soruya cevap vermiyor. Tutarlılık ve bütünlük, çoğu programlamanın hala usule dayalı, bildirimsel değil gerçeğini nasıl etkiler?
Jay Elston

Açılış paragrafınız, arnaud'un cevap programındaki bir noktaya cevap gibi görünüyor , soruyu kendisi değil, programcılar.stackexchange.com/ a/275839/67057 . Orada bir yorum olmalı (ekranımda, cevabınız artık bir şeyin altında değil). Ben düşünüyorum senin cevabın kalan bildirim kod küçük bir miktar eşdeğer zorunluluk kod büyük miktarda üretmek nasıl bir resmidir ama net değil. Cevabınız, özellikle dikkat çeken noktalarla ilgili olarak, biraz toparlanma gerektiriyor.
saat

-3

Her şey bildirimsel bir şekilde temsil edilemez.

Genellikle, açıkça yürütme akışını kontrol etmek istersiniz

Örneğin, sözde kodu takip etme: if whatever read a file call an URL else call an URL write a file Bunu bildirimsel olarak nasıl temsil ederdiniz?

Tabii ki, muhtemelen yapmanın bazı egzotik yolları vardır. Gibi monads . Ancak bunlar genellikle hantal, karmaşık ve işlemsel bölümlerinden çok daha az sezgiseldir.

Hepsi senin ortamla "etkileşim" / sistem olmasından aşağı kaynar değil bildirim. G / Ç ile ilgili her şey özünde prosedüreldir. Tam olarak ne ve ne olması gerektiğini ve hangi sırayla söylemelisiniz.

Bildirim, yalnızca hesaplama ile ilgili olan her şey için mükemmeldir. Dev bir fonksiyon gibi, X'i de içine koyar ve Y'yi alırsın. Bu harika. Bunun bir örneği HTML, giriş metin, çıktı ise tarayıcınızda gördüğünüz şeydir.


2
Bunu satın almıyorum. Örnek olarak neden beyanda bulunmuyor ? Bu, if/ else, hangi durumda bildirimsel bir alternatife benzeyecek? Kesinlikle read/ write/ callkısımları değil, çünkü bunlar güzel bir şekilde tanımlayıcı değer listeleridirler (sarıldıklarını ima ediyorsanız {...; ...}, neden sarıldıklarını ima etmiyorsunuz [..., ...]?) Elbette, liste sadece ücretsiz monoidlerdir; diğerleri de yapardı. Burada monadların neden alakalı olduğunu anlamıyorum; onlar sadece bir API. Haskell, akışlardan -> monadlardan geçti ve manuel kompozisyona yardımcı oldu, ancak mantık dilleri listeleri otomatik olarak sırayla oluşturabilirdi.
Warbo

2
Sadece Monad'lar için -1. 1. Gerçekten egzotik değiller (listeler ve setler Monad'lar ve herkes bunları kullanıyor). 2. Onlar (Haskell belirli bir sırayla yapılacak şeyler zorlayarak ile ilgisi olmayan yapmak notasyonu görünüyor imperative ama değil). Bildirimsel / işlevsel diller, ilişkileri ve bağımlılıkları belirtir. Eğer X fonksiyonu Y girişine ihtiyaç duyuyorsa, X'ten önce Y üretilecektir. Bağımlılıkları doğru alın ve uygun olay dizisi kendini tanımlayacaktır. Çok fazla etkileşim olayı yönlendirir, bir set dizide değil. Bilgilendirici diller olaylara tepki vermeyi zorlaştırmaz.
saat

Tembellik bunlardan bazılarını zorlaştırır, ancak tembellik, çoğu onu kullanmayan, Declarative dillerin tanımının bir parçası değildir. Ve bunu yapanlarda, değerlendirmeyi garanti etmenin yolunun monadlarla bir ilgisi yok. Bilgilendirici bir dilin soyut hesaplama yerine sadece etkileşim için kullanıldığı bir örnek için düzen belirtilmez, ancak doğru şeylerin sırayla yapıldığından emin olun, Puppet DSL'den başka bir yere bakmayın. Sadece gerekli şeylerin gerçekleştiği bonusu vardır - zorunlu diller kolay değildir.
saat

1
@ İtsbruce örneğine ek olarak, reaktif programlama bildirimde bulunur ve çevre ile etkileşim hakkındadır.
Maciej Piechotka
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.