İşlevsel, bildirimsel ve zorunlu programlama terimleri ne anlama geliyor?
İşlevsel, bildirimsel ve zorunlu programlama terimleri ne anlama geliyor?
Yanıtlar:
Bunu yazarken, bu sayfada en çok oy alan cevaplar kesin değildir ve Wikipedia'dan alıntı yapan cevap da dahil olmak üzere bildirici ile zorunlu tanım arasında karıştırılır. Bazı cevaplar terimleri farklı şekillerde karıştırmaktadır.
Formüllerin hücreleri mutasyona uğratmasına bakılmaksızın, elektronik tablo programlamanın neden bildirici olduğunu açıkladığım açıklamalara da bakın .
Ayrıca, bazı cevaplar işlevsel programlamanın bir bildirim alt kümesi olması gerektiğini iddia etmektedir. Bu noktada, "işlev" i "yordam" dan ayırıp ayırmamamıza bağlıdır. Öncelikle zorunlu ve deklaratifi ele alalım.
Deklaratif ifadenin tanımı
Sadece muhtemelen bir ayırt edebilir nitelik deklaratif bir ifadeyi şart ifadesinin alt ifadelerin referans şeffaflık (RT) 'dir. Diğer tüm özellikler ya her iki ifade türü arasında paylaşılır ya da RT'den türetilir.
% 100 bildirici bir dil (diğer bir deyişle her olası ifadenin RT olduğu dil) (diğer RT gereksinimleri arasında) depolanan değerlerin, örneğin HTML'nin ve Haskell'in çoğunun mutasyonuna izin vermez.
RT ifadesinin tanımı
RT'ye genellikle "yan etkisi yoktur" denir. Etkiler teriminin kesin bir tanımı yoktur, bu nedenle bazı insanlar "hiçbir yan etkinin" RT ile aynı olmadığı konusunda hemfikir değildir. RT'nin kesin bir tanımı vardır .
Her alt ifade bir işlev çağrısı kavramsal olduğundan, RT ise değişken durumuna erişmek olmayabilir bir işlev (denilen işlevi içinde yani ifade (ler)) uygulanması gerektirir dış işlevine (erişen değişebilir yerel devlet olduğunu izin verilir). Basitçe söylemek gerekirse, işlev (uygulama) saf olmalıdır .
Saf fonksiyonun tanımı
Saf bir işlevin genellikle "yan etkisi olmadığı" söylenir. Etkiler teriminin kesin bir tanımı yoktur, bu nedenle bazı insanlar aynı fikirde değildir.
Saf işlevler aşağıdaki özelliklere sahiptir.
RT'nin ifadelere (fonksiyon çağrılarını içeren) ve saflığın fonksiyonlara (uygulamalarına) uygulandığını unutmayın.
RT ifadeleri yapan saf olmayan işlevlerin belirsiz bir örneği eşzamanlılıktır, ancak bunun nedeni, kesme soyutlama katmanında saflığın kırılmasıdır. Bunu gerçekten bilmenize gerek yok. RT ifadeleri yapmak için saf işlevleri çağırırsınız.
RT'nin türev özellikleri
Deklaratif programlama için atıfta bulunulan diğer herhangi bir özellik, örneğin Wikipedia tarafından kullanılan 1999'dan yapılan alıntı RT'den türetilir veya zorunlu programlama ile paylaşılır. Böylece kesin tanımımın doğru olduğunu kanıtlıyorum.
Dış değerlerin değişmezliği RT gereksinimlerinin bir alt kümesidir.
Bildirime diller örneğin kontrol yapıları, döngü yok for
ve while
çünkü nedeniyle değişmezlik için döngü koşulu değişim asla.
Bildirimli diller iç içe geçmiş işlev sırası (mantıksal bağımlılıklar olarak da bilinir) dışında kontrol akışını ifade etmez, çünkü değişmezlik nedeniyle diğer değerlendirme sırası seçenekleri sonucu değiştirmez (aşağıya bakın).
Bildirici diller mantıksal "adımları" (yani iç içe RT işlev çağrısı sırasını) ifade eder, ancak her işlev çağrısının daha yüksek düzeyde bir anlamsal olup olmadığı (yani "ne yapmalı") bildirimsel programlama için bir gereklilik değildir. Zorunluluktan farklı olan , değişmezlik (yani daha genel olarak RT) nedeniyle, bu "adımlar" değişebilir duruma, sadece ifade edilen mantığın ilişkisel sırasına (yani fonksiyon çağrılarının iç içe geçme sırasına, yani alt ifadelere) bağlı olmamasıdır. ).
Örneğin, HTML paragrafı <p>
, paragraftaki alt ifadeler (yani etiketler) değerlendirilene kadar görüntülenemez. Değişken bir durum yoktur, yalnızca etiket hiyerarşisinin mantıksal ilişkisi ( benzer şekilde iç içe işlev çağrıları olan alt ifadelerin iç içe yerleştirilmesi ) nedeniyle bir sipariş bağımlılığı vardır .
Böylece değişmezlik türevi özniteliği (daha genel olarak, RT) bildirime ifadeler, ifade ettiği, orada sadece mantıksal bir parçasına ait ilişkileri (örn alt sentezleme foksiyon argümanları) olup kesilebilir durum ilişkileri.
Değerlendirme sırası
Alt ifadelerin değerlendirme sırasının seçimi, ancak işlev çağrılarından herhangi biri RT olmadığında (yani işlev saf değilse), örneğin işlev içinde harici bir değişken duruma erişildiğinde değişken bir sonuç verebilir.
Örneğin, bazı iç içe ifadeler, örneğin verilen f( g(a, b), h(c, d) )
fonksiyonlar eğer, fonksiyon argümanları istekli ve tembel değerlendirme aynı sonuçları verecektir f
, g
ve h
saftır.
Oysa, işlevler f
, g
ve h
saf değilse, değerlendirme sırası seçimi farklı bir sonuç verebilir.
Not, iç içe ifadeler kavramsal olarak iç içe işlevlerdir, çünkü ifade işleçleri yalnızca tekli önek, tekli postfix veya ikili infix gösterimi gibi görünen işlev çağrılarıdır.
Tüm tanımlayıcılar, örneğin eğer teğetsel a
, b
, c
, d
, olup değişmez her program için dış durumu (yani I / O) erişilemez ve bir ayırma katmanı kırılması yoktur, o zaman fonksiyonları her zaman saftır.
Bu arada, Haskell'in farklı bir sözdizimi var f (g a b) (h c d)
.
Değerlendirme siparişi ayrıntıları
İşlev, girdiden çıktıya durum geçişidir (değiştirilebilir depolanmış değer değil). Saf işlevlere yapılan çağrıların RT kompozisyonları için , bu durum geçişlerinin yürütme sırası bağımsızdır. Her bir işlev çağrısının durum geçişi, yan etkilerin olmaması ve bir RT işlevinin önbelleğe alınmış değeri ile değiştirilebileceği ilkesi nedeniyle diğerlerinden bağımsızdır . İçin bir yanlış doğru , saf monadik bileşimdir zaman bildirim ve RT Haskell'ın gerçeğine rağmen, IO
tek hücreli bir belki saf olmayan ve bu nedenle zorunlu wrt World
programına dış durum (ancak aşağıda uyarı anlamında, yan etkiler izole edilir).
İstekli değerlendirme, işlev bağımsız değişkenleri işlev çağrılmadan önce değerlendirilir ve tembel değerlendirme, bağımsız değişkenlerin işlev içinde erişilinceye kadar (ve değilse) değerlendirilmediği anlamına gelir .
Tanım : işlev parametreleri işlev tanımlama sitesinde bildirilir ve işlev bağımsız değişkenleri işlev çağrı sitesinde sağlanır. Parametre ve argüman arasındaki farkı bilir .
Kavramsal olarak, tüm ifadeler işlev çağrılarıdır (örn. Sabitler girdi içermeyen işlevlerdir, tekli işleçler bir girdili işlevlerdir, ikili infix işleçleri iki girdili işlevlerdir, yapıcılar işlevlerdir ve hatta denetim deyimleri (ör if
. for
, while
) fonksiyonlarla modellenebilir. Bu o düzenin argümanı değerlendirilir fonksiyonları (iç içe işlev çağrısı sipariş ile değil şaşırtmak yapmak) örneğin sözdizimi tarafından bildirilmedi f( g() )
heyecanla değerlendirilebilir g
sonra f
üzerinde g
'in sonucu veya değerlendirilebilir f
ve sadece tembel değerlendirmek g
onun sonucu olan ihtiyaç olduğunda f
.
Dikkat, Turing tam dili (yani sınırsız özyinelemeye izin veren) mükemmel bir şekilde beyan edicidir, örneğin tembel değerlendirme bellek ve zaman belirsizliğini ortaya çıkarır. Ancak değerlendirme sırasının seçiminden kaynaklanan bu yan etkiler bellek tüketimi, yürütme süresi, gecikme, sonlandırma ve harici histerezis ile sınırlıdır, bu nedenle harici senkronizasyon ile sınırlıdır .
Fonksiyonel programlama
Deklaratif programlama döngülere sahip olamadığından, yinelemenin tek yolu işlevsel özyinelemedir. Bu anlamda fonksiyonel programlama deklaratif programlama ile ilgilidir.
Ancak fonksiyonel programlama, bildirimsel programlama ile sınırlı değildir . Fonksiyonel kompozisyon, alt tiplerle kontrastlanabilir , özellikle Ekspresyon Sorunu ile ilgili olarak, uzatma ya alt tipler eklenerek veya fonksiyonel ayrışma ile sağlanabilir . Genişletme her iki metodolojinin bir karışımı olabilir .
İşlevsel programlama genellikle işlevi birinci sınıf bir nesne yapar, yani işlev türü dilbilgisinde başka herhangi bir türün olabileceği herhangi bir yerde görünebilir. Sonuç, fonksiyonların fonksiyonlara girebilmesi ve çalışabilmesi, böylece fonksiyon kompozisyonunu vurgulayarak endişelerin ayrılmasını sağlaması, yani deterministik bir hesaplamanın alt hesaplamaları arasındaki bağımlılıkları ayırmasıdır.
Örneğin, bir koleksiyonun her öğesine uygulanabilecek sonsuz sayıda olası özel eylemin her biri için ayrı bir işlev yazmak (ve işlev de bildirici olması gerekiyorsa döngüler yerine özyineleme kullanmak yerine) yerine, işlevsel programlama yeniden kullanılabilir yineleme kullanır fonksiyonlar, örneğin map
, fold
, filter
. Bu yineleme işlevleri, birinci sınıf özel eylem işlevini girer. Bu yineleme işlevleri koleksiyonu yineler ve her öğe için girdi özel eylem işlevini çağırır. Bu eylem işlevleri daha özlüdür, çünkü artık koleksiyonu yinelemek için döngü ifadelerini içermelerine gerek yoktur.
Ancak, bir işlev saf değilse, o zaman gerçekten bir prosedür olduğunu unutmayın. Belki de saf olmayan fonksiyonlar kullanan fonksiyonel programlamanın gerçekten prosedürel programlama olduğunu söyleyebiliriz. Dolayısıyla, bildirici ifadelerin RT olduğunu kabul edersek, prosedürel programlamanın bildirici programlama olmadığını söyleyebiliriz ve bu nedenle fonksiyonel programlamanın her zaman RT olduğunu ve bildirici programlamanın bir alt kümesi olması gerektiğini söyleyebiliriz.
paralellik
Birinci sınıf fonksiyonlara sahip bu fonksiyonel kompozisyon , bağımsız fonksiyonu ayırarak paralellikteki derinliği ifade edebilir .
Brent Prensibi: çalışma w ve derinlik d ile hesaplama, O zamanında bir p-işlemci PRAM'de (maks (w / p, d)) uygulanabilir.
Hem eşzamanlılık hem de paralellik , bildirimsel programlama gerektirir , yani değişmezlik ve RT.
Peki Paralellik == Eşzamanlılığın bu tehlikeli varsayımı nereden geldi? Bu, yan etkileri olan dillerin doğal bir sonucudur: dilinizin her yerde yan etkileri olduğunda, her seferinde birden fazla şey yapmaya çalıştığınızda, esasen her işlemden efektlerin araya girmesinden kaynaklanan belirleyici olmamanız gerekir. . Yani yan etkili dillerde, paralellik elde etmenin tek yolu eşzamanlılıktır; bu yüzden ikisinin de kapalı olduğunu görmemiz şaşırtıcı değil.
Değerlendirme sırasının ayrıca fonksiyonel kompozisyonun sona ermesini ve performans yan etkilerini de etkilediğini unutmayın.
Istekli (CBV) ve tembel (CBN) kategorik düellolardır [ 10 ], çünkü değerlendirme sırasını tersine çevirmişlerdir, yani sırasıyla sırasıyla dış veya iç fonksiyonların değerlendirilip değerlendirilmediği. Baş aşağı bir ağaç hayal edin, sonra işlev ağacı dalı ipuçlarından dal hiyerarşisini en üst düzey işlev gövdesine kadar değerlendirmek istekli; tembel, bagajdan dalın uçlarına kadar değerlendirir. Eager, konjonktif ürünlere ("ve", a / k / kategorik "ürünler") sahip değildir ve tembel, ayrışan ürünlere ("veya", a / k / a kategorik "toplamlar") sahip değildir [ 11 ].
Verim
İstekli
Sonlandırılmada olduğu gibi, istekli, konjonktif fonksiyonel kompozisyonla çok istekli, yani kompozisyon kontrol yapısı tembel ile yapılmayan gereksiz işleri yapar. İçin , örneğin , istekli heyecanla ve gereksiz bir kat ile meydana geldiği zaman, Boolean için tüm listesini haritalar ilk gerçek eleman üzerine sonlandırır.
Bu gereksiz çalışma , her ikisi de saf fonksiyonlarla istekli ve tembelin ardışık zaman karmaşıklığında "en fazla" talep edilen ekstra bir giriş faktörünün nedenidir . Bir çözüm, tembel kurucularla (yani isteğe bağlı tembel ürünlerle istekli) functorları (örneğin listeler) kullanmaktır, çünkü istekli olarak heveslilik yanlışlığı iç fonksiyondan kaynaklanır. Bunun nedeni ürünlerin yapıcı tipler olması, yani başlangıçtaki sabitleme noktasında başlangıç cebiri olan endüktif tiplerdir [ 11 ]
Tembel
Sonlandırılmada olduğu gibi tembel, ayrık fonksiyonel kompozisyonla çok tembeldir, yani koindüktif nihailık gerekenden daha sonra ortaya çıkabilir, bu da hem gereksiz çalışmaya hem de istekli olmayan gecikmenin belirlenememesine neden olur [ 10 ] [ 11 ] . Kesinlik örnekleri, durum, zamanlama, fesih ve çalışma zamanı istisnalarıdır. Bunlar zorunlu yan etkilerdir, ancak saf bir bildirici dilde (örneğin Haskell) bile, zorunlu IO monadında durum vardır (not: tüm monadlar zorunlu değildir!) Uzay tahsisinde örtüktür ve zamanlama zorunludur gerçek dünya. İsteğe bağlı istekli kopeklerle bile tembel kullanmak iç temliklere "tembellik" sızıntısı yapar, çünkü tembellikte tembellik yanlışlığı dış fonksiyondan kaynaklanır(Sonlandırma Yok bölümündeki örneğe bakın; burada == bir dış ikili işleç işlevidir). Bunun nedeni, kopyantların nihailık, yani son bir nesne üzerinde son bir cebir içeren koindüktif tipler ile sınırlanmış olmasıdır [ 11 ].
Tembel , beyan edilen fonksiyon hiyerarşisi ve çalışma zamanı değerlendirme sırası arasındaki uyumsuzluk nedeniyle, hata ayıklaması muhtemelen programcıların çoğunun yeteneklerinin ötesinde olan gecikme ve alan için işlevlerin tasarımında ve hata ayıklamasında belirsizliğe neden olur . İstekli olarak değerlendirilen tembel saf fonksiyonlar, potansiyel olarak daha önce görülmemiş bir sonlandırmayı çalışma zamanında getirebilir. Tersine, tembel olarak değerlendirilen istekli saf işlevler, çalışma zamanında daha önce görülmemiş alan ve gecikme belirsizliğini ortaya çıkarabilir.
Sigara sonlandırma
Derleme zamanında, Durma sorunu ve Turing tam dilinde karşılıklı özyineleme nedeniyle, işlevlerin genellikle sonlandırılacağı garanti edilemez.
İstekli
İstekli fakat tembel değilken, Head
"ve" birleşimi için, Tail
ya sona eriyor ya Head
da Tail
sona ermiyorsa, sırasıyla ya List( Head(), Tail() ).tail == Tail()
ya List( Head(), Tail() ).head == Head()
doğru değildir, çünkü sol taraf sona ermez ve sağ taraf sona ermez.
Oysa tembel bir şekilde her iki taraf da sona eriyor. Bu nedenle, konjonktif ürünlerle istekli değildir ve gerekli olmadığı durumlarda sonlandırılmaz (çalışma zamanı istisnaları dahil).
Tembel
Tembel ama istekli değil, 1
"veya" nin ayrılması için 2
, eğer f
bitmezse, o zaman List( f ? 1 : 2, 3 ).tail == (f ? List( 1, 3 ) : List( 2, 3 )).tail
doğru değildir , çünkü sol taraf sona erer ve sağ taraf gitmez.
Oysa, her iki taraf da iki tarafın da bitmediği için eşitlik testine asla ulaşılamaz. Bu nedenle tembel, ayrışan kopyalarla çok tembeldir ve bu durumlarda, istekli olandan daha fazla iş yaptıktan sonra (çalışma zamanı istisnaları dahil) sona ermez.
[ 10 ] Deklaratif Sürdürmeler ve Kategorik Dualite, Filinski, bölüm 2.5.4 CBV ve CBN ve SCL'de 3.6.1 CBV ve CBN karşılaştırması.
[ 11 ] Deklaratif Sürdürmeler ve Kategorik Dualite, Filinski, bölüm 2.2.1 Ürünler ve eşyalar, 2.2.2 Terminal ve başlangıç nesneleri, tembel ürünlerle 2.5.2 CBV ve istekli eşyalar ile 2.5.3 CBN.
Bunlar için gerçekten belirsiz, nesnel bir tanım yoktur. Burada nasıl ben onları tanımlarsınız:
Zorunlu - Odak, bilgisayarın ne yapacağından ziyade bilgisayarın hangi adımları atması gerektiğidir (örn. C, C ++, Java).
Bildirici - Odak, bilgisayarın nasıl olması gerektiği yerine ne yapması gerektiğidir (örn. SQL).
İşlevsel - özyinelemeye yoğun odaklanan bildirim dillerinin bir alt kümesi
zorunluluk ve beyan edici , iki karşıt programlama tarzını tanımlar. zorunlu "geleneksel adım adım tarifi" yaklaşımı açıklayıcı ise daha fazla "istediğim budur, şimdi bunu nasıl yapacağınızı anlıyorsunuz".
bu iki yaklaşım programlama boyunca gerçekleşir - aynı dil ve aynı programla bile. genellikle bildirimsel yaklaşım tercih edilir olarak kabul edilir, çünkü programcıyı çok fazla ayrıntı belirtmek zorunda bırakmaz, aynı zamanda hatalar için daha az şansa sahiptir (istediğiniz sonucu açıklarsanız ve bazı iyi test edilmiş otomatik süreç bundan geriye doğru çalışabilir) adımları tanımlayın, her şeyin elle belirtilmesi gerekenden daha güvenilir olduğunu umabilirsiniz).
Öte yandan, zorunlu bir yaklaşım size daha düşük seviye kontrolü sağlar - programlama için "mikromanager yaklaşımı" dır. ve bu programcının sorun hakkında daha etkin bir cevap verebilmesi için bilgiden faydalanmasını sağlayabilir. bu nedenle bir programın bazı bölümlerinin daha bildirimsel bir tarzda yazılması olağandışı değil, hız açısından kritik bölümlerin daha zorunlu olması.
Tahmin edebileceğiniz gibi, bir program yazmak için kullandığınız dil ne kadar bildirimsel olabileceğinizi etkiler - sonucun açıklaması verildiğinde ne yapacağınızı öğrenmek için yerleşik "akıllı" bir dil çok daha bildirimsel bir izin verecektir daha yüksek bir katman oluşturmak için önce programcının bu tür istihbaratı zorunlu kodla eklemesi gereken bir yaklaşımdan daha fazla yaklaşır. bu nedenle, örneğin, prolog gibi bir dil çok açıklayıcı olarak kabul edilir, çünkü yerleşik, cevapları arayan bir sürece sahiptir.
şimdiye kadar, fonksiyonel programlama bahsetmedim fark edeceksiniz . bunun anlamı, diğer ikisi ile hemen ilişkisi olmayan bir terimdir. en basit, fonksiyonel programlama, fonksiyonları kullandığınız anlamına gelir. özellikle, işlevleri "birinci sınıf değerleri" olarak destekleyen bir dil kullandığınız anlamına gelir; bu, yalnızca işlevler yazmanın yanı sıra işlevler (işlevler yazan ...) ve işlevleri ileten işlevler de yazabileceğiniz anlamına gelir. fonksiyonlar. Kısacası - bu işlevler dize ve sayı gibi esnek ve yaygındır.
o zaman, işlevsel, zorunlu ve beyan edici sıklıkla birlikte bahsedilmesi garip gelebilir. bunun nedeni fonksiyonel programlama fikrini "aşırıya çıkarmak" sonucudur. bir fonksiyon, en saf anlamıyla, matematikten bir şeydir - bir miktar girdi alan ve her zaman aynı çıktıyı veren bir tür "kara kutu". ve bu tür davranışlar değişen değişkenlerin saklanmasını gerektirmez. bu nedenle amacı, çok saf, matematiksel olarak etkilenmiş bir fonksiyonel programlama fikri uygulamak olan bir programlama dili tasarlarsanız, büyük ölçüde değişebilecek değerler fikrini (belirli, sınırlı, teknik anlamda) reddedersiniz.
ve bunu yaparsanız - değişkenlerin nasıl değişebileceğini sınırlarsanız - o zaman neredeyse kazara programcıyı daha beyan edici programlar yazmaya zorlarsınız, çünkü zorunlu programlamanın büyük bir kısmı değişkenlerin nasıl değiştiğini açıklar ve artık yapamazsınız. yap bunu! dolayısıyla fonksiyonel programlamanın - özellikle de işlevsel bir dilde programlama - daha bildirimsel kod verme eğiliminde olduğu ortaya çıkıyor.
özetlemek gerekirse:
zorunlu ve bildirici iki karşıt programlama stilidir (aynı stilleri bu stilleri teşvik eden programlama dilleri için kullanılır)
fonksiyonel programlama, fonksiyonların çok önemli hale geldiği ve sonuç olarak değişen değerlerin daha az önem kazandığı bir programlama tarzıdır. değerlerde değişiklik belirleme yeteneği daha bildirimsel bir stil gerektirir.
dolayısıyla "işlevsel programlama" genellikle "bildirimsel" olarak tanımlanır.
Kısaca:
Bir zorunluluk dil sırayla bilgisayar yürütür (daha sonra bunu yapın) o bir dizi talimat specfies.
Bir bildirime dil çıkışları hangi girişler (örn. Eğer A varsa, o zaman sonuç B) neden gerektiği hakkında bir dizi kural beyan eder. Bir motor bu kuralları girişlere uygular ve bir çıkış verir.
Bir işlevsel dil giriş çıkış tercüme şeklini belirlemek matematiksel / mantıksal işlevleri kümesi bildirir. Örneğin. f (y) = y * y. bir tür bildirici dildir.
Emir Kipi: hedefimize nasıl ulaşılır
Take the next customer from a list.
If the customer lives in Spain, show their details.
If there are more customers in the list, go to the beginning
Beyan: Neyi başarmak istiyoruz
Show customer details of every customer living in Spain
Zorunlu Programlama , programınızın bir bilgisayar tarafından gerçekleştirilen işlemlerin nasıl gerçekleşeceğini açıklayan talimatlardan yapılandırıldığı herhangi bir programlama stili anlamına gelir .
Bildirici Programlama , programınızın sorunun ya da çözümün açıklaması olduğu, ancak işin nasıl yapılacağını açıkça belirtmediği herhangi bir programlama stili anlamına gelir .
Fonksiyonel Programlama fonksiyonların fonksiyonlarını ve fonksiyonlarını değerlendirerek programlamadır ... Fonksiyonel programlama (kesin olarak tanımlandığı gibi) yan etkisiz matematiksel fonksiyonları tanımlayarak programlama anlamına gelir , bu yüzden bir deklaratif programlama şeklidir, ancak deklaratif programlamanın tek türü değildir. .
Mantık Programlama (örneğin Prolog'da), başka bir bildirim programlaması biçimidir. Mantıksal bir ifadenin doğru olup olmadığına (veya tatmin edilip edilemeyeceğine) karar vererek hesaplamayı içerir. Program genellikle bir dizi gerçek ve kuraldır - bir dizi talimattan ziyade bir açıklamadır.
Terim Yeniden Yazma (örneğin CASL), başka bir bildirim programlaması biçimidir. Cebirsel terimlerin sembolik dönüşümünü içerir. Mantık programlama ve fonksiyonel programlamadan tamamen farklıdır.
Emir Kipi - ifadeler, gerçekleştirilecek eylem dizisini tanımlar (çağrışımsal)
bildirim - ifadeler, programın davranışına katkıda bulunan bildirimlerdir (çağrışımsal, değişmeli, idempotent, monotonik)
fonksiyonel - ifadeler sadece etki olarak değer taşır; anlambilim denklem akıl yürütmeyi destekler
Önceki cevabımı yazdığım için, beyan edici özelliğin aşağıda belirtilen yeni bir tanımını formüle ettim . Ayrıca zorunlu programlamayı dual özellik olarak tanımladım.
Bu tanım önceki cevabımda verdiğim tanımdan daha üstündür, çünkü özlüdür ve daha geneldir. Ancak, grok yapmak daha zor olabilir, çünkü programlama ve genel olarak yaşam için geçerli olan eksiklik teoremlerinin imaları, insanların aklını sarması zordur.
Tanımın alıntı yapılan açıklaması, saf fonksiyonel programlamanın bildirimsel programlamada oynadığı rolü tartışmaktadır .
Tüm egzotik programlama türleri, aşağıdaki tanımlayıcı ve zorunluluk sınıflandırmalarına uymaktadır, çünkü aşağıdaki tanım bunların ikili olduğunu iddia etmektedir.
Beyan Edici ve Zorunlu
Bildirici özellik, genel ve belirsiz olmayan teknik olarak kesin bir tanımda tuhaf, geniş ve yakalanması zordur, çünkü istenmeyen yan etkilere yol açmadan programın anlamını (aka anlambilim) bildirebileceğimiz naif bir kavramdır. Anlamın ifadesi ile istenmeyen etkilerin önlenmesi arasında doğal bir gerilim vardır ve bu gerilim aslında programlamanın ve evrenimizin eksiklik teoremlerinden kaynaklanmaktadır .
Teknik olarak kesin olmayan basite indirgemek, ve aynı bildirim tanımlamak çoğu zaman belirsiz “ ne yapacağını ” olarak ve zorunlu “ nasıl yapılacağını ” . Bir belirsiz durum “ Ne olduğunu” “ nasıl ” bir programda o çıkışları da programlanabilen bir derleyici.
Açıkçası, bir dili Turing'i tamamlayan sınırsız özyineleme de benzer bir şekilde anlambilimdedir - yalnızca değerlendirmenin sözdizimsel yapısında değil (operasyonel anlambilim). Bu mantıksal olarak Gödel'in teoremine benzer bir örnektir - “ herhangi bir aksiyom sistemi de tutarsız ”. Bu alıntıdaki çelişkili tuhaflığı düşünün! Bu nedenle biz kanıtlayamayız, aynı zamanda anlam ekspresyonu kanıtlanabilir bağlı olmayan gösterilmiştir bir örnek 2 olduğu bir program (ve benzer şekilde kendi semantik) Sonlanma teoremi aka dur.
Eksiklik teoremleri, Termodinamiğin İkinci Kanununda belirtildiği gibi “ entropi (bağımsız olasılıklar # olarak da bilinir) sonsuza kadar en fazla eğilim gösteren evrenimizin temel doğasından kaynaklanır . Bir programın kodlaması ve tasarımı hiçbir zaman bitmez - canlıdır! - çünkü gerçek bir dünya ihtiyacını karşılamaya çalışır ve gerçek dünyanın anlambilimi her zaman daha fazla olasılıkla değişir ve eğilimlidir. İnsanlar asla yeni şeyler keşfetmeyi bırakmazlar (programlardaki hatalar dahil ;-).
Bu garip evrende kenarı olmayan (evrenimizin “dışında” olmadığını) düşünün, açıklanana kadar yanlış görünecek olan kısa ama aldatıcı-basit olmayan bir tanım gerektirir, bu yukarıda bahsedilen istenen kavramı kesin ve teknik olarak yakalamak için. derinden.
Tanım:
Bildirici özellik, her bir modüler semantiği ifade edebilecek sadece bir olası ifade kümesinin mevcut olduğu yerdir.
Zorunlu özellik 3 , anlambilimin bileşim altında tutarsız olduğu ve / veya ifade kümelerinin varyasyonlarıyla ifade edilebildiği ikili karakterdir.
Bu bildirim tanımı anlamsal kapsamda belirgin bir şekilde yereldir , yani modüler bir anlambilim, küresel kapsamda nerede ve nasıl somutlaştırıldığına ve nerede kullanıldığına bakılmaksızın tutarlı anlamını korumasını gerektirir . Böylece her bildirime modüler semantik tüm olası Başkalarıyla değil (dolayı eksiklik teoremleri kadar) bir imkansız özünde dik olmalıdır küresel ayrıca “nin noktasıdır tutarlılık, tanık için algoritma veya model Fazla her zaman daha iyi Robert Harper, Profesör tarafından” Standart ML tasarımcılarından Carnegie Mellon Üniversitesi'nde Bilgisayar Bilimleri Bölümü.
Bu modüler bildirimsel semantiklerin örnekleri arasında kategori teorisi işlevleri, örn .
Applicative
, Nominal yazım, ad alanları, adlandırılmış alanlar ve wrt, semantik operasyonel seviyesine ve daha sonra saf fonksiyonel programlamaya dahildir.Bu nedenle, iyi tasarlanmış beyan dilleri, ifade edilebilecek şeylerde bir miktar genellik kaybı olsa da, içsel tutarlılıkla ifade edilebilecek bir kazanç olsa da, anlamı daha açık bir şekilde ifade edebilir.
Yukarıda belirtilen tanımın bir örneği, bir e-tablo programının hücrelerindeki farklı sütun ve sıra hücrelerine taşındığında aynı anlamı vermesi beklenmeyen, yani hücre tanımlayıcıları gibi formül kümesidir. Hücre tanımlayıcıları, amaçlanan anlamın bir parçasıdır ve gereksiz değildir. Bu nedenle, her bir elektronik tablo sonucu, bir formül kümesindeki hücre tanımlayıcılarına benzersizdir. Bu durumda tutarlı modüler semantik, hücre formülleri için saf fonksiyonların giriş ve çıkışı olarak hücre tanımlayıcılarının kullanılmasıdır (aşağıya bakınız).
Hiper Metin İşaretleme Dili (diğer adıyla HTML) - statik web sayfalarının dili - (en azından HTML 5'ten önce) dinamik davranışı ifade etme yeteneği olmayan yüksek (ancak mükemmel bir şekilde 3 değil ) bildirici dile bir örnektir . HTML belki de öğrenmesi en kolay dildir. Dinamik davranış için, JavaScript gibi zorunlu bir komut dosyası dili genellikle HTML ile birleştirilir. Her nominal tür (yani etiketler) sözdizimi kuralları dahilinde kompozisyon altında tutarlı anlamını koruduğundan, JavaScript içermeyen HTML bildirim tanımına uyar.
Bildirici için rakip bir tanım , anlamsal ifadelerin değişmeli ve idempotent özellikleridir, yani ifadelerin anlamı değiştirilmeden yeniden sıralanabilir ve çoğaltılabilir. Örneğin, adlandırılmış alanlara değer atanan ifadeler, bu adlar herhangi bir zımni sıraya göre modüler ise, programın anlamı değiştirilmeden yeniden sıralanabilir ve çoğaltılabilir. İsimler bazen bir sipariş anlamına gelir, örneğin hücre tanımlayıcıları sütunlarını ve satır konumlarını içerir - toplamı e-tabloya taşımak anlamını değiştirir. Aksi takdirde, bu özellikler dolaylı olarak genelanlambilimin tutarlılığı. İfadelerin semantiklerini, rasgele sıralanmış veya çoğaltılmışsa tutarlı kalmaları için tasarlamak genellikle imkansızdır, çünkü düzen ve çoğaltma semantiğe özgüdür. Örneğin, “Foo var” (veya inşaat) ve “Foo yok” (ve yıkım) ifadeleri. Eğer kişi amaçlanan anlambilimin rastgele tutarsızlığını endimyasal olarak kabul ederse, bu tanım bildirici özellik için yeterince genel kabul edilir. Özünde bu tanım genelleştirilmiş bir tanım olarak anlamsızdır, çünkü anlambilime diklikle tutarlılık sağlamaya çalışır, yani anlambilim evreninin dinamik olarak sınırsız olduğu ve küresel bir tutarlılık paradigmasında yakalanamayacağı gerçeğini ortadan kaldırmaya çalışır .
Alt düzey operasyonel semantiğin değişmeli ve idempotent özelliklerine ihtiyaç duyulması, operasyonel semantiği bildirici yerelleştirilmiş modüler semantiğe dönüştürür, örneğin saf fonksiyonel programlama (zorunlu döngüler yerine özyineleme dahil). Daha sonra uygulama detaylarının operasyonel sırası , üst düzey anlambilimin tutarlılığını etkilemez (yani küresel olarak yayılır ). Örneğin, elektronik tablo formüllerinin değerlendirme sırası (ve teorik olarak da çoğaltılması) önemli değildir çünkü çıktılar, tüm çıktılar hesaplanana kadar, yani saf işlevlere benzer şekilde girdilere kopyalanmaz.
C, Java, C ++, C #, PHP ve JavaScript özellikle bildirici değildir. Copute'un sözdizimi ve Python'un sözdizimi, amaçlanan sonuçlarla daha açıklayıcı bir şekilde birleştirilir , yani, dışsal olanı ortadan kaldıran tutarlı sözdizimsel semantikler, kodun unutulduktan sonra kolayca anlaşılabilmesini sağlar. Copute ve Haskell operasyonel anlambilimin determinizmini uygular ve “ kendinizi tekrar etmeyin ” (KURU) ' yu teşvik eder , çünkü sadece saf işlevsel paradigmaya izin verirler.
2 biz dil Coq ile bir program, örneğin semantik kanıtlayabilirim bile, bu ifade edilir semantik sınırlıdır yazmaya ve yazarak bile vardır diller için bir programla sematiğinde tüm yakalamak asla tam değil, örneğin HTML + CSS ile tanımlanmamış anlambilime sahip tutarsız kombinasyonları ifade etmek mümkündür.
3 Birçok açıklama yanlış bir şekilde sadece zorunlu programlamanın sözdizimsel olarak sıralı ifadeler olduğunu iddia etmektedir. Zorunlu ve fonksiyonel programlama arasındaki bu karışıklığı açıkladım . Örneğin, HTML ifadelerinin sırası, anlamlarının tutarlılığını azaltmaz.
Edit: Robert Harper'ın bloguna aşağıdaki yorumu gönderdim :
fonksiyonel programlamada ... bir değişkenin değişim aralığı bir tiptir
Birinin işlevselliği zorunluluk programlamasından nasıl ayırdığına bağlı olarak, bir zorunluluk programındaki 'atanabilir' ifadeniz de değişkenliğine bir sınır koyan bir türe sahip olabilir.
İşlevsel programlama için şu anda takdir ettiğim tek karışık olmayan tanım a) birinci sınıf nesneler ve türler gibi işlevler, b) döngülere göre özyineleme tercihi ve / veya c) saf işlevler - yani istenen anlambilimi etkilemeyen işlevler ( böylece bellek tahsisi gibi işlevsel anlamsallıkların etkilerinden dolayı genel amaçlı bir anlamsal semantikte mükemmel derecede saf fonksiyonel programlama mevcut değildir ).
Saf bir fonksiyonun idempotent özelliği, değişkenleri üzerindeki fonksiyon çağrısının, genellikle zorunlu bir prosedürün argümanları için geçerli olmayan değeri ile değiştirilebileceği anlamına gelir. Saf işlevler, girdi ve sonuç türleri arasındaki oluşturulamayan durum geçişlerine göre deklaratif görünmektedir.
Ancak saf işlevlerin bileşimi böyle bir tutarlılığı korumaz, çünkü yan etki (küresel durum) zorunlu bir sürecini, örneğin Haskell'in IOMonad'ı gibi saf bir fonksiyonel programlama dilinde modellemek mümkündür ve dahası, böyle bir şeyin yapılmasını önlemek tamamen imkansızdır. herhangi bir Turing tam saf fonksiyonel programlama dili.
Ben şöyle yazdı 2012'de de yorumların benzer uzlaşma görünüyor ki en son blogunuza bildirim programlama amaçlanan semantik opak asla oldukları görüşünü yakalamak için bir girişim olduğunu. Opak semantik örnekleri düzene bağımlılık, operasyonel anlambilim katmanında daha yüksek seviyeli semantiklerin silinmesine bağımlılıktır (örneğin, dökümler dönüşüm değildir ve rejenere jenerikler daha yüksek seviyeli semantiği sınırlar ) ve kontrol edilemeyen değişken değerlere bağımlılıktır (kanıtlanmıştır) doğru) programlama diline göre.
Böylece, sadece Turing olmayan tam dillerin açıklayıcı olabileceği sonucuna vardım.
Dolayısıyla, bildirici bir dilin açık ve belirgin bir özelliği, çıktısının bazı numaralandırılabilir üretken kurallara uyduğu kanıtlanabilir. Örneğin, komut dosyası yazılmayan (diğer bir deyişle Turing tamamlanmamıştır) belirli bir HTML programı (yorumlayıcıların ayrılma yollarındaki farklılıkları yok sayarak) için çıktı değişkenliği numaralandırılabilir. Ya da daha özünde bir HTML programı değişkenliğinin saf bir fonksiyonudur. Bir elektronik tablo programı, giriş değişkenlerinin saf bir işlevidir.
Bu yüzden bana göre, bildirici diller sınırsız özyinelemenin antitezidir , yani Gödel'in ikinci eksiklik teoremine göre kendini referanslayan teoremler kanıtlanamaz.
Lesie Lamport , Öklid'in Gödel'in türler ve mantık (Curry-Howard yazışmaları, vb.) Arasındaki uyumla programlama dili bağlamında matematik kanıtlarına uygulanan eksiklik teoremlerinin nasıl çalıştığı hakkında bir peri masalı yazdı .
Zorunlu programlama: “makineye” bir şeylerin nasıl yapılacağını söyler ve sonuç olarak ne olmasını istersiniz.
Deklaratif programlama: “makineye” ne olmasını istediğinizi söyleyin ve bilgisayarın bunu nasıl yapacağını anlamasına izin verin.
function makeWidget(options) {
const element = document.createElement('div');
element.style.backgroundColor = options.bgColor;
element.style.width = options.width;
element.style.height = options.height;
element.textContent = options.txt;
return element;
}
function makeWidget(type, txt) {
return new Element(type, txt);
}
Not: Fark, kısalık, karmaşıklık veya soyutlama değildir. Belirtildiği gibi, fark nasıl vs ne .
Zorunlu / Bildirimsel / Fonksiyonel açıdan jenerik dilleri sınıflandırmak geçmişte iyiydi, ancak günümüzde tüm "büyük dil" bazı seçenek (tipik sahip (Java, Python, JavaScript, vb gibi) çerçeveler "Diğer odak" ile ifade etmek) ana süreçten (olağan zorunlu) ve paralel süreçleri, bildirim işlevlerini, lambdaları vb.
Bu sorunun iyi bir varyantı, "Bugün çerçeveleri sınıflandırmak için hangi yön iyidir?" ... Önemli bir yönü "programlama tarzı" olarak etiketleyebileceğimiz bir şeydir ...
Açıklamak için iyi bir örnek. Wikipedia'da jQuery hakkında okuyabileceğiniz gibi ,
Seçici motoru (...) tarafından etkinleştirilen jQuery çekirdek özellikleri - DOM öğesi seçimleri, geçiş ve manipülasyon - yeni bir "programlama stili", kaynaştırma algoritmaları ve DOM-veri yapıları oluşturdu
Yani jQuery, sadece nesne yönelimi değil, "yeni programlama tarzı" na odaklanmanın en iyi (popüler) örneğidir , " Kaynaştırma algoritmaları ve veri yapıları " dır . jQuery, elektronik tablolar gibi biraz reaktiftir, ancak "hücre yönelimli" değildir, " DOM düğümü yönelimlidir " ... Bu bağlamdaki ana stilleri karşılaştırmak :
Resim füzyon : Tüm "büyük diller" olarak, bir fonksiyonel / Bildirimsel / Emir ifadede, normal veriler ve algoritma "füzyon" terimi, bir bazı nesne yönelim dışında olan füzyon içinde katı cebirsel yapısı bakış açısından.
Bazı füzyon : tüm klasik füzyon stratejileri, günümüzde bunu paradigma olarak kullanan bir çerçeveye sahiptir ... veri akışı , Olay odaklı programlama (veya awk ve XSLT olarak eski alana özgü diller ) ... Modern elektronik tablolarla programlama gibi, bunlar da reaktif programlama üslubu örnekleri .
Büyük füzyon : "jQuery tarzı" dır ... jQuery, " kaynaştırma algoritmaları ve DOM-veri yapıları " üzerine odaklanan alana özgü bir dildir .
PS: XQuery, SQL (zorunlu ifade seçeneği olarak PL ile) olarak diğer "sorgu dilleri" de veri-algoritma-füzyon örnekleridir, ancak diğer sistem modülleri ile füzyon olmadan adalardır ... Bahar , find()
-varyantları kullanırken ve Şartname maddeleri, bir başka iyi füzyon örneğidir.
Deklaratif programlama, giriş ve çıkış arasındaki zamansız mantığı ifade ederek programlamadır, örneğin, sözde kodda, aşağıdaki örnek bildirici olacaktır:
def factorial(n):
if n < 2:
return 1
else:
return factorial(n-1)
output = factorial(argvec[0])
Burada sadece 'faktöriyel' olarak adlandırılan bir ilişki tanımladık ve çıktı ile girdi arasındaki ilişkiyi bu ilişki olarak tanımladık. Burada da anlaşılacağı gibi, herhangi bir yapılandırılmış dil hakkında bildirici programlamanın bir dereceye kadar genişlemesine izin verir. Deklaratif programlama için merkezi bir fikir değişmez verilerdir, bir değişkene atarsanız, bunu yalnızca bir kez yaparsınız ve bir daha asla yapmazsınız. Diğer, daha katı tanımlar, hiçbir yan etki olmayabileceğini gerektirir, bu dillere bazen 'tamamen bildirici' denir.
Zorunlu bir stilde aynı sonuç:
a = 1
b = argvec[0]
while(b < 2):
a * b--
output = a
Bu örnekte, giriş ve çıkış arasında zamansız statik mantıksal ilişki ifade etmedik, biri istenen sonucu alana kadar bellek adreslerini manuel olarak değiştirdik. Tüm dillerin açıklayıcı anlambilimin bir dereceye kadar genişlemesine izin verdiği, ancak hepsinin zorunlu olmasına izin vermediği açıktır, bazı 'tamamen' açıklayıcı diller yan etkilere ve mutasyona tamamen izin verir.
Deklaratif dillerin genellikle 'nasıl yapılır' yerine 'ne yapılması gerektiğini' söylediği söylenir, bence bu yanlış adlandırmadır, bildirim programları hala bir kişinin girdiden çıktıya nasıl alınması gerektiğini belirtir, ancak başka bir şekilde, Belirttiğiniz ilişki etkili bir şekilde hesaplanabilir olmalıdır (önemli terim, bilmiyorsanız arayın). Başka bir yaklaşım, uygulamanızın deneme yanılmadaki tüm yolları başarılı olana kadar tüketmeye başlamadan önce gerçekten hangi sonucun çok hangi koşulları karşıladığını belirleyen belirsiz olmayan programlamadır.
Tamamen bildirici diller arasında Haskell ve Pure Prolog bulunmaktadır. Birinden diğerine kayan ölçek: Saf Prolog, Haskell, OCaml, Şema / Lisp, Python, Javascript, C--, Perl, PHP, C ++, Pascall, C, Fortran, Montaj
factorial
herhangi bir değeri değiştirmediğini görün.
Burada belirtilen "tipler" ile ilgili bazı iyi cevaplar.
Genellikle fonksiyonel programlama kalabalığı ile ilişkili ek, daha "egzotik" kavramlar sunuyorum:
Taksonominin yanlış olduğunu düşünüyorum. Zorunlu ve beyan edici iki zıt tip vardır. İşlevsel, yalnızca bildirim niteliğindeki bir alt türdür. BTW, wikipedia aynı gerçeği belirtir.
Özetle, bir programlama stili Ne yapmalı (ne yapmalı), Nasıl Yapılır (ne yapmalı) detaylarını soyutlarsa o tarzın daha açıklayıcı olduğu düşünülür. Bunun tersi, mecburiyet için doğrudur. İşlevsel programlama, bildirici stille ilişkilendirilir.