Ini adalah kelanjutan dari artikel
“Mengapa Racket? Kenapa Tertidur? ” Saya menulis sekitar setahun setelah saya menemukan
Racket . Sebagai seorang pemula, saya tidak bisa memahami pujian yang mengalir pada Lisp dari semua sisi. Saya tidak tahu harus berpikir apa. Bagaimana memahami bahwa Lisp pada akhirnya akan menyebabkan
"pencerahan yang mendalam .
" Oke, bro, katamu.
Saya punya pertanyaan sederhana:
apa gunanya? Dalam artikel sebelumnya, saya mencoba menjawabnya dan merangkum alasan mengapa seseorang ingin belajar Lisp atau, khususnya, Racket.
Saya telah menyusun daftar fitur
sembilan bahasa yang paling berharga bagi saya sebagai pemula untuk Racket. Misalnya, fitur nomor 5 adalah "penciptaan bahasa pemrograman baru". Metode ini juga disebut
pemrograman berorientasi bahasa , atau
JOP .
Sejak itu, IOP telah menjadi bagian favorit saya dari Racket, dan saya berbagi kekaguman saya dalam buku online
Beautiful Racket , yang menjelaskan teknik ROP dan alat Racket.
Salah satu contoh dalam pekerjaan saya adalah
Pollen . Saya menulis bahasa pemrograman ini untuk tipografi yang nyaman dari buku online saya. Di Pollen, paragraf sebelumnya diprogram sebagai berikut:
#lang pollen ◊link["https://beautifulracket.com/appendix/why-racket-why-lisp.html#so-really-whats-in-it-for-me-now"]{ }, Racket. , № 5 — « ». ◊em{- }, ◊em{}.
Contoh lain adalah
brag , generator parser (dengan gaya
lex/yacc
), yang menggunakan
tata bahasa BNF sebagai kode sumber. Contoh sederhana untuk bahasa
bf :
#lang brag bf-program : (bf-op | bf-loop)* bf-op : ">" | "<" | "+" | "-" | "." | "," bf-loop : "[" (bf-op | bf-loop)* "]"
Kedua bahasa diimplementasikan dalam Racket dan dapat dijalankan dengan juru bahasa Racket biasa atau di dalam IDE Racket (disebut DrRacket).
Masalah utama
Namun ... Terlepas dari kenyataan bahwa buku itu telah memaksa ribuan orang untuk mulai menjelajahi Racket, kadang-kadang tampak bagi saya bahwa saya melangkah di tanah cepat yang sama dengan para penggemar Lisp yang pernah saya kritik.
Jika NOP sangat keren, lalu mengapa menghabiskan beberapa hari membaca buku. Benar? Saya bisa menjelaskan semuanya dengan singkat, tanpa basa-basi lagi. Dua pertanyaan sederhana perlu dijawab:
- Masalah apa yang paling cocok untuk pemrograman bahasa?
- Mengapa Racket terbaik untuk membuat bahasa?
Pertanyaan kedua sederhana. Yang pertama bukan. Saya ditanyai dia berkali-kali. Saya sering mengutip ungkapan
terkenal Hakim Stewart Stewart: Anda akan memahaminya ketika Anda melihatnya. Jawabannya cukup baik bagi mereka yang benar-benar tertarik. Tetapi tidak bagi mereka yang berada di pihak dan ingin mendengarkan argumen substantif.
Jadi, saya akan coba. Perlu diingat bahwa saya bukan profesor ilmu komputer dan tidak bisa berbicara tentang teori bahasa pemrograman. Sebaliknya, saya menggunakan Racket dan bahasa khusus domain (DSL) untuk tujuan praktis: pekerjaan sehari-hari saya bergantung pada mereka. Karena itu, saya akan fokus pada aspek praktis.
Jawaban singkat
- JOP sebenarnya adalah metode desain antarmuka. Ini sangat ideal untuk tugas-tugas yang membutuhkan notasi minimal dengan tetap menjaga akurasi maksimum . Notasi minimal berarti satu-satunya notasi yang diizinkan. Tidak lebih. Presisi maksimum, yaitu, makna notasi ini, persis seperti yang Anda katakan. Tidak ada ambiguitas atau pola. TIO mencapai titik seperti tidak ada yang lain.
(Tidak sabar dapat beralih ke kategori tugas tertentu yang akan mendapat manfaat dari NOP).
- Racket sangat ideal untuk OOP karena sistem makronya . Mereka bekerja dalam gaya kompiler, menyederhanakan konversi kode. Sistem makro Racket lebih baik daripada yang lain.
Pada titik ini, setengah dari pembaca artikel akan ingin menerbitkan komentar anonim yang mengkritik tesis saya. Tetapi harap diingat: bagaimanapun juga, saya menang. JOP dan Racket telah sangat meningkatkan produktivitas pemrograman saya. Saya senang berbagi pengetahuan ini sehingga Anda juga dapat memanfaatkan manfaat ini. Tetapi saya juga akan senang jika alat ini tetap menjadi senjata rahasia saya. Dalam hal ini, saya akan tetap di 0,01% dari programmer paling produktif, mendapatkan hasil yang lebih mengesankan dan menguntungkan daripada 99,9% sisanya
Jadi pilihan ada di tangan Anda.
Jawaban panjang
Jika Anda memikirkan pertanyaan-pertanyaan paling penting, mereka sampai pada satu pertanyaan meta: mengapa sulit untuk menjelaskan manfaat senjata nuklir?
Mungkin ketika kita berbicara tentang
bahasa , istilah itu penuh dengan harapan tentang apa bahasa itu dan apa fungsinya. Sementara kita berada di dalam paradigma ini, sulit untuk memahami nilai bahasa pemrograman.
Tetapi jika Anda mengurangi skala dan menganggap bahasa sebagai bagian dari kategori yang lebih luas dari antarmuka manusia-komputer, maka lebih mudah untuk melihat keuntungan spesifik dari OOP. Jadi mari kita lakukan.
Bahasa umum dan bahasa khusus domain
Pertama, terminologi kecil. Pemrograman berorientasi bahasa (juga dikenal sebagai OOP) adalah ide untuk memecahkan masalah pemrograman dengan menciptakan bahasa baru, dan kemudian menulis program di atasnya. Seringkali "bahasa kecil" seperti itu disebut bahasa khusus domain (DSL).
Seperti namanya, bahasa yang berorientasi pada subjek disesuaikan dengan tugas-tugas bidang tertentu. Misalnya, PostScript, SQL,
make
, ekspresi reguler,
.htaccess
dan HTML dianggap bahasa yang berorientasi pada subjek. Mereka tidak berusaha melakukan segalanya. Sebaliknya, mereka fokus melakukan satu hal dengan baik.
Di ujung lain dari spektrum
adalah bahasa tujuan umum . Di sini kita melihat C, Pascal, Perl, Java, Python, Ruby, Racket, dll. Mengapa mereka tidak dianggap berorientasi pada subjek? Karena mereka memposisikan diri untuk berbagai tugas komputasi.
Dalam praktiknya, bahasa serba guna sering berspesialisasi dalam bidang tertentu. Misalnya, C lebih baik daripada yang lain untuk pemrograman sistem. Perl - untuk skrip dalam administrasi sistem. Python menonjol sebagai bahasa untuk pemula. Racket untuk pemrograman berorientasi bahasa. Dalam setiap kasus, ini adalah apa bahasa yang awalnya dirancang untuk.
Ada garis tipis antara DSL dan bahasa tujuan umum. Misalnya, Ruby dibuat sebagai bahasa tujuan umum, tetapi menjadi populer terutama untuk aplikasi web melalui hubungannya dengan Ruby on Rails. Sebaliknya, JavaScript pada awalnya adalah bahasa yang berorientasi pada subjek untuk skrip browser web. Tapi dia bermutasi seperti virus, dan sejak itu telah berkembang jauh melampaui tugas aslinya.
Apa itu bahasa?
Jika seluruh spektrum luas ini disebut bahasa, lalu apa saja fitur yang menentukan dari bahasa tersebut?
Saya tahu apa yang Anda pikirkan: “Di sinilah Anda salah. HTML bukan bahasa. Ini hanya markup. Dia tidak bisa mendeskripsikan algoritme. ” Atau: “Ekspresi reguler bukan bahasa. Mereka tidak bekerja sendiri. Itu hanya sintaks untuk bahasa lain. "
Dulu saya juga berpikir begitu. Tetapi semakin dekat saya melihat, semakin kabur perbedaan-perbedaan ini. Dengan demikian, pernyataan utama pertama saya (dari tiga): bahasa pemrograman pada dasarnya merupakan media pertukaran -
sistem notasi yang dapat dimengerti oleh orang dan komputer .
Sistem notasi (notasi) berarti bahasa tersebut memiliki sintaksis. "Jelas" berarti bahwa dengan sintaksnya bahasa menyampaikan
makna (atau
semantik , jika Anda menggunakan kata yang lebih mewah). Definisi ini mencakup semua bahasa pemrograman untuk tujuan umum. Dan semua DSL. (Tapi tidak setiap aliran data, yang akan dibahas lebih detail nanti).
(Omong-omong, meskipun "pemrograman" dan "bahasa" adalah kata-kata yang digunakan secara bersama-sama, bahasa ini tidak hanya digunakan oleh orang-orang untuk memprogram komputer. Kadang-kadang mereka digunakan oleh komputer untuk berkomunikasi dengan kami (misalnya, ekspresi S), kadang-kadang untuk berkomunikasi satu sama lain (misalnya, XML, JSON, HTML.) Jelas, tampaknya salah untuk mengecualikan fitur-fitur ini. Tetapi dalam praktiknya, ya - apa yang biasanya kita lakukan dengan bahasa pemrograman, sebenarnya, pemrograman.)
Pertimbangkan kode HTML: cara untuk memberi tahu komputer - khususnya browser web - cara menggambar halaman web. Ini adalah sistem notasi (kurung sudut, tag, atribut, dll.) Yang dapat dimengerti oleh manusia dan komputer (atribut
charset
menunjukkan pengkodean karakter, tag
p
berisi paragraf, dll.).
Ini adalah halaman HTML kecil:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>My web page</title> </head> <body> <p>Hello <strong>world</strong></p> </body> <html>
Misalkan Anda tidak setuju bahwa HTML adalah bahasa pemrograman. Bagus Kami akan menampilkan halaman kami dengan Python. Ini adalah bahasa pemrograman yang nyata, bukan?
print "<!DOCTYPE html>" print "<html>" print "<head>" print "<meta charset=\"UTF-8\">" print "<title>My web page</title>" print "</head>" print "<body>" print "<p>Hello <strong>world</strong></p>" print "</body>" print "<html>"
Jika Python adalah bahasa pemrograman, tetapi HTML tidak, maka sampel Python ini adalah sebuah program, tetapi sampel HTML bukan.
Jelas, ini adalah perbedaan yang tersiksa. Di sini pythonization tidak menambahkan apa pun kecuali kompleksitas dan stereotip. Hal yang mengasyikkan adalah bahwa satu-satunya konten semantik yang menarik dalam program Python - dari sudut pandang mengelola browser web - adalah bahwa konten tersebut disematkan dalam HTML (mungkin tag HTML seperti
DOCTYPE
,
meta
, dan
strong
dapat dianggap sebagai fungsi yang mengambil argumen). Logika membuat kita menyimpulkan bahwa HTML, meskipun lebih sederhana dan kurang fleksibel, masih merupakan bahasa pemrograman.
Bahasa Tertanam
Contoh dengan HTML dan Python kami buat. Tetapi menanamkan DSL dalam bahasa lain ada di mana-mana. Bahasa yang digunakan dengan cara ini disebut
tertanam . Mereka mewakili bentuk pemrograman bahasa yang paling umum. Sebagai seorang programmer, Anda telah mengandalkan JOP selama bertahun-tahun, bahkan jika Anda tidak tahu namanya.
Misalnya, ekspresi reguler (contoh lain:
printf
untuk string pemformatan, CLDR untuk pola tanggal / waktu, SQL). Kami tidak dapat menganggap ekspresi reguler sebagai bahasa independen. Tetapi setiap programmer tahu apa itu:
^fo+(bar)*$
Selain itu, Anda mungkin dapat memasukkan ekspresi reguler ini dalam bahasa pemrograman favorit Anda dan itu hanya akan berfungsi. Perilaku konsisten ini hanya dimungkinkan karena notasi ekspresi reguler adalah bahasa eksternal (
POSIX ).
Seperti halnya HTML, kita dapat menulis ekspresi yang setara dalam notasi bahasa host. Misalnya, Racket mendukung
Skeme regular expressions (SRE): ini adalah ekspresi reguler dengan notasi
ekspresi-S . Template di atas akan ditulis seperti ini:
(seq bos "f" (+ "o") (* (submatch "bar")) eos)
Tetapi programmer Racket jarang menggunakan ekspresi SRE. Mereka terlalu panjang dan sulit untuk diingat.
Contoh lain yang ada di mana-mana dari DSL yang disematkan: ekspresi matematika. Setiap programmer tahu apa artinya ini:
(1 + 2) * (3 / 4) - 5
Ekspresi matematika saja tidak membuat program yang menarik. Kita perlu menggabungkannya dengan konstruksi bahasa lain. Tetapi, seperti halnya ekspresi reguler, ini adalah catatan yang ergonomis dan praktis. Ekspresi matematika memiliki notasi dan makna mereka sendiri yang dapat dimengerti oleh orang dan komputer, sehingga mereka memenuhi syarat sebagai bahasa bawaan yang terpisah.
Apakah Anda bercanda bahwa HTML adalah pemrograman?
Bukan itu. Saya menegaskan bahwa HTML (baik ekspresi reguler maupun matematika) memenuhi syarat sebagai bahasa pemrograman yang belum sempurna. Ini berarti bahwa menulis HTML (atau ekspresi reguler atau ekspresi matematika) memenuhi syarat sebagai pemrograman dasar.
Tolong jangan panik. Tentu saja, seorang "programmer" di LinkedIn dengan pengetahuan hanya HTML dan aritmatika, ini omong kosong (walaupun dalam seminggu ia mungkin akan mendapatkan pekerjaan sebesar $ 180 ribu). Tapi ini adalah masalah terpisah, apa artinya "programmer" di pasar tenaga kerja. Kami tidak membicarakan hal itu.
Turing Totality Trap
Jika definisi bahasa pemrograman ini masih mengganggu Anda, mungkin Anda berpikir bahwa bahasa pemrograman nyata harus mengekspresikan semua algoritma yang mungkin - yaitu, itu harus
Turing lengkap .
Saya mengerti bahwa secara intuitif pemikiran seperti itu menunjukkan dirinya. Setiap bahasa pemrograman tujuan umum Turing lengkap.
Tetapi masalahnya adalah bahwa ini adalah bar rendah. Kelengkapan Turing adalah metrik teknis yang tidak sesuai dengan penggunaan bahasa di dunia nyata. Sebagai contoh, ekspresi reguler tidak Turing lengkap, tetapi mereka berguna ketika mengekspresikan banyak perhitungan dengan notasi minimal. HTML juga Turing tidak lengkap, tetapi ini adalah cara yang berguna untuk mengontrol browser. Sebaliknya, bahasa
bf adalah Turing yang lengkap, tetapi bahkan tugas yang paling sepele membutuhkan kilometer kode yang tidak bisa dilewati.
Batasan bahasa
Apakah ada yang masuk dalam definisi bahasa saya? Tidak.
- Format data biner tidak dianggap sebagai bahasa. Misalnya, file
jpeg
. Meskipun komputer dapat memahaminya, seseorang tidak. Atau PDF: jika Anda meretasnya, ada beberapa bagian di dalamnya yang dapat dibaca manusia. Tapi ini karena cara kerja PDF. Tidak ada gunanya menulis ide menggunakan konstruk PDF.
- File teks bukan bahasa. Misalkan kita memiliki file dengan Homer's Iliad. Kita manusia dapat membaca dan memahaminya. Meskipun komputer dapat dengan mudah memproses file dengan, misalnya, mencetak kontennya, teks di dalamnya tidak dapat dipahami oleh komputer.
- Antarmuka pengguna grafis bukan bahasa. Ya, ini adalah sistem notasi (yang mengandalkan teks dan gambar). Tetapi mereka hanya bisa dimengerti oleh orang-orang. Komputer menggambar GUI tetapi tidak memahaminya.
Bahasa sebagai Antarmuka
Di atas, saya menggambarkan bahasa pemrograman sebagai "media pertukaran" antara orang dan komputer. Dengan demikian, bahasa masuk ke dalam kategori yang lebih luas, yang kami sebut
antarmuka .
Ini mengarah pada pernyataan dasar kedua (dari tiga): bahwa
pemrograman bahasa pada dasarnya adalah metode mendesain antarmuka . Jika Anda suka memikirkan antarmuka, Anda akan menyukai JOP. Jika tidak, Anda masih akan menyukai JOP karena memungkinkan antarmuka yang tidak dapat dicapai.
Salah satu contoh favorit saya dari bahasa sebagai antarmuka adalah
sesumbar , bahasa generator parser yang dibuat dengan Racket. Jika Anda pernah menggunakan lex / yacc toolchain, Anda tahu bahwa seringkali tujuannya adalah untuk menghasilkan parser dari
tata bahasa BNF . Misalnya, untuk
bf, terlihat seperti ini:
bf-program : (bf-op | bf-loop)* bf-op : ">" | "<" | "+" | "-" | "." | "," bf-loop : "[" (bf-op | bf-loop)* "]"
Untuk membuat parser dalam bahasa tujuan umum, Anda perlu menerjemahkan tata bahasa ini menjadi sekelompok kode asli. Ini adalah pekerjaan yang membosankan. Dan tidak ada gunanya - bukankah kita sudah menulis tata bahasa? Kenapa melakukannya lagi?
Namun,
brag
memenuhi keinginan kami. Untuk membuat parser, kita cukup menambahkan baris
#Lang brag
ke file, yang secara ajaib mengubah tata bahasa BNF ke kode sumber
brag
:
#Lang brag bf- : (Bf-op | Bf-loop)* bf-op : ">" | "<" | "+" | "-" | "."| "," Bf-loop : "["(Bf-op | Bf-loop)* "]"
Selesai! Saat dikompilasi, file ini mengekspor fungsi
parse
, yang mengimplementasikan tata bahasa BNF ini.
Ini adalah salah satu contoh favorit saya karena tidak dapat disangkal unggul dari opsi lain. Selain itu, dengan bahasa tujuan umum, antarmuka seperti itu praktis tidak mungkin.
Tetapi seorang programmer JOP terus-menerus membuat antarmuka seperti itu.
Di mana bahasa adalah antarmuka terbaik
Ini membawa saya pada tesis dasar ketiga dan terakhir saya bahwa
bahasa memiliki kelebihan unik dibandingkan antarmuka . Tentu saja, kategori di bawah ini tidak lengkap atau eksklusif. Tetapi saya menemukan bahwa IOP memiliki banyak hal untuk ditawarkan dalam situasi seperti ini:
1. Saat Anda ingin membuat antarmuka untuk programmer yang kurang terampil, atau yang bukan programmer, atau programmer yang malas (jangan meremehkan ukuran kategori yang terakhir).
Misalnya, Racket memiliki
perpustakaan aplikasi web yang canggih. Tetapi server web sederhana juga dapat dengan cepat mulai menggunakan bahasa
web-server/insta
:
#lang web-server/insta (define (start request) (response/xexpr '(html (body "Hello LOP World"))))
Matthew Flatt dalam artikelnya
"Creating Languages in Racket" menunjukkan bahasa yang menghasilkan petualangan teks yang dapat diputar. Seperti
brag
, itu lebih mirip spesifikasi daripada program, tetapi berfungsi:
#lang txtadv ===VERBS=== north, n "go north" south, s "go south" get _, grab _, take _ "get" ===THINGS=== ---cactus--- get "Ouch!" ===PLACES=== ---desert--- "You're in a desert. There is nothing for miles around." [cactus, key] north meadow south desert
2. Ketika Anda ingin menyederhanakan notasi. Salah satu contohnya adalah ekspresi reguler. Contoh lain adalah
Pollen bahasa berorientasi subjek saya untuk menulis buku online. Pollen mirip dengan Racket, hanya di sini Anda mulai bekerja dalam mode teks dan menggunakan karakter khusus untuk menunjukkan perintah Racket yang tertanam dalam konten (Pollen didasarkan pada bahasa dokumentasi Racket yang disebut
Scribble , yang mengambil sebagian besar beban). Jadi, awal paragraf ini diprogram sebagai berikut:
. — . — - ◊link["https://pollenpub.com/"]{Pollen} -.
Pollen peduli tentang menempelkan semua tag yang diperlukan dan mengubahnya menjadi HTML yang sempurna. Saya masih memiliki semua kelebihan markup manual (kontrol penuh atas halaman), tetapi tidak ada kekurangan (katakanlah, saya tidak dapat secara tidak sengaja meninggalkan tag yang tidak tertutup).
Contoh lain dari notasi yang disederhanakan adalah
lindenmayer
, generasi fraktal
sistem Lindenmayer dan bahasa gambar, seperti ini:
Dalam Racket biasa, program Lindenmayer mungkin terlihat seperti ini:
#lang racket/base (require lindenmayer/simple/compile) (define (finish val) (newline)) (define (A value) (display 'A)) (define (B value) (display 'B)) (lindenmayer-system (void) finish 3 (A) (A -> AB) (B -> A))
Tetapi Anda dapat menggunakan notasi yang disederhanakan dengan hanya mengubah notasi
#lang
di bagian atas file:
#lang lindenmayer/simple ## axiom ## A ## rules ## A -> AB B -> A ## variables ## n=3
Bahasa ini mengasumsikan bahwa Anda sudah terbiasa dengan sistem-L. Tetapi notasi yang disederhanakan memudahkan untuk menuliskan keinginan Anda dalam program yang melakukan apa yang Anda inginkan.
3. Saat Anda ingin bekerja dengan notasi yang ada. Kami melihat di atas bagaimana
brag
menggunakan tata bahasa BNF sebagai kode sumber.
#lang brag bf-program : (bf-op | bf-loop)* bf-op : ">" | "<" | "+" | "-" | "." | "," bf-loop : "[" (bf-op | bf-loop)* "]"
Contoh lain. Orang yang mencoba Pollen berkata, "Ya, itu bagus, tapi saya lebih suka Markdown." Tidak masalah:
pollen/markdown
adalah dialek Pollen yang menawarkan semantik Pollen tetapi menerima notasi Markdown biasa:
. — . — - [Pollen]("https://pollenpub.com/") -.
Hal yang paling menyenangkan? Saya menulis dialek ini hanya dalam satu jam, menggabungkan
parser Markdown dengan kode yang ada.
4. Jika Anda ingin membuat target menengah untuk bahasa lain. JSON, YAML, S-expressions, dan XML adalah semua bahasa yang berorientasi subjek yang menentukan format data untuk mesin baca dan tulis.
Dalam Perfect Racket, satu bahasa pelatihan disebut
jsonic
. Ini memungkinkan Anda untuk menanamkan ekspresi Racket di JSON, sehingga membuat JSON dapat diprogram. Kode sumber terlihat seperti ini:
#lang jsonic // a line comment [ @$ 'null $@, @$ (* 6 7) $@, @$ (= 2 (+ 1 1)) $@, @$ (list "array" "of" "strings") $@, @$ (hash 'key-1 'null 'key-2 (even? 3) 'key-3 (hash 'subkey 21)) $@ ]
Kompilasi ke JSON reguler:
[ null, 42, true, ["array","of","strings"], {"key-1":null,"key-3":{"subkey":21},"key-2":false} ]
5. Ketika bagian utama dari program adalah konfigurasi. Sebagai contoh, Dotfiles dapat digambarkan sebagai DSL. Contoh yang lebih kompleks dari Racket adalah Riposte Jesse Alama, bahasa untuk menguji HTTP API berbasis JSON:
#lang riposte $productId := 41966 $qty := 5 $campaignId := 1 $payload := { "product_id": $productId, "campaign_id": $campaignId, "qty": $qty } POST $payload cart/{uuid}/items responds with 200 $itemId := /items/0/cart_item_id GET cart responds with 200
Sebagai bahasa skrip miniatur, Riposte jauh lebih pintar daripada rata-rata dotfile. Itu menyembunyikan semua kode perantara yang diperlukan untuk transaksi HTTP, dan memungkinkan pengguna untuk fokus pada tes menulis. Ini masih membersihkan rumah. Tapi setidaknya Anda bisa fokus pada rumah tangga yang Anda sayangi.
Mengapa raket?
Seringkali, kritikus JOP bertanya: “Mengapa membuat bahasa yang berorientasi pada subjek? Apakah lebih mudah menulis perpustakaan asli? "
Tidak, itu tidak mudah jika Anda memiliki alat yang tepat. Racket tidak biasa: ia dirancang dari bawah ke atas khusus untuk YOP.
Dengan demikian, menerapkan DSL pada Racket lebih cepat, lebih murah, dan lebih mudah daripada alternatif. Misalnya, dalam pelajaran pertama buku saya, saya menunjukkan bagaimana mengembangkan bahasa baru dalam satu jam - bahkan jika Anda belum pernah menggunakan Racket.Di bawah penutup setiap DSL dalam Racket, kompiler sumber-ke-sumber benar-benar berfungsi , yang mengubah notasi dan semantik DSL menjadi program Racket yang setara. Untuk alasan ini, Racket DSL tidak akan dapat berjalan secepat kode C. yang ditulis secara manual. Namun, semua alat dan pustaka Racket tersedia untuk setiap DSL. Anda kehilangan produktivitas, tetapi berulang kali menang dalam kenyamanan. Dan ketika membuat DSL nyaman dan mudah, itu menjadi pilihan realistis untuk berbagai masalah yang jauh lebih luas.Jadi, untuk menjawab kritik - tidak, DSL tidak serta-merta membutuhkan lebih banyak pekerjaan daripada perpustakaan asli. Selain itu, seperti yang telah kita lihat, sebagai antarmuka, bahasa dapat melakukan apa yang tidak bisa dilakukan perpustakaan asli.Mengapa makro?
Karena semua DSL dikompilasi ke dalam Racket, programmer harus menulis beberapa transformator sintaks yang mengubah notasi DSL ke Racket asli. Konverter sintaksis ini dikenal sebagai makro . Bahkan, mereka dapat digambarkan sebagai ekstensi ke kompiler Racket.Sistem makro Racket sangat luas, elegan, dan tidak diragukan lagi adalah mutiara mahkotanya. Banyak buku saya tentang kesenangan bekerja dengan makro Racket. Saya dapat menyebutkan dua fungsi luar biasa:- Racket , . . , , Racket , , , , , . ( . « » ).
- Makro raket adalah higienis , yaitu, secara default kode yang dibuat oleh makro mempertahankan konteks leksikal dari mana makro didefinisikan. Dalam praktiknya, ini menghilangkan sejumlah besar gerakan tidak perlu yang biasanya diperlukan untuk DSL (untuk lebih jelasnya lihat bab "Hygiene" ).
Apakah mungkin untuk mengimplementasikan DSL di, katakanlah, Python? Tentu saja
Bahkan, saya menulis DSL pertama saya khusus di Python - dan masih menggunakannya dalam pekerjaan desain tipe saya . Ya itu. Satu kali sudah cukup. Sejak itu saya menggunakan Racket.Kesimpulan: kemenangan dengan YaOP
Saat ini, Anda mungkin memiliki satu dari dua reaksi:- « , , » . , . , , . . . , . .
- «, , c Racket » . , - Riposte , — ( ):
[ ] - Racket. , , - … : « API , ?» : « Riposte». , , [DSL], , . «» Racket. DSL , .
Di akhir artikel “Kenapa Racket? Kenapa Tertidur? ” Saya mengatakan bahwa bahasa Lisp "memberi Anda kesempatan untuk mengeluarkan potensi Anda sebagai seorang programmer dan pemikir dan dengan demikian meningkatkan harapan Anda tentang apa yang dapat Anda capai."IOP menawarkan kesempatan yang sama: untuk meningkatkan harapan kami mengenai apa yang bisa dilakukan oleh bahasa pemrograman untuk kami. Bahasa bukan kotak hitam. Ini adalah antarmuka yang bisa kita desain. Pada saat yang sama, kami membuka kemungkinan baru untuk apa yang dapat dilakukan dengan bantuan program.Jika Anda dapat menemukan teknik pemrograman terbaik, gunakan itu. Sekarang saya memiliki OOP dan Racket, saya tidak akan pernah kembali.Bacaan lebih lanjut