API ve katıştırılmış Etki Alanına Özgü Dil (DSL) arasındaki fark nedir?
Sadece sözdizimi mi?
OpenGL gibi bir API düşünün. Grafik DSL'den farkı nedir?
Başka bir deyişle, bir API yeterince karmaşıksa, yerleşik bir DSL olarak düşünülebilir mi?
API ve katıştırılmış Etki Alanına Özgü Dil (DSL) arasındaki fark nedir?
Sadece sözdizimi mi?
OpenGL gibi bir API düşünün. Grafik DSL'den farkı nedir?
Başka bir deyişle, bir API yeterince karmaşıksa, yerleşik bir DSL olarak düşünülebilir mi?
Yanıtlar:
Ayrımı yapmak zordur ve kullanılan dile bağlıdır. Aynı zamanda özneldir.
Clojure'da, DSL'ye benzeyen API'ler tanımlayabilirsiniz. Örnek olarak, hıçkırık html oluşturmanıza izin verir:
(html [:span {:class "foo"} "bar"])
Bu lisp sözdizimine sahip bir DSL olarak düşünülebilir. html
Bir makro olabileceği gerçeği, s-ifadeleri ile bir html şablonlama lib'i yazıyormuş gibi aynı güç kaynağını verir (bkz. Sxml )
Python'da aynı API şöyle görünebilir:
html(["span", {"class" : "foo"}, "bar"])
html bir işlevdir. İlk olarak argümanı değerlendirilecek ve daha sonra fonksiyon çağrısı gerçekleşecek. Python sözdiziminin daha spesifik olması ve python semantiğinin daha katı olması, bu ifadenin dilden bağımsız bir DSL olarak yorumlanmasının daha zor olduğu anlamına gelir.
Klasik bir dil temsili, ağaç benzeri bir veri yapısı ve düğümlerinde özyinelemeli olarak adlandırılan bir değerlendirme işlevidir. LISP dilleri bu ağaç yapısını çok belirgin hale getirir, böylece iç içe fonksiyon çağrısı yerleşik bir dil özelliğinden ayırt edilemez. Bu nedenle LISP topluluğu hemen hemen her şey için DSL'ler hakkında konuşur.
Programlamanın faydalı soyutlamalar sağlamak olduğuna inanıyorum. İnsanların karmaşık bir sorunu çözmelerine yardımcı olan dil öğeleri olarak inşa ettiğiniz her şeye (uygulamanızın bir lib veya hatta UI) bakmanın çoğu şeyi tasarlamanın etkili bir yolu olduğunu düşünüyorum. Bu bakış açısıyla, her kütüphanenin DSL olduğunu iddia ediyorum, ancak bazıları kötü tasarlanmış :-)
API'lar ve DSL'ler oldukça farklı konseptlerdir ve yalnızca örtüştükleri söylenebilecek bazı alanlar vardır.
Tüm DSL'ler bilgisayar dilleridir . Bir API üzerinden iletilen iletilerde kullanılabilecek yorumlanabilir, derlenebilir, biçimlendirilebilir, sorgulama dilleri (örn. SQL) veya (JSON veya bazı XML kullanımları gibi) veri dilleri olabilir, ancak bunlar dil olmalıdır . Terim , amacı değil, doğayı tanımlar .
API'ler, bir yazılım bileşeninin diğer bileşenler tarafından kullanılmasına izin veren arabirimlerdir. Terim , doğayı değil amacı tanımlar . Bir API bir DSL nesne değil , bir dizi nesne yöntemi olabilir . Bir web API'si DSL kullanabilir (veya dinlendirici ise DSL olduğunu iddia edebilirsiniz ), ancak paylaşılan, etki alanına özgü bir dil tanımın bir parçası değildir. Bir aygıt için bir yazılım sürücüsü C olarak yazılabilir, derlenmiş kitaplık olarak dağıtılan API, protokol tamamen ikili ve kitaplığı kullanabilen herhangi bir dil bir istemci yapmak için kullanılabilir. Bu API'daki hiçbir şey DSL olarak adlandırılamaz (API işlevleri için sembolik adların listesi onu kesmez).
Tanımlar verildiğinde neden sadece benzerlikleri görebileceğiniz konusunda biraz kafam karıştı.
Genel olarak, hayır. DSL, bazı işlemleri daha kolay hale getirmek amacıyla kasıtlı olarak genel olmayan bir hale getirilmiştir . HTML veya Logo gibi şeyler başlangıçta alana özgü dillerdi.
Genel olarak, en güçlü API ile bile bir DSL'i başka bir dile gömemezsiniz; bu API'ya karşı programladığınız her ne olursa olsun, ana bilgisayar dilinde bir dizi ifade gibi görünecek ve özel amaçlı bir dil kullanmak kadar uygun olmayacaktır.
İstisnalar, bir kütüphane aracılığıyla sözdizimini çarpıtmak için olağanüstü fırsatlar sağlayan dillerdir (C ++ gibi aşırı yüklenen operatör, Scala gibi yeni operatörler icat eden, hatta Perl gibi tamamen farklı bir okuma sözdizimini tahmin eden kaynak filtreler). Böyle bir dili kullandığınızda ve sundukları esneklikten tam olarak yararlandığınızda, sonuç yeni, özel amaçlı bir dil gibi görünebilir (ancak semantik, dil gerçekten icat edildiğinde genellikle beklediğinizden hafifçe farklı olacaktır. uçlarından hizmet etmek için sıfırdan).
Burada, Martin Fowler tarafından DslBoundary'den
Makaleden, anlayışım temel olarak gömülü DSL'ler ve API'ler çok farklı değil. Ancak burada biraz fark var.
Ancak harici DSL hakkında konuşursanız başka bir hikaye olacaktır. Harici DSL tıpkı küçük bir programlama dili gibidir, ancak elbette, genel amaçlı bir dil değildir, bunun anlamı tüm sorunları çözemeyeceği, bunun yerine belirli bir problemi çözeceği anlamına gelir.
Her API'nin gömülü bir DSL olduğunu düşünüyorum ancak bunun tersi doğru değil: her gömülü DSL bir API değildir. Yalnızca dil, bileşenleri entegre etmek için bir araç olarak kullanıldığında, API olarak adlandırılabilir.
API neden gömülü DSL olarak kabul edilebilir? Her şeyden önce, bir dil oluşturur: soyutlamalar oluşturmak ve karmaşık problemleri çözmek için birleştirilebilen (ana bilgisayar dili aracılığıyla) ilkel unsurlara (tipler ve işlemler) sahiptir. Örneğin, OpenGL API 3D sahneleri gerçek zamanlı olarak oluşturmak için kullanılabilir. Koleksiyonlar API'si, nesneler, vb. Kümelerinde çalışan algoritmalar oluşturmak için kullanılabilir. İkinci olarak, açıkça etki alanına özgüdür; örneğin, Koleksiyonlar API'sının etki alanı nesne kümelerini işliyor ve OpenGL API'sı etki alanı 3B oluşturuyor. Dolayısıyla API, alana özgü bir dildir.
Ancak her DSL bir API değildir. Örneğin, bazı DSL'ler belirlenen bir bileşen tarafından uygulanmayacaktır. Tüm sistemler bazı soyutlamaları tanımlar ve belirli bir alanla ilgili soyutlamalar bir DSL olarak kabul edilebilir, ancak bu soyutlamaların uygulamalarının "değiştirilebilir" olması gerektiği anlamına gelir, başka bir deyişle, bir API oluşturmak zorunda değildirler. . Yapabilirlerdi, ama bu her zaman gerekli değildir. Bununla birlikte, uygulamanın "bileşenli" olduğu durumlarda (daha iyi bir terim eksikliğinden dolayı özür dileriz), DSL gerçekten bir API olur.