C # Dev - Lisps'i denedim, fakat alamadım [kapalı]


37

Hem CL hem de biraz Clojure ile birkaç ay boyunca Lisp hakkında bir şeyler öğrendikten ve oynadıktan sonra, hala C # yerine bir şey yazmak için zorlayıcı bir neden göremiyorum.

Gerçekten zorlayıcı nedenlerden birini veya birisinin gerçekten büyük bir şeyi kaçırdığımı belirtmesini isterim .

Lisp'in güçlü yönleri (araştırmam başına göre):

  • Kompakt, etkileyici gösterim - C # 'dan çok, evet ... ama bu fikirleri de C # ile ifade edebiliyor gibiyim.
  • İşlevsel programlama için örtülü destek - LINQ eklentisi yöntemleriyle C #:
    • mapcar = .Secect (lambda)
    • mapcan = .Seçin (lambda) .Açelik ((a, b) => a. Union (b))
    • araba / ilk = .İlk ()
    • cdr / rest = Atla (1) .... vb.
  • Lambda ve daha üst düzey işlev desteği - C # buna sahip ve sözdizimi tartışmasız daha basit:
    • "(lambda (x) (vücut))" ve "x => (vücut)"
    • Clojure'da "# (" "ile" "" ""% 1 ","% 2 "güzel
  • Nesnelerden ayrılmış yöntem gönderme - C #, uzatma yöntemleriyle buna sahiptir
  • Multimethod gönderme - C #, bu doğal olarak yok, ancak birkaç saat içinde bir işlev çağrısı olarak uygulayabilir
  • Kod Veridir (ve Makrolar) - Belki de "makro" almadım, ancak bir makro fikrinin bir işlev olarak uygulanamayacağı tek bir örnek görmedim; "dili" değiştirmiyor, ama bunun bir güç olduğundan emin değilim.
  • DSLs - Yalnızca fonksiyon bileşimi ile yapabilir ... ama çalışır
  • Türlenmemiş "keşif" programlaması - yapılar / sınıflar için, C # 'ın otomatik özellikleri ve "nesne" oldukça iyi çalışır ve ilerledikçe daha güçlü yazarak kolayca yükselebilirsiniz
  • Windows olmayan bir donanımda çalışır - Evet, öyle mi? Kolej dışında, yalnızca evde Windows çalıştırmayan bir kişi ya da en azından * nix / Mac'te bir Windows sanal makinesi tanıdım. (Sonra tekrar, belki de bu düşündüğümden daha önemli ve beynimi yeni yıkadım ...)
  • Aşağıdan yukarıya tasarım için REPL - Tamam, bunun gerçekten çok hoş olduğunu kabul ediyorum ve C # 'da özlüyorum.

Lisp'te özlediğim şeyler (C #, .NET, Visual Studio, Resharper karışımı nedeniyle):

  • Namespaces. Statik yöntemlerle bile, bağlamlarını sınıflandırmak için onları bir "sınıfa" bağlamayı seviyorum (Clojure buna sahip görünüyor, CL görünmüyor.)
  • Mükemmel derleme ve tasarım zamanı desteği
    • tip sistemi etrafta dolaştığım veri yapılarının "doğruluğunu" belirlememe izin veriyor
    • yanlış yazılmış herhangi bir şeyin gerçek zamanlı olduğunun altı çizilir; Bilmek için çalışma zamanı kadar beklemek zorunda değilim
    • kod iyileştirmeleri (zorunlu olan yerine FP yaklaşımını kullanmak gibi) otomatik olarak kabul edilir
  • GUI geliştirme araçları: WinForms ve WPF (Clojure'un Java GUI kitaplıklarına erişimi olduğunu biliyorum, ancak tamamen bana yabancılar.)
  • GUI Hata ayıklama araçları: kesme noktaları, adım adım, adım adım, değer denetçileri (metin, xml, özel), saatler, iş parçacığı hata ayıklama, koşullu kesme noktaları, koda herhangi bir düzeyde atlama kabiliyeti olan çağrı yığını penceresi yığında
    • (Adil olmak gerekirse, Emacs + Slime ile olan ilişkim bunun bir kısmını veriyor gibiydi, ama VS GUI odaklı yaklaşımın bir parçasıyım)

Lisp'i çevreleyen yutturmaca gerçekten seviyorum ve bir şans verdim.

Fakat Lisp'te yapabileceğim ve C # ile yapamayacağım bir şey var mı? C # biraz daha ayrıntılı olabilir, ama aynı zamanda otomatik tamamlama var.

Neyi kaçırıyorum? Neden Clojure / CL kullanmalıyım?


4
Zaten işlevsel bir tarzda programlama yaptığınızdan ve Windows altyapısına oldukça güveniyormuşsunuz gibi göründüğü için, C # 'dan değişmeniz için hiçbir zorlayıcı sebep göremiyorum. Tanıdığım çoğu kişi Mac veya Linux kullanıyor, bu yüzden açıkça çalıştığınız kalabalığa bağlı (3.1'den beri her Windows sürümünü kullandım ancak genel olarak platformlar arası yazılım ve * nix sistemleriyle çalışmayı tercih ediyorum ...) ama sonra herhangi bir yerel GUI çalışması yapmam, tüm sunucular ve web kullanıcı arayüzü öğeleri)
Sean Corfield

2
Sen The Swine Before Perl bakabilirsiniz . Dinlemesi eğlenceli bir konuşma ve makroların neye iyi geldiğinin basit bir örneğini sunuyor.
Matthias Benkard

4
“Makro fikrinin bir işlev olarak uygulanamayacağı tek bir örnek görmedim” - Nasıl yazacağınızı ANDveya ORbir işlev olarak görmek isterim . Yapılabilir (verilen LAMBDA, aynı zamanda bir makrodur), ancak bunu yapmanın tamamen berbat olmayacağı açık bir yol görmüyorum.

1
"İsim alanları. ... Clojure buna sahip görünüyor, CL görünmüyor" - Aradığın şey hakkında daha spesifik olabilir misin? Gerçekten Clojure kullanmamıştım ancak ad alanları CL'nin paketlerine çok benziyor.

4
Jonathan: CL kullanır :(veya ::verilmeyen semboller için) paketlerdeki sembollerin isimlendirilmesi için, örneğin, buradaki örnekte http:sessionve kullanılır chat:session.

Yanıtlar:


23

Makrolar, derleyicileri dilinizin rahatlığını bırakmadan yazmanıza izin verir. C # gibi dillerde DSL'ler genellikle bir çalışma zamanı yorumlayıcısına karşılık gelir. Etki alanınıza bağlı olarak, performans nedenleriyle bu sorunlu olabilir. Hız önemlidir , aksi takdirde C # değil, yorumlanmış bir dilde kodlama yaparsınız.

Ayrıca, makrolar ayrıca insan faktörlerini göz önünde bulundurmanıza izin verir - belirli bir DSL için en kullanıcı dostu sözdizimi nedir? C # ile sözdizimi hakkında yapabileceğiniz pek bir şey yok.

Böylece Lisp, verimliliğe giden yolu feda etmeden dil tasarımına katılmanıza izin verir . Ve bu konular sizin için önemli olmasa da , üretime yönelik tüm programlama dillerinin temellerinin altında yer aldıkları için son derece önemlidir. C # 'da bu temel eleman size en iyi şekilde çok sınırlı bir şekilde maruz kalır.

Makroların önemi diğer dillerde kaybolmuyor - Template Haskell, camlp4 akla geliyor. Fakat yine de bu bir kullanılabilirlik meselesi - Bugüne kadar Lisp makroları muhtemelen derleme zamanı dönüşümünün en kullanıcı dostu ama güçlü uygulamasıdır.

Sonuç olarak, genel olarak insanların genel olarak C # gibi w / w yapabilecekleri DSIL'leri (Etki Alanına Göre Yorumlanan Diller) oluşturur. Lisp size daha radikal bir şey yapma fırsatı veriyor, DSP'ler (Domain Spesifik Paradigmalar). Raket (eski adıyla PLT-Scheme) bu konuda özellikle ilham veriyor - tembel bir dilleri (Lazy Raketleri), yazılanları (Typed Racket), Prolog ve Datalog hepsi makroya gömülü olarak yazıyor. Tüm bu paradigmalar , büyük problem sınıflarına güçlü çözümler sunar - zorunlu programlama veya hatta FP paradigmalarıyla çözülmeyen problemler.


3
Bu argümanla ilgili ilginç bulduğum şey, DSL / DSIL uygulamak için asla bir fırsata (ya da cehaletime tamamen göz ardı ettiğim) rastlamam. DSL'lerin gücünü detaylandırabilir misiniz? (Hem geliştirici hem de kullanıcı için.) Bu ses, gerçekten özlediğim en büyük şey olabilir .

15
@Jonathan Mitchem, zaten birçok harici DSL kullanıyorsunuz - yapılandırma dosyaları, komut dosyaları oluşturma, ORM yapılandırmaları, görsel kod üreteçleri (örneğin, winforms editörü), XAML, ayrıştırma üreteçleri, vb. Onlar için ayrı bir yapım aracına ihtiyaç duymazlar ve tek bir dilde sunulurlar. Ve yerleşik DSL'lerden en az ikisine aşina olmalısınız - normal ifadeler ve SQL.
SK-mantık

Vay canına tamam. Bunları DSL olarak hiç düşünmedim. Şimdi, kasıtlı olarak, "c # ile yapabileceğim herhangi bir şey, c # için yapışacağım" esasına dayanarak, bundan çok saptım. Kişisel olarak, tutarlı bir davranışa sahip tek bir aletle yapışmayı seviyorum. Ancak bu örneklerde DSL'lerin değerini anlıyorum.

2
@Jonathan Mitchem, verilen herhangi bir araçla ilgili sorun, verilen bir amaç için mutlaka uygun olmayacağıdır. Farklı görevler için farklı araçlar seçmelisin. Lisp de dahil olmak üzere herhangi bir meta dilin gücü, kendi dil alanına özgü kendi araçlarınızı ana dilinizin üzerinde büyütebildiğiniz için başka bir araca tamamen geçmeniz gerekmediğidir. Nemerle'ye göz atmanızı öneririm, bir C # geliştiricisi için bunu anlamak daha kolay olurdu ve makroları neredeyse Lisp'ler kadar güçlü.
SK-mantık

3
“Tek bir araçla yapışmayı seviyorum ...” Lisp'ta düzgün hazırlanmış DSL'ler asla Lisp'in gücünü saklamıyor, bu yüzden hala bir aracın var. Sadece kelime dağarcığına, belirli bir alan için kodlamayı daha "doğal" hale getirecek şekilde eklerler, yani daha iyi soyutlamalar ve genel organizasyon.

15

Başlangıçta yalnızca Lisps'ta mevcut olan hemen hemen her şey neyse ki diğer birçok modern dile geçmiştir. En büyük istisna, "kod veridir" felsefesi ve makrolardır.

Kod Veridir (ve Makrolar) - Belki de "makro" almadım, ancak bir makro fikrinin bir işlev olarak uygulanamayacağı tek bir örnek görmedim

Evet, makroları kırmak zor. Metaprogramming genel olarak grok zordur. İşlev olarak uygulanabilecek herhangi bir makroyu gördüyseniz , programcı yanlış yapıyordu. Makrolar, yalnızca bir işlev çalışmadığında kullanılmalıdır.

Bir makronun "merhaba dünyası" örneği, cond cinsinden "if" yazmaktır. Makroların gücünü gerçekten öğrenmek istiyorsanız, clojure'da bir "my-if" tanımlamayı deneyin, fonksiyonları kullanın ve nasıl kırıldığını izleyin. Gizemli olmak istememiştim, sadece kimsenin yalnızca açıklama yaparak makroları anlamaya başladığını görmedim, ancak bu slayt gösterisi oldukça iyi bir giriş: http://www.slideshare.net/pcalcado/lisp-macros-in -20 dakika sonraki özellikli-Clojure-sunum

Makrolar kullanarak yüzlerce / binlerce satır kod biriktirdiğim küçük projelerim vardı (Java’da alacağı ile karşılaştırıldığında). Clojure'un çoğu Clojure'da uygulanır, bu yalnızca makro sistem nedeniyle mümkündür.


3
Herhangi bir koda dokunmadan, hem kafamda hem de Clojure hem de C # 'da makrolar olmadan bir "if" kullanma senaryosuna baktım. Etkili (veya tam anlamıyla) yapılamaz. Kabul ediyorum, temiz. Ama bunun benim için ne kadar yararlı olduğu bağlantısını özlüyorum. Akıllıca veya OO tasarımıyla yapamayacağım makrolarla ("if" yazmanın dışında) ne yapabilirim? “Bu bana nasıl yardımcı olabilirdi” bir dili değerlendirmek için geçerli bir kriter değildir, ancak onu kullanıp kullanmayacağımı değerlendirmek içindir. (Gerçekten bir Lisp'in

1
Bu örneği almam biraz zaman alacak. Benim için, "kazan kodunu korumak" genellikle açıklamaların beni ikna etmediğinin bir parçası olan "yeniden düzenleme" terimini kullanmaktadır. Uyguladığım her durumda işe yarayan bir çözümüm var. Sanırım soru şu ki, bir makroyu kullanabileceğiniz durumları nasıl belirliyorsunuz?

1
Makroların değerli olduğuna katılıyorum, ancak bir my-eğer onları isterse, üst düzey bir işlev olarak yazılabileceği doğru değil (aşağıdaki CL örneğine bakın). Yalnızca, kodu yürümek veya yeni bir sözcük bağlamına yerleştirmek istiyorsanız, yalnızca makrolara ihtiyacınız vardır. (defun my-if (test then &optional else) (cond (test (funcall then)) ('otherwise (funcall else))))

1
Temelde bir fonksiyonla yürüyebileceğiniz alıntı olan her iki kodu da kabul etme seçeneğiniz vardır, ancak kendi sözcük bağlamı eksiktir çünkü yürüdüğünüz ve fonksiyonun sözcük bağlamında yürütüyorsunuz. Ya da sözcüksel bağlamlarını koruyan kapanışları kabul edebilirsiniz, ancak onları arayabilir, yürüyemez ya da sözcüksel bağlamlarına bir şeyler ekleyebilirsiniz. Her ikisini de yapmak için, kodu genişletme işleminin makro çağrısının sözlü bağlamına yerleştirilmeden önce yürüyebilen ve sarabilen bir makroya ihtiyacınız vardır.

7
@Jonathan Mitchem, LINQ sözdizimi, makrolarla neler yapılabileceğinin güzel bir örneğidir, ancak dil düzgün bir meta programlamayı desteklemediğinden, bunun yerine bir dil çekirdeğinde uygulanması gerekiyordu.
SK-mantık

14

Common Lisp'te uzman değilim, ama hem C # hem de Clojure'u oldukça iyi biliyorum, umarım bu yararlı bir bakış açısıdır.

  • Basit sözdizimi => power - Lisps, çalışması mümkün olabilecek en basit sözdizimi hakkındadır. S ifadeleri tek ihtiyacınız olan şey. "(Function-call arg1 arg2 arg2 arg3)" ifadesini kullandıktan sonra, temelde anladınız. Gerisi sadece doğru fonksiyon çağrıları ve argümanları seçmektir. Neredeyse önemsiz derecede basit görünüyor, ancak gerçek şu ki bu basitlik Lisps'a bu kadar güç ve esneklik kazandırıyor ve özellikle Lisp'in ünlü olduğu meta-programlama yeteneklerini mümkün kılıyor. mesela ben bir makro ben sadece bu (aşağıdaki gibi bir şey yapmak aynı argümanları üzerinde birkaç farklı işlevleri çağırmak istiyorum değil size tüm bireysel fonksiyon çağrıları yazmış gibi kod derlenmiş oluşturur makro - sadece çalışma zamanı fonksiyon uygulaması elle):
(defmacro print-many [functions args]  
  `(do   
     ~@(map   
        (fn [function] `(println (~function ~@args)))   
        functions)))

(print-many [+ - * /] [10 7 2])  
19  
1  
140  
5/7
  • İnanılmaz derecede basit bir sözdiziminin bir sonucu olarak, Lisp'in "kod veridir" felsefesi, işlev bileşimi / şablonlar / generics vb. İle yapabileceğiniz her şeyden çok daha güçlüdür. Derleme zamanında DSL'lerden daha fazlası, kod oluşturma ve manipülasyon , dilin temel bir özelliği olarak. Bu tür yetenekleri C # veya Java gibi homoikon olmayan bir dilde almaya çalışırsanız , sonunda Lisp'i fena halde yeniden keşfedeceksiniz . Dolayısıyla ünlü Greenspuns Onuncu Kuralı: "Yeterince karmaşık olan herhangi bir C veya Fortran programı, Ortak Lisp'in yarısının geçici, gayri resmi olarak belirlenmiş, böcek basması, yavaş uygulanmasını içerir". Uygulamanızın içinde turing-komple bir şablonlama / akış kontrol dilini icat ettiğinizi keşfettiyseniz, muhtemelen ne demek istediğimi anlarsınız.

  • Eşzamanlılık benzersiz bir Clojure gücüdür (diğer Lisps'lere kıyasla bile), ancak programlamanın geleceğinin çok çekirdekli makinelere ölçeklenen uygulamalar yazmak zorunda kalacağı anlamına geldiğini düşünüyorsanız, o zaman gerçekten bu konuya gerçekten bakmalısınız - çığır. Clojure STM (Yazılım İşlem Belleği) çalışır çünkü Clojure , kimlik ve durumun yeni bir ayrımına dayanan değişmezliği ve kilitlenmemiş eşzamanlılık yapılarını benimsediğinden çalışır (bkz. Rich Hickey'nin kimlik ve durum hakkındaki mükemmel videosu ). Bu tür eşzamanlılık kabiliyetini, API'lerin önemli bir kısmının değişken nesneler üzerinde çalıştığı bir dil / çalışma zamanı ortamı üzerine yerleştirmek çok acı verici olacaktır.

  • Fonksiyonel programlama - Lisps, daha üst düzey fonksiyonlarla programlamayı vurgulamaktadır. OO nesnelerinde kapaklar / işlev nesneleri vb. İle öykünebileceğini haklısınız, ancak fark şu ki, tüm dil ve standart kütüphanesi bu şekilde kod yazmanıza yardımcı olacak şekilde tasarlandı. Örneğin, Clojure dizileri tembeldir , bu nedenle C # / Java'daki ArrayLists veya HashMaps öğelerinin aksine sonsuz uzun olabilir. Bu, bazı algoritmaları ifade etmeyi çok daha kolaylaştırır, örneğin, aşağıdakiler sonsuz bir fibonacci sayıları listesi uygular:

    (def fibs (lazy-cat '(0 1) (map + fibs (drop 1 fibs))))

  • Dinamik yazım - Lisps, işlevsel programlama dili spektrumunun "dinamik" ucunda olma eğilimindedir (Haskell gibi dillerin aksine, çok güçlü ve güzel bir statik türleri anlayışı olan). Bunun hem avantajları hem de dezavantajları vardır, ancak dinamik dillerin daha fazla esneklik nedeniyle programlama verimliliğini destekleme eğiliminde olduğunu savunuyorum. Bu dinamik yazmanın düşük bir çalışma süresi performans maliyeti vardır, ancak bu sizi rahatsız ediyorsa, statik yazmayı almak için her zaman kodunuza tür ipuçları ekleyebilirsiniz. Temel olarak - varsayılan olarak kolaylık elde edersiniz ve almak için biraz daha fazla çalışma yapmaya istekli olursanız performans elde edersiniz.

  • Etkileşimli gelişim - aslında C # 4.0 için bir çeşit REPL alabileceğinizi düşünüyorum, ancak Lisp'te bir yenilikten ziyade standart bir uygulamadır. Bir derleme / derleme / test döngüsü yapmanız gerekmez - kodunuzu doğrudan çalışan ortama yazarsınız ve daha sonra kaynak dosyalarınıza kopyalarsınız. Size, sonuçları hemen gördüğünüz ve çözümünüzü yinelemeli şekilde rafine ettiğinizde kodlamanın çok farklı bir yolunu öğretir.

"Eksik" olarak gördüğünüz şeyler hakkında birkaç kısa yorum:

  • Söylediğin gibi, Clojure'un ad alanları var. Aslında, dinamik ad alanlarıdır: çalışma zamanında bunları güncelleyebilirsiniz - bu etkileşimli gelişim için bazı şaşırtıcı yararlar sağlar. Çalışan bir iş parçacığının burnu altındaki işlevleri yeniden tanımlamak ya da canlı bir veri yapısını kesmek çok eğlenceli oldu.
  • Derleme / tasarım zamanı desteği - bir REPL'de kodlama yapıyorsanız, konuyla ilgili değil - sadece bunu yapın ve sonucu doğrudan görün. Bunu söyledikten sonra Clojure, Eclipse için CounterClockwise eklentisi gibi bazı IDE desteği almaya başladı .
  • GUI geliştirme - Evet, yeni bir API öğrenmek zorunda kalacaksınız, ancak dilleri değiştirirken her zaman durum böyle olacak ... iyi haber şu ki, Java API'leri o kadar da zor değil ve şimdi bazı ilginç Clojure- kullanımı oldukça kolay görünen özel ambalajlar / örnekler. Bazı güzel örnekler için Clojure GUI geliştirme üzerine bu soruya bakın.
  • GUI hata ayıklaması: Bu, Netbeans kullanıyorsanız, CounterClockwise ya da Enclojure kullandığınız varsayımıyla Eclipse'deki GUI hata ayıklayıcı ile çalışır. Bunu söyledikten sonra, bu özelliği kullanmıyorum - REPL'de etkileşimli hata ayıklamayı daha verimli buluyorum.

Şahsen Clojure / Lisp’in avantajlarını oldukça çekici buluyorum ve C # / Java’ya geri dönmeyi planlamıyorum (tüm faydalı kütüphaneleri ödünç almam gerekenin ötesinde!).

Ancak, kafamı tamamen dolaştırmam birkaç ay sürdü. Eğer gerçekten Lisp / Clojure'u aydınlatıcı bir öğrenme deneyimi olarak öğrenmek ilginizi çekiyorsa, dalış yapmanın ve kendinizi birkaç şeyi uygulamaya zorlamanın bir alternatifi yoktur…


1
Fikirlerin büyük sayımı için teşekkür ederiz. Aslında tembel sekansları C # içindeki IEnumerable <> construct ile çok fazla kullanıyorum (ve 2005’ten beri bir ArrayList’e dokunmadım) ancak bu fikri anlıyorum. Clojure'un eşzamanlılık ilkeleri son derece etkileyici. Birkaç yıl önce C # 'da grid hesaplama yapıyordum - birçok çok çekirdekli makinede eşzamanlılık - ve hala bunun geleceği olduğuna inanıyorum. Muhtemelen herkesten edindiğim en büyük fikir "gerçekten kazmak ve deneyimlemek zorundasın, gerçekten açıklanamaz" dır. Bu yüzden kazmaya devam edeceğim ve yaşamaya devam edeceğim.

1
Cool, yardımcı olmaktan memnun - ve bu kesinlikle doğru ruh!
mikera

10

C # birçok özelliğe sahip, ancak karışım farklı hissediyor. Bazı dilin bir özelliğe sahip olması hâlâ kullanımı kolay, paradigmatik ve dilin geri kalanıyla iyi bir şekilde entegre olduğu anlamına gelmez.

Yaygın Lisp bu karmaya sahiptir:

  • veri sözdizimi olarak s ifadeleri
  • Makrolara ve diğer sembolik hesaplama tekniklerine yol açan veri kodları
  • Dinamik dil çalışma zamanı değişikliklerine izin verir (geç bağlama, MOP, ...)
  • yazılan, dinamik olarak yazılmış
  • artımlı derleyici veya tercüman ile etkileşimli kullanım
  • Çekirdek yürütme motoru olarak değerlendirici
  • Çöp Toplama ile yönetilen bellek
  • Zorunlu, işlevsel ve nesne yönelimli programlamanın yoğun kullanıldığı karma bir dil. Diğer paradigmalar eklenebilir (kurallar, mantık, kısıtlamalar, ...).

Şimdi, C # gibi diğer diller de var. Ancak çoğu zaman aynı vurgu ile değil.

C # vardır

  • C benzeri sözdizimi
  • Bazı FP özellikleri ile çoğunlukla zorunlu nesne yönelimli
  • statik olarak yazılmış
  • toplu derleyici ile çoğunlukla toplu kullanım
  • Çöp Toplama ile yönetilen bellek

Lisp'te olduğu gibi yaygın olarak kullanılmazsa, C # örneğin kod manipülasyon özelliklerine sahip olması yardımcı olmaz. Lisp'te, makroları her türlü basit ve karmaşık şekillerde yoğun şekilde kullanmayan birçok yazılım bulamazsınız. Kod manipülasyonunu kullanmak Lisp'te gerçekten büyük bir özelliktir. Bazı kullanımların taklit edilmesi birçok dilde mümkündür, ancak bunu Lisp'te olduğu gibi merkezi bir özellik yapmaz. Örnekler için 'On Lisp' veya 'Practical Common Lisp' gibi kitaplara bakın.

Etkileşimli gelişim için aynı. Büyük bir CAD sistemi geliştirirseniz, geliştirmenin çoğu editörden ve REPL'den etkileşimli olacaktır - doğrudan çalışan CAD uygulamasına. Bunların çoğunu C # veya diğer dillerde - genellikle bir uzantı dili uygulayarak - taklit edebilirsiniz. Lisp için, değişiklik eklemek için geliştirilmekte olan CAD uygulamasını yeniden başlatmak aptalca olurdu. CAD sistemi daha sonra, CAD nesnelerini ve bunların ilişkilerini (kısmen, içerilen, ...) tanımlamak için dil özellikleri (makrolar ve sembolik açıklamalar şeklinde) ekleyebilecek gelişmiş bir Lisp içerecektir. Birisi C # 'da benzer şeyler yapabilir, ancak Lisp'te bu varsayılan geliştirme tarzıdır.

Etkileşimli bir geliştirme süreci kullanarak karmaşık yazılımlar geliştirirseniz veya yazılımınızın önemli bir sembolik bölümü vardır (meta programlama, diğer paradigmalar, bilgisayar cebiri, müzik kompozisyonu, planlama, ...), o zaman Lisp sizin için olabilir.

Windows ortamında çalışıyorsanız (yok), o zaman C #, Microsoft'un ana geliştirme dili olduğundan bir avantaja sahiptir. Microsoft, Lisp'i hiçbir şekilde desteklememektedir.

Sen yaz:

  • Namespaces. Statik yöntemlerle bile, bağlamlarını sınıflandırmak için onları bir "sınıfa" bağlamayı seviyorum (Clojure buna sahip görünüyor, CL görünmüyor.)

Common Lisp, sınıflara isim alanları eklemiyor. Ad alanları sembol paketleriyle sağlanır ve sınıflardan bağımsızdır. CLOS kullanıyorsanız, nesne yönelimli programlama yaklaşımınızı yeniden yönlendirmeniz gerekir.

  • Büyük derleme ve tasarım zamanı desteği, yazım sisteminin yanlış yazılmış herhangi bir şeyden geçirdiğim veri yapılarının "doğruluğunu" belirlememe izin veriyor; Kod geliştirmelerinin (zorunlu bir yerine bir FP yaklaşımının kullanılması gibi) otomatik olarak engellenmesini bilmek için çalışma zamanını beklememe gerek yok

Lisp derleyicisini kullanın. Bilinmeyen değişkenler hakkında sizi bilgilendirir, stil önerileri olabilir (kullanılan derleyiciye bağlı olarak), verimlilik ipuçları verir, ... Derleyici bir tuşa basılmaz.

  • GUI geliştirme araçları: WinForms ve WPF (Clojure'un Java GUI kitaplıklarına erişimi olduğunu biliyorum, ancak tamamen bana yabancılar.)

LispWorks ve Allegro CL gibi ticari Lisps, Windows altında benzer şeyler sunar.

  • GUI Hata ayıklama araçları: kesme noktaları, adım adım, adım adım, değer denetçileri (metin, xml, özel), saatler, konuya göre hata ayıklama, koşullu kesme noktaları, her seviyedeki koda atlayabilme özelliğine sahip çağrı yığını penceresi yığında (Adil olmak gerekirse, Emacs + Slime ile olan ilişkim bunun bir kısmını veriyor gibiydi, ama VS GUI odaklı yaklaşımın bir parçasıyım)

LispWorks ve Allegro CL gibi ticari Lisps, Windows altında bunların hepsini sunar.


1
Benim eleştirim gerçekten Lisps'tan değil. Onları oldukça yetenekli buluyorum. Bir Lisp'in bana daha önce yapmadığım bir şeyi ne yapabileceğini / verebileceğini arıyorum. C # dev'lerin çoğu "yeni" dil özelliğini kullanmadığını tamamen anlıyorum. Sanırım asıl mesele şu ki, dürüst olmak gerekirse, GUI dışında, neredeyse% 100 FP tarzında yazıyorum. FP kavramsal bir sıçramaydı ama buna değdi. Ancak, bulunduğum yerden Lisp'a geçmek çok az fayda sağlıyor gibi görünüyor. Buna bir şans vermem için bir neden olduğunu bulmayı umuyorum.

@Jonathan Mitchem: C # bir FP dili gibi görünmüyor, dilin onu destekleyen bazı özellikleri olsa da ve birkaç kütüphane bunları kullanabilir. Microsoft eko sisteminde FP programlama yapmak istiyorsanız, F # sizin için olabilir.

@Rainer Hayır, bir FP dili gibi görünmüyor, ancak bunu yapabilir ve oldukça kompakt bir şekilde. Ve zorunlu kod veya OO istediğimde / ihtiyaç duyduğumda, bunu da yapabilirim. (biraz konu dışı: Gerçekten F # 'ı kazmaya değer ciddi bir dil olarak görmüyorum, Haskell'deki monadların etrafına kafamı sokmayı tercih ederim. "gerçek" bir dil ya da [ve o zamanlar değildi,


@Jonathan Mitchem: neden bakmalıyım? C # 'nın bazı FP özelliklerini desteklediğini yazdım. Sadece zorunluluk nesne yönelimli bir dile eklenmiştir ve Lisp, Scheme gibi, özellikle de SML, F #, Haskell veya diğer esas olarak işlevsel dillerle karşılaştırılmadığı gibi, deyimsel değildir. Demek istediğim: Bazı FP C # 'da mümkün, ancak temel bir özellik değil.

5

Rainier Joswig en iyisini söyledi.

Benim için, Lisp’in gücü sadece Lisp özelliklerinin bir listesine bakarak anlaşılamaz. Lisp ve özellikle Common Lisp için bütün, parçaların toplamından daha büyük. Bu sadece REPL artı s ifadeleri artı makrolar artı çoklu yöntem gönderme artı kapanışlar artı paketler artı CLOS artı yeniden başlatmalar artı X, Y ve Z değil. Diğer programlama dillerinin günlük deneyimlerinden çok farklı olan günlük deneyim.

Lisp farklı görünüyor, farklı kullanılıyor, biri kullanıldığında farklı bir şekilde programlamaya yaklaşıyor. Zarif, eksiksiz, büyük ve kusursuz. Kendi lekeleri ve peccadilloları olmadan değildir. İleride çıkamayacağı yerlerde yapılabilecek diğer dillerle kesinlikle karşılaştırılabilir. Ancak hiçbir şekilde Lisp yalnızca X dili REPL ve makrolar ya da Y dili ve çoklu yöntem gönderimi ve yeniden başlatmaları anlamına gelmez.


3
Kod Veridir (ve Makrolar) - Belki de "makro" almadım, ancak bir makro fikrinin bir işlev olarak uygulanamayacağı tek bir örnek görmedim; "dili" değiştirmiyor, ama bunun bir güç olduğundan emin değilim.

Genellikle, bir işlev çağrısı olarak ifade edilemeyen bir şey için bir makro kullanılmalıdır. C # 'da bir anahtar benzeri koşullu olup olmadığını bilmiyorum (C'de var olana benzer, anahtar olarak (form) {case ...}), fakat aynı sınırlamalara yakın olduğunu ve aynı sınırlamalara yaklaştığını varsayalım ( İntegral tip gerektiren).

Şimdi, bunun gibi görünen ancak dizeleri gönderen bir şey istediğinizi varsayalım. Lisp'te (özellikle, Common Lisp'te ve muhtemelen başkalarında), bu bir "makro" uzaktır ve kullanıcının eşleşmesi için sabit dizeleri (muhtemelen zor olmayan) ile sınırlandırırsanız (derleme zamanı) hesaplayabilirsiniz. hangi durumun eşleşeceğini belirlemek için minimum testler dizisi (veya bir karma tablo kullanın, kapakların saklanması, belki).

Bir işlev olarak (karşılaştırma dizesi, yürütülmesi gereken davaların ve kapanışların bir listesi) bir ifade olarak ifade etmek mümkün olsa da, muhtemelen "normal kod" gibi görünmeyecek ve lisp makrolarının kesin bir kazanım elde ettiği yer burasıdır. Muhtemelen epeyce makro veya makro benzeri, gibi taht özel formlar kullandım defun, defmacro, setf, cond, loopve daha birçok.


2

Bu, okuduğumu, kullanılan kavramların daha derin etkilerini göstermek için Lisp savunuculuğunun yüzeyinden alan en iyi açıklayıcı makale.

http://www.defmacro.org/ramblings/lisp.html

Başka bir yerde şöyle bir fikri okuduğumu hatırlıyorum: Diğer diller Lisp'in çeşitli özelliklerini benimsemiştir; çöp toplama, dinamik yazma, isimsiz fonksiyonlar, daha iyi bir C ++ / C / Algol üretmek için kapanır. Ancak Lisp'in gücünden yararlanmak için, tüm temel özelliklerine ihtiyacınız var; bu noktada, 50 yıldan uzun bir süredir bir formda veya başka bir yerde olan farklı bir dil ailesi olan Lisp'in başka bir lehçesine sahipsiniz.

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.