Saya pikir Anda bertanya tentang dua hal yang berbeda.
- Kemampuan bahasa pemrograman untuk mewakili semua programnya sebagai data.
- Penalaran tentang program sebagai data.
Untuk tujuan analitis, penting untuk memisahkannya. Saya akan fokus pada yang pertama.
Kemampuan suatu bahasa pemrograman untuk mewakili, memanipulasi (dan menjalankan) program-programnya ketika data berjalan di bawah istilah-istilah seperti meta-programming atau
homoiconicity .
Dengan cara (canggung), semua bahasa pemrograman terkenal dapat melakukan meta-pemrograman, yaitu dengan menggunakan tipe data string bersama dengan kemampuan memanggil program eksternal (kompiler, tautan, dll.) Pada string (misalnya dengan menuliskannya ke file sistem pertama). Namun, itu mungkin bukan yang Anda maksud. Anda mungkin memiliki sintaks yang bagus dalam pikiran. String bukanlah sintaks yang bagus untuk representasi program karena hampir semua string tidak mewakili program, yaitu tipe data string berisi banyak 'sampah' ketika dilihat sebagai mekanisme representasi program. Lebih buruk lagi, aljabar operasi string pada dasarnya tidak ada hubungannya dengan aljabar konstruksi program.
Apa yang mungkin ada dalam pikiran Anda adalah sesuatu yang jauh lebih baik. Misalnya jika adalah program, maka ⟨ P ⟩P⟨ P⟩ adalah , tetapi sebagai data, di tangan untuk manipulasi dan analisis. Ini sering disebut kutipan . Dalam praktiknya, kutipan tidak fleksibel, jadi kami menggunakan kuasi-kutip , yang merupakan generalisasi kutipan di mana kutipan dapat memiliki 'lubang' di mana program dapat dijalankan yang menyediakan data untuk 'mengisi' lubang. Misalnya ⟨ i fP adalah kuasi-kutipan mewakili bersyarat di mana bukan kondisi kita memiliki lubang [ ⋅ ] . Jika program M mengevaluasi data ⟨ x >
⟨ if[⋅ ]t he n7e l se8 + 9 ⟩
[ ⋅ ]M. , maka kuasi-kutipan
⟨ i f⟨ X > 0 ⟩⟨ I f[ M]t h e n7e l s e8 + 9 ⟩
mengevaluasi data
⟨ I fx > 0t h e n7e l s e8 + 9 ⟩ .
(Perhatikan bahwa adalah program normal (bukan program sebagai data) yang mengembalikan program yang dikutip, yaitu program sebagai data.) Agar ini berfungsi, Anda memerlukan tipe data untuk mewakili program. Biasanya tipe data itu disebut AST (pohon sintaksis abstrak), dan Anda bisa melihat (kuasi-) kutipan sebagai mekanisme singkatan untuk AST.M.
Beberapa bahasa pemrograman menawarkan kuasi-kutip dan fitur lain untuk meta-pemrograman. Itu Lisp dengan fungsi makro yang memelopori kemampuan ini untuk memperlakukan program sebagai data. Mungkin sayangnya, kekuatan macro berbasis Lisp telah lama dilihat untuk beristirahat sebagian besar pada sintaksis minimalis Lisp; Tidak sampai MetaML (1) yang modern, bahasa yang kaya secara sintaksis terbukti mampu meta-pemrograman. Sejak saat itu, MetaOCaml (2) (keturunan MetaML, penting untuk terobosannya dalam pencarian yang masih berlangsung untuk menyelesaikan masalah bagaimana mengetik program sebagai data), Template Haskell (3) dan Converge (4) (bahasa pertama untuk mendapatkan semua fitur meta-pemrograman kunci tepat menurut saya) telah menunjukkan bahwa berbagai bahasa pemrograman modern dapat menampung meta-pemrograman. Penting untuk menyadari bahwa kita dapat mengambilsetiap bahasa pemrograman dan mengubahnya menjadi bahasa meta-pemrograman L m p
yang LL.L.m pL. bersama-sama dengan kemampuan yang mewakili (dan mengevaluasi) program sendiri sebagai data.
Mewakili hasil dari menjalankan program, diberikan sebagai data, dicapai dengan menambahkan fungsi yang mengambil program (diberikan sebagai data) sebagai input dan menjalankannya, mengembalikan hasilnya. Misalnya jika P adalah program evaluasi untuk 17 dan ⟨ P ⟩ , yang (kuasi) versi dikutip dari P , yaitu P sebagai data, maka e v a l ( ⟨ P ⟩ )e v a l (⋅)P⟨ P⟩PPe v a l (⟨P⟩ ) juga kembali 17. Ada segala macam seluk-beluk di sini bahwa saya mengabaikan di sini seperti pertanyaan kapanprogram meta-program sedang dievaluasi (memunculkan perbedaan antara waktu kompilasi dan meta-program terprogram), apa yang harus dilakukan dengan tipe atau evaluasi gagal, apa yang terjadi pada variabel terikat dan bebas dalam proses perpindahan dari ke ⟨ P ⟩P⟨ P⟩ atau sebaliknya.
Adapun dimensi kedua, alasan tentang program yang diberikan sebagai data. Segera setelah Anda dapat mengubah program menjadi data, mereka adalah data 'normal' dan dapat dianggap sebagai data. Anda dapat menggunakan segala macam teknologi prover, misalnya tipe atau kontrak yang bergantung atau prover teorema interaktif atau alat otomatis, seperti yang ditunjukkan Joshua. Namun Anda harus mewakili semantik bahasa Anda dalam proses penalaran. Jika bahasa itu, seperti yang Anda butuhkan, memiliki kemampuan meta-pemrograman, hal-hal dapat menjadi sedikit rumit dan tidak banyak pekerjaan yang telah dilakukan dalam arah ini, dengan (5) menjadi satu-satunya logika program untuk tujuan ini. Ada juga karya Curry-Howard berdasarkan alasan tentang pemrograman-meta (6, 7, 8). Perhatikan bahwa pendekatan berbasis logika ini, dan pendekatan berbasis tipe (2) memang bisa mengekspresikan properti yang berlaku untuk semua tahap meta-pemrograman di masa depan. Terlepas dari (2) tidak ada kertas yang telah dilaksanakan.
Singkatnya: apa yang Anda minta telah diterapkan, tetapi cukup halus, dan masih ada pertanyaan terbuka, khususnya yang berkaitan dengan jenis dan penalaran yang efisien.
W. Taha. Pemrograman Multi-Tahap: Teori dan Aplikasi-nya .
W. Taha dan MF Nielsen. Pengklasifikasi lingkungan .
T. Sheard dan S. Peyton Jones. Meta-pemrograman template untuk Haskell .
L. Tratt. Kompilasi meta-pemrograman dalam bahasa OO yang diketik secara dinamis .
M. Berger, L. Tratt, Logika Program untuk Pemrograman Meta Homogen .
R. Davies, F. Pfenning, Analisis modal perhitungan bertahap .
R. Davies, Pendekatan Temporal-Logika untuk Analisis Binding-Time .
T. Tsukada, A. Igarashi. Dasar logis untuk pengklasifikasi lingkungan .