Ada banyak bahasa yang memungkinkan semacam pemrograman . Secara khusus, saya terkejut melihat tidak ada jawaban yang berbicara tentang keluarga bahasa Lisp .
Dari wikipedia:
Metaprogramming adalah penulisan program komputer dengan kemampuan untuk memperlakukan program sebagai datanya.
Kemudian dalam teks:
Lisp mungkin merupakan bahasa klasik dengan fasilitas pemrograman metaprogram, baik karena didahulukan secara historis maupun karena kesederhanaan dan kekuatan metaprogrammingnya.
Bahasa yang gampang
Intro cepat dibuat untuk Lisp berikut.
Salah satu cara untuk melihat kode adalah sebagai rangkaian instruksi: lakukan ini, lalu lakukan itu, lalu lakukan hal lain ini ... Ini adalah daftar! Daftar hal-hal yang harus dilakukan program. Dan tentu saja Anda dapat memiliki daftar di dalam daftar untuk mewakili loop dan seterusnya ..
Jika kita mewakili daftar yang berisi unsur-unsur a, b, c, d seperti ini: (abcd) kita mendapatkan sesuatu yang tampak seperti Lisp fungsi panggilan, di mana a
adalah fungsi, dan b
, c
, d
adalah argumen. Jika fakta khas "Hello World!" Program dapat ditulis seperti ini:(println "Hello World!")
Tentu saja b
, c
atau d
dapat berupa daftar yang mengevaluasi sesuatu juga. Berikut ini: (println "I can add :" (+ 1 3) )
kemudian akan mencetak "" Saya dapat menambahkan: 4 ".
Jadi, sebuah program adalah serangkaian daftar bersarang, dan elemen pertama adalah fungsi. Berita baiknya adalah kita dapat memanipulasi daftar! Jadi kita bisa memanipulasi bahasa pemrograman.
Keuntungan Lisp
Lisps tidak begitu banyak bahasa pemrograman seperti halnya toolkit untuk membuat bahasa pemrograman. Bahasa pemrograman yang dapat diprogram.
Ini tidak hanya jauh lebih mudah di Lisps untuk membuat operator baru, juga hampir mustahil untuk menulis beberapa operator dalam bahasa lain karena argumen dievaluasi ketika diteruskan ke fungsi.
Misalnya dalam bahasa mirip C, misalkan Anda ingin menulis if
operator sendiri, seperti:
my-if(condition, if-true, if-false)
my-if(false, print("I should not be printed"), print("I should be printed"))
Dalam hal ini kedua argumen akan dievaluasi dan dicetak, dalam urutan yang tergantung pada urutan evaluasi argumen.
Di Lisps, menulis operator (kami menyebutnya makro) dan menulis fungsi adalah tentang hal yang sama dan digunakan dengan cara yang sama. Perbedaan utama adalah bahwa parameter untuk makro tidak dievaluasi sebelum diteruskan sebagai argumen ke makro. Ini penting untuk dapat menulis beberapa operator, seperti di if
atas.
Bahasa dunia nyata
Menunjukkan betapa tepatnya sedikit di luar ruang lingkup di sini, tetapi saya mendorong Anda untuk mencoba pemrograman dalam satu Lisp untuk mempelajari lebih lanjut. Misalnya, Anda dapat melihat:
- Skema , Lisp tua, cukup "murni" dengan inti kecil
- Lisp umum, Lisp lebih besar dengan sistem objek terintegrasi dengan baik, dan banyak implementasi (standar-ANSI)
- Racket Lisp yang diketik
- Clojure favorit saya, contoh di atas adalah kode Clojure. Lisp modern yang berjalan di JVM. Ada beberapa contoh makro Clojure pada SO juga (tapi ini bukan tempat yang tepat untuk memulai. Saya akan melihat 4clojure , braveclojure atau clojure koans pada awalnya)).
Oh, ngomong-ngomong, Lisp berarti LISt Processing.
Mengenai contoh Anda
Saya akan memberikan contoh menggunakan Clojure di bawah ini:
Jika Anda dapat menulis suatu add
fungsi di Clojure (defn add [a b] ...your-implementation-here... )
, Anda dapat menamainya +
seperti itu (defn + [a b] ...your-implementation-here... )
. Ini sebenarnya apa yang dilakukan dalam implementasi nyata (tubuh fungsi sedikit lebih terlibat tetapi definisi dasarnya sama dengan yang saya tulis di atas).
Bagaimana dengan notasi infiks? Nah Clojure menggunakan prefix
notasi (atau Polandia), jadi kita bisa membuat infix-to-prefix
makro yang akan mengubah kode awalan menjadi kode Clojure. Yang sebenarnya sangat mudah (sebenarnya ini adalah salah satu latihan makro di koalisi clojure)! Itu juga bisa dilihat di alam liar, misalnya lihat Incanter $=
macro .
Ini adalah versi paling sederhana dari koans yang dijelaskan:
(defmacro infix [form]
(list (second form) (first form) (nth form 2)))
;; takes a form (ie. some code) as parameter
;; and returns a list (ie. some other code)
;; where the first element is the second element from the original form
;; and the second element is the first element from the original form
;; and the third element is the third element from the original form (indexes start at 0)
;; example :
;; (infix (9 + 1))
;; will become (+ 9 1) which is valid Clojure code and will be executed to give 10 as a result
Untuk mengarahkan poin lebih jauh, beberapa Lisp mengutip :
“Bagian dari apa yang membuat Lisp istimewa adalah ia dirancang untuk berkembang. Anda dapat menggunakan Lisp untuk menentukan operator Lisp baru. Sebagai abstraksi baru menjadi populer (pemrograman berorientasi objek, misalnya), selalu ternyata mudah untuk mengimplementasikannya dalam Lisp. Seperti DNA, bahasa seperti itu tidak ketinggalan gaya. ”
- Paul Graham, ANSI Common Lisp
“Memprogram di Lisp seperti bermain dengan kekuatan primordial alam semesta. Rasanya seperti kilat di antara ujung jari Anda. Tidak ada bahasa lain yang terasa dekat. ”
- Glenn Ehrlich, Jalan Menuju Lisp