İşlevsel bir dilde bir derleyici yazmak neden daha kolay? [kapalı]


89

Bu soruyu çok uzun süredir düşünüyordum, ancak yanıtı Google'da ve Stackoverflow'da benzer bir soru bulamadım. Bir kopya varsa, bunun için üzgünüm.

Pek çok insan, derleyicileri ve diğer dil araçlarını OCaml ve Haskell gibi işlevsel dillerde yazmanın, bunları zorunlu dillerde yazmaktan çok daha verimli ve daha kolay olduğunu söylüyor.

Bu doğru mu? Ve eğer öyleyse - bunları C gibi zorunlu bir dil yerine işlevsel dillerde yazmak neden bu kadar verimli ve kolay? Ayrıca - işlevsel bir dildeki bir dil aracı, C gibi bazı düşük seviyeli dillerden daha yavaş değil mi?


5
Daha kolay olduğunu söyleyemem. Ancak, ayrıştırma gibi derleme görevlerinin işlevsel doğası, muhtemelen işlevsel programlamaya oldukça doğal bir şekilde katkıda bulunur. OCaml gibi işlevsel diller son derece hızlı olabilir ve C'nin hızına rakip olabilir.
Robert Harvey

17
Millet, bu gerçekten tartışmaya açık mı? Şüphesiz birinin içgörüsü vardır. Kendimi tanımak isterim
Robert Harvey

Bence zorunlu bir dil yerine işlevsel bir dil kullanmak için en azından bazı iyi nedenler olmalı. Temelde, işlevsel dillerin hiçbir yan etkisi olmadığına dair bazı makaleler buldum. Ama pek net değildi. Ancak, bu tartışmaya açıksa, kapatmak veya soruyu yeniden formüle etmek daha iyi olabilir.
wvd

12
Bazı nişlerin belirli bir dil tarzına daha uygun olduğunu kabul etmek gerçekten tartışmacı mı? "Aygıt sürücülerini yazmak için C neden Javascript'ten daha iyidir" tartışmalı olmaz, sanırım ...
CA McCann

1
Bunun tersi olacağını düşündüm. "Süper minik derleyici" okuyorum ve her yerde değişken mutasyon kullanıyor.
Rolf

Yanıtlar:


102

Çoğu zaman bir derleyici ağaçlarla çok çalışır. Kaynak kodu bir sözdizimi ağacına ayrıştırılır. Bu ağaç, daha sonra, tür denetimi gerçekleştirmek için tür ek açıklamalarıyla başka bir ağaca dönüştürülebilir. Şimdi, bu ağacı yalnızca temel dil öğelerini içeren bir ağaca dönüştürebilirsiniz (sözdizimsel şeker benzeri gösterimleri şekersiz bir biçime dönüştürmek). Şimdi, temelde ağaç üzerinde dönüşümler olan çeşitli optimizasyonları gerçekleştirebilirsiniz. Bundan sonra, muhtemelen normal bir biçimde bir ağaç oluşturursunuz ve ardından hedef (derleme) kodunu oluşturmak için o ağaç üzerinde yinelersiniz.

İşlevsel dil, desen eşleştirme ve verimli özyineleme için iyi destek gibi özelliklere sahiptir, bu da ağaçlarla çalışmayı kolaylaştırır, bu yüzden genellikle derleyiciler yazmak için iyi diller olarak kabul edilirler.


Şimdiye kadarki en eksiksiz cevap, bunu kabul edilen cevap olarak işaretleyeceğim, ancak Pete Kirkham'ın cevabının da iyi olduğunu düşünüyorum.
wvd

1
Bir derleyicinin doğruluğu önemli bir özellik olduğu için, "doğruluğu kanıtlamak" a ne dersiniz? İşlevsel dillerin hayranlarının bir şekilde iş akışlarına doğruluk "kanıtını" dahil ettiklerini sık sık duymuştum. Bunun pratik anlamda ne anlama geldiğine dair hiçbir fikrim yok, ancak derleyici güvenilirliği önemli olduğu için bu değerli görünüyor.
Warren P

3
@WarrenP: "Kanıtı taşıyan kod" kavramı, statik olarak yazılmış işlevsel dillerden gelir. Buradaki fikir, tür sistemini öyle bir şekilde kullanmanızdır, böylece bir işlev yalnızca doğru olup olmadığını kontrol edebilir, bu nedenle kodun derlendiği gerçeği, doğruluğun kanıtıdır. Tabii ki bu, dili eksiksiz ve yazım denetimi karar verilebilir tutarken tam olarak mümkün değildir. Ancak tip sistemi ne kadar güçlüyse, bu hedefe o kadar yaklaşabilirsiniz.
sepp2k

3
Bu kavramın işlevsel toplulukta esas olarak popüler olmasının nedeni, değişken duruma sahip dillerde, türlerde durum değişikliğinin ne zaman ve nerede meydana geldiği hakkındaki bilgileri de kodlamanız gerekmesidir. Bir işlevin sonucunun yalnızca argümanlarına bağlı olduğunu bildiğiniz dillerde, türlerde bir ispatı kodlamak çok daha kolaydır (kodun doğruluğunu manuel olarak ispatlamak çok daha kolaydır çünkü hangi genel durumun olduğunu düşünmek zorunda değilsiniz olası ve işlevin davranışını nasıl etkileyeceği). Ancak bunların hiçbiri özellikle derleyicilerle ilgili değildir.
eylül

3
Bence en önemli özellik, desen eşleştirmesidir. Soyut bir sözdizimi ağacını desen eşleştirme ile optimize etmek aptalca kolaydır. Desen eşleştirmesi olmadan yapmak genellikle sinir bozucu derecede zordur.
Bob Aman

38

Birçok derleyici görevi ağaç yapıları üzerinde desen eşleştirmesidir.

Hem OCaml hem de Haskell, güçlü ve özlü kalıp eşleştirme yeteneklerine sahiptir.

Kalıpla eşleşecek şekilde değerlendirilen veya ayıklanan değer ne olursa olsun yan etkisiz olması gerektiğinden, zorunlu dillere kalıp eşleme eklemek daha zordur.


Makul bir cevap gibi görünüyor, ama tek şey bu mu? Örneğin, kuyruk özyineleme gibi şeyler de bir rol oynar mı?
wvd

Bu, gerçek yürütme modelinden çok tip sistem sorunu olduğunu gösteriyor gibi görünüyor. Yapısal tipler yerine değişmez değerlere sahip zorunlu programlamaya dayalı bir şey iyi olabilir.
Donal Fellows

@wvd: Kuyruk özyineleme optimizasyonu, doğrusal özyinelemeli işlevleri yinelemeli döngüye eşdeğer kılan bir dil özelliği değil, bir uygulama ayrıntısıdır. C'deki bağlantılı bir listede dolaşmak için özyinelemeli bir işlev, Scheme'deki bir listede yinelemenin yaptığı kadar fayda sağlayacaktır.
CA McCann

@wvd gcc C, diğer değişken eyalet dillerinde olduğu gibi kuyruk çağrısının ortadan kaldırılmasına sahiptir
Pete Kirkham,

3
@camccann: Dil standardı tco'yu garanti ediyorsa (veya en azından belirli bir formun özyinelemeli işlevlerinin hiçbir zaman bir yığın taşmasına veya bellek tüketiminde doğrusal bir büyümeye neden olmayacağını garanti ediyorsa), bunu bir dil özelliği olarak kabul ederim. Standart garanti etmiyorsa, ancak derleyici yine de yapıyorsa, bu bir derleyici özelliğidir.
sepp2k

15

Dikkate alınması gereken önemli bir faktör, herhangi bir derleyici projesinin büyük bir kısmının, derleyiciyi kendi kendine barındırabileceğiniz ve "kendi köpek mamasını yiyebileceğiniz" zamandır. Bu nedenle, dil araştırması için tasarlandıkları OCaml gibi dillere baktığınızda, derleyici türü problemler için harika özelliklere sahip olma eğilimindedirler.

Derleyici benzeri son işimde, C kodunu işlerken OCaml'i tam da bu nedenle kullandık, bu görev için en iyi araçtı. INRIA'daki insanlar OCaml'i farklı önceliklerle inşa etmiş olsaydı, bu o kadar da uygun olmayabilirdi.

Bununla birlikte, işlevsel diller herhangi bir sorunu çözmek için en iyi araçtır, bu nedenle mantıksal olarak, bu belirli sorunu çözmek için en iyi araç oldukları sonucuna varır. QED.

/ me: Java görevlerime biraz daha az neşe içinde geri dönüyor ...


4
"İşlevsel diller, herhangi bir sorunu çözmek için en iyi araçtır." Bu doğru olsaydı, hepimiz onları her yerde kullanırdık. ;)
Andrei Krotkov

15
@Andrei Krotkov: Bugünün kelimesi fa · ce · tious Telaffuz: \ fə-ˈsē-shəs \ İşlev: sıfat Etimoloji: Orta Fransız facetieux, facetie jest'ten, Latin facetia'dan Tarih: 1599 1: genellikle uygunsuz şekilde şaka veya şaka yapma : waggish <sadece şakacı olmak> 2: mizahi ya da komik olması amaçlanmıştır: ciddi değil <a akilli sözler> eş anlamlılar esprili görün Şakayı kaçırmanın yanı sıra, mantığınız hala kusurludur. Tüm insanların rasyonel aktörler olduğunu ve korktuğumun adil bir varsayım olmadığını varsayıyorsunuz.
Ukko

5
Sanırım şakayı kaçırdım, çünkü gerçek hayattaki insanları tamamen ciddiye almak dışında hemen hemen aynı şeyi söyleyecekler. Poe kanunu sanırım. tvtropes.org/pmwiki/pmwiki.php/Main/PoesLaw
Andrei Krotkov

13
@Andrei: Argumentum ad populum'unuzu kullanarak : "Eğer mantık, duygusal cehaletten daha iyiyse, hepimiz onu her yerde kullanıyor oluruz."
Tim Schaeffer

9

Temel olarak, bir derleyici, bir kod setinden diğerine bir dönüşümdür - kaynaktan IR'ye, IR'den optimize edilmiş IR'ye, IR'den montaja vb. sadece bir şeyden diğerine bir dönüşüm. Zorunlu işlevler bu niteliğe sahip değildir. Bu tür bir kodu zorunlu bir dilde yazabilmenize rağmen, işlevsel diller bunun için uzmanlaşmıştır.


6

Ayrıca bakınız

F # tasarım deseni

FP olayları 'işlemle' gruplarken, OO şeyleri 'türe göre' ve 'işlemle' bir derleyici / yorumlayıcı için daha doğaldır.


3
Bu, bazı Programlama Dili Teorisi çevrelerinde "ifade problemi" olarak adlandırılan şeyle ilgilidir. Örneğin, işleri "genişletilebilir türler" yoluyla yapan gerçekten korkunç bir Haskell kodunu gösterdiğim şu soruya bakın . Aksine, bir OOP dilini "genişletilebilir işlemler" stiline zorlamak Ziyaretçi Modelini motive etme eğilimindedir.
CA McCann

6

Bir olasılık, bir derleyicinin bir dizi köşe vakası ile çok dikkatli bir şekilde ilgilenme eğiliminde olmasıdır. Kodu doğru bir şekilde elde etmek genellikle, uygulamayı, uyguladığı kurallara paralel olacak şekilde yapılandıran tasarım kalıpları kullanılarak kolaylaştırılır. Çoğu zaman bu, zorunlu (sıralama, "ne zaman") tasarımdan ziyade bir bildirimsel (örüntü eşleştirme, "nerede") olur ve dolayısıyla bildirimsel bir dilde uygulanması daha kolaydır (ve çoğu işlevseldir).


4

Görünüşe göre herkes başka bir önemli nedeni gözden kaçırmış. Normal kodda (E) BNF'ye çok benzeyen ayrıştırıcılar için gömülü bir etki alanına özel dil (EDSL) yazmak oldukça kolaydır. Parsec gibi ayrıştırıcı birleştiriciler , üst düzey işlevleri ve işlev bileşimini kullanarak işlevsel dillerde yazmak oldukça kolaydır. Sadece daha kolay değil, aynı zamanda çok zarif.

Temel olarak, en basit genel ayrıştırıcıları yalnızca işlevler olarak temsil edersiniz ve bu ilkel ayrıştırıcıları dilbilginiz için daha karmaşık, daha özel ayrıştırıcılar halinde oluşturmanıza izin veren özel işlemlere (genellikle daha yüksek dereceli işlevler) sahipsiniz .

Tabi ki, daha iyi çerçeveler yapmanın tek yolu bu değil.

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.