Bayt kodu dokuma vs Lisp makroları


11

Ben insanların intercept fonksiyon çağrıları, günlük kaydı kodu eklemek, vb gibi şeyler yapmak için bayt kodu dokuma kullanan Java ve C # gibi diller için yazmış kütüphaneler hakkında okuyordum Ayrıca bir Lisp / Clojure makroları üzerinde okudum onları nasıl kullanacağını daha iyi anlamaya çalışmak. Makrolar hakkında ne kadar çok okursam, bayt kod dokuma kitaplıklarıyla aynı işlevsellik sağlar gibi görünüyor. İşlevsel olarak, derleme zamanında kod manipüle yeteneği demek.

İncelediğim kütüphanelere örnek olarak AspectJ, PostSharp ve Cecil verilebilir.

Biriyle değil diğeriyle yapılabilecek bir şey var mı? Aynı problemleri gerçekten çözüyorlar mı yoksa elma ve portakalları mı karşılaştırıyorum?


2
bayt kod dokuma dinamik bir dile ihtiyaç duyduğunuzda ancak statik olarak yazılan bir dille sıkıştığında bir
çözümdür

2
@kevincline bu eski savaşı ciddi bir şekilde başlatmaya mı çalışıyorsunuz?
Jonathan Henson

Yanıtlar:


10

Bayt kodu dokuma ve makrolar iki farklı şeydir.

Bayt kodu dokuma, işlev çağrılarını engellemenin bir yoludur, böylece işlev yürütülmeden önce veya sonra bir işlev çağrısına bir tür işlevsellik (genellikle günlük kaydı gibi kesişen bir endişe) enjekte edebilirsiniz. Bayt kodu dokuma bayt kodu düzeyinde yapılır, yani derlemeden sonra gerçekleşir . İşlevin kendisi etkilenmez. Aspect Oriented Programming'in kullandığı tekniklerden biri budur .

Makrolar bir dilin sözdizimini genişletmenin bir yoludur. En basit haliyle, bir makro tuş vuruşlarını kaydetmenin ve daha sonra bir kısayol tuşu kullanarak oynatmanın bir yoludur. Dil makroları da benzer şekilde çalışır; bir tür makro genişletmenin yerine kullanılan bir anahtar kelime veya başka bir sözdizimi oluşturmasının yerini alır. Bu elbette aşırı derecede basitleştirilmiştir; Lisp'e özgü bir makronun daha iyi bir örneğini burada bulabilirsiniz .


Bunun AOP'yi uygulamanın önemli bir yolu olduğunu belirten +1.
Jonathan Henson

Ve işlemler ... işlemleri unutmayalım.
Jonathan Henson

3
LISP makroları 'tuş vuruşlarını kaydetmenin bir yolu' gibi bir şey değildir.
kevin cline

1
Peki IMO cevabında bazı temel kavramlar eksik, bunlar şunlar olabilir: AST, yansıma, Metacircularity.
AndreasScheinert

2
@AndreasScheinert: OP bunlardan hiçbirini sormadı. Bu bir tez değil; bu sadece OP'nin sorusuna bir cevap.
Robert Harvey

5

Aynı amaçla kullanılabilmelerine rağmen, LISP makroları Java bayt kodu dokuma eklentilerinden oldukça farklıdır. LISP makroları, LISP sözdizimini LISP kaynak kodu düzeyinde genişletir. LISP makroları diğer LISP kodlarıyla aynı düzeyde yazıldığından, yaygın olarak kullanılan bir dil özelliğidir.

Java bayt kodu dokuma eklentileri JVM düzeyinde çalışır. Birçok Java programcısı başkaları tarafından yazılan bayt kodu dokuma eklentilerini kullanabilirken, çok az Java programcısı kendi bayt kodu dokuma eklentilerini yazar.

Java derleyici eklentileri tarafından yapılan bazı çalışmalar dinamik dillerde kolayca yapılabilir. İşlev çağrısı müdahalesi özellikle basittir.


İkisi arasındaki teknik farklılıkları anlıyorum. Soruya üst düzey bir bakış açısıyla bakmaya çalışıyordum. Her iki araç da aynı hedeflere ulaşmak için kodu manipüle edebilir mi? Makroların bayt kod manipülasyonunun çözebileceği herhangi bir sorun var mı (aklı başında ve uygun maliyetli bir şekilde)? Ben de bunun için gidiyordum.
mortalapeman

@mortalapeman: bayt kodu değişikliği yoluyla Java ve C # 'da mümkün olan manipülasyonların hepsi doğrudan Lisp, Ruby, Python, Lua, Javascript gibi dillerde yapılabilir ... Bir LISP makrosunun bayt yoluyla yapabileceği her şeyi yapmak mümkündür. -kod manipülasyonu, ama pratikte bu gerçekleşmez.
kevin cline

4

Lisp makroları kaynak kodu düzeyinde çalışıyor. Bir makro parçasını bir kod parçasının etrafına sararsanız, birçok şey yapabilirsiniz. Kaynak kodunu ayrıştırma, kod ekleme, kodu yeniden yazma vb.

İşlev çağrılarını değiştirmek istiyorsanız, Lisp genellikle iki mekanizma kullanır:

  • geç bağlama sembolleri. Bir sembole bağlı işlevi değiştirebilirsiniz. Bir sembolün içinden geçen her fonksiyon çağrısı daha sonra yeni fonksiyonu kullanır.

  • Lisp uygulamaları bazen 'tavsiye' adı verilen bir özellik sağlar. Bu, çağrıların öncesinde, sonrasında veya çevresinde kod yürütülmesine izin verir. Örneğin LispWorks'te: Tavsiye .

Böylece, düşük seviyeli kod manipülasyonu olmadan çağrıları kesebilirsiniz.

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.