Saf olmayan diller, prensip olarak, bilindik zorunlu dillerden gerçekten farklı değildir, özellikle şimdi birçok işlevsel numara kopyalanmıştır. Farklı olan stil - sorunları nasıl çözdüğünüz.
Haskell'i saf olarak veya IO monadını safsızlık olarak sayın, Haskell stili bu tarzın aşırı bir biçimidir ve öğrenmeye değer.
Haskell IO monad (tabii ki) monad'ların matematiksel teorisinden türetilmiştir. Ancak, zorunlu programcılar için, monad'lara varmanın geriye doğru bir yolunun daha anlamlı olduğunu düşünüyorum.
Birinci aşama - saf işlevsel bir dil, sonuç olarak kolayca büyük bir dize değeri döndürebilir. Bu büyük dize, bazı gereksinim belirleyici parametrelerden saf bir işlevsel yolla türetilen zorunlu bir programın kaynak kodu olabilir. Daha sonra, kod üretecinizi çalıştıran bir "daha yüksek seviye" derleyicisi oluşturabilir, ardından oluşturulan kodu otomatik olarak zorunlu dil derleyicisine besleyebilirsiniz.
İkinci aşama - metinsel kaynak kodu oluşturmak yerine, güçlü bir şekilde yazılan soyut bir sözdizimi ağacı oluşturursunuz. Zorunlu dil derleyiciniz "üst düzey" derleyicinize alınır ve AST'yi doğrudan kaynak kodu olarak kabul eder. Bu Haskell'in yaptıklarına çok daha yakın.
Yine de bu garip. Örneğin, kod oluşturma aşamasında değerlendirilen ve oluşturulan program çalıştırıldığında yürütülen iki farklı işlev türünüz vardır. Biraz C ++ fonksiyonlar ve şablonlar arasındaki ayrım gibi.
Dolayısıyla, 3. aşama için, ikisini aynı yapın - aynı sözdizimine sahip aynı işlev "kod üretimi" sırasında kısmen değerlendirilebilir veya tamamen değerlendirilebilir veya hiç değerlendirilmeyebilir. Ayrıca, tüm ilmek yapı AST düğümlerini özyineleme lehine atın. Aslında, AST düğümleri fikrini tamamen özel bir veri türü olarak atın - "gerçek değere" sahip olmayan AST düğümleri, sadece değerler vb.
Bu, IO monadının yaptığı şeydir - bind operatörü, programlar oluşturmak için "eylemler" oluşturmanın bir yoludur. Bu özel bir şey değil - sadece bir işlev. Birçok kod ve işlev "kod üretimi" sırasında değerlendirilebilir, ancak G / Ç yan etkilerine bağlı olanlar, herhangi bir özel kural tarafından değil, veri bağımlılıklarının doğal bir sonucu olarak, çalışma zamanına kadar değerlendirmeyi geciktirmelidir. ifade.
Monadlar genel olarak sadece genellemedir - aynı arayüze sahiptirler, ancak soyut işlemleri farklı şekilde uygularlar, bu yüzden zorunlu kodun bir tanımını değerlendirmek yerine başka bir şeye değerlendirirler. Aynı arayüze sahip olmak, hangi monad'ı umursamadan monadlara yapabileceğiniz bazı şeyler olduğu anlamına gelir, bu da faydalı olduğu ortaya çıkar.
Bu açıklama kuşkusuz safların kafalarını patlatacak, ama bana göre Haskell'in ilginç olmasının gerçek nedenlerinden bazılarını açıklıyor. Programlama ve metaprogramlama arasındaki sınırı bulanıklaştırır ve özel sözdizimine gerek kalmadan zorunlu programlamayı yeniden icat etmek için fonksiyonel programlama araçlarını kullanır.
C ++ şablonlarına sahip olduğum bir eleştiri, zorunlu bir dilde bir tür kırık saf fonksiyonel alt dil olduklarıdır - aynı temel işlevi derleme zamanında değerlendirmek için tamamen farklı bir stil kullanarak yeniden uygulamak zorundasınız kodlama. Haskell'de, safsızlık türünde etiketlenmekle birlikte, aynı fonksiyon hem meta-programlama anlamda hem de aynı programda çalışma zamanı meta-programlama dışı anlamda değerlendirilebilir - kesin bir çizgi yoktur programlama ve meta programlama arasında.
Bununla birlikte, standart Haskell'in yapamayacağı bazı metaprogramlama şeyleri vardır, çünkü temel olarak türler (ve belki de birkaç şey) birinci sınıf değerler değildir. Bununla birlikte, bunu ele almaya çalışan dil varyantları vardır.
Haskell hakkında söylediğim birçok şey saf fonksiyonel dillerde ve hatta bazen zorunlu dillerde uygulanabilir. Haskell farklıdır, çünkü bu yaklaşımı benimsemekten başka seçeneğiniz yoktur - temel olarak sizi bu tarz bir çalışma öğrenmeye zorlar. "ML'de C" yazabilirsiniz, ancak "Haskell'de C yazamazsınız" - en azından başlık altında neler olduğunu öğrenmeden.