Apakah pembuatan kode sumber merupakan anti-pola?


118

Jika sesuatu dapat dihasilkan, maka hal itu adalah data, bukan kode.

Karena itu, bukankah seluruh gagasan pembuatan kode sumber ini merupakan kesalahpahaman? Yaitu, jika ada generator kode untuk sesuatu, maka mengapa tidak menjadikan sesuatu itu fungsi yang tepat yang dapat menerima parameter yang diperlukan dan melakukan tindakan yang benar bahwa kode "akan dihasilkan" akan dilakukan?

Jika itu dilakukan karena alasan kinerja, maka itu terdengar seperti kekurangan dari kompiler.

Jika sedang dilakukan untuk menjembatani dua bahasa, maka itu terdengar seperti kurangnya antarmuka perpustakaan.

Apakah saya melewatkan sesuatu di sini?

Saya tahu bahwa kode adalah data juga. Yang tidak saya mengerti adalah, mengapa menghasilkan kode sumber ? Mengapa tidak membuatnya menjadi fungsi yang dapat menerima parameter dan menindaklanjutinya?


11
Sebuah istilah yang terkait dengan pembuatan kode adalah metaprogramming
UselesssCat

4
en.wikipedia.org/wiki/Code_as_data , Lisp, FP, scripting, metaprogramming, Von Neumann / dimodifikasi Harvard arsitektur dll Ini telah ditutupi membosankan iklan . tl; dr perbedaan "kode sumber" vs "kode keluaran", "kode" vs "data" dll. dimaksudkan untuk menyederhanakan berbagai hal. Mereka seharusnya tidak dogmatis .
vaxquis

9
@ Utku, alasan yang lebih baik untuk melakukan pembuatan kode sering berhubungan dengan keinginan untuk memberikan deskripsi tingkat yang lebih tinggi daripada yang bisa diungkapkan oleh bahasa Anda saat ini . Apakah kompiler dapat atau tidak dapat membuat kode efisien tidak benar-benar ada hubungannya dengan itu. Pertimbangkan parser generator - lexer yang dihasilkan oleh flexatau parser yang dihasilkan oleh bisonhampir pasti akan lebih dapat diprediksi, lebih benar, dan sering lebih cepat untuk dieksekusi daripada setara dengan tulisan tangan dalam C; dan dibangun dari kode yang jauh lebih sedikit (dengan demikian juga lebih sedikit pekerjaan untuk dipelihara).
Charles Duffy

1
Mungkin Anda berasal dari bahasa yang tidak memiliki banyak elemen fungsional, tetapi dalam banyak bahasa fungsi adalah kelas satu - Anda dapat mengedarkannya, jadi dalam jenis kode bahasa tersebut adalah data, dan Anda dapat memperlakukannya begitu saja.
Restioson

1
@Restioson dalam kode bahasa fungsional bukan data. Fungsi kelas pertama persis berarti: Fungsi adalah data. Dan tidak perlu data yang sangat bagus: Anda tidak dapat memutasikannya sedikit saja (seperti mengubah semua penambahan dalam fungsi menjadi pengurangan, katakanlah). Kode adalah data dalam bahasa Homoiconic. (kebanyakan bahasa homoikonik memiliki fungsi kelas satu. Tetapi kebalikannya tidak benar.).
Lyndon White

Jawaban:


150

Apakah pembuatan kode sumber merupakan pola anti?

Secara teknis, jika kita menghasilkan kode, itu bukan sumber meskipun itu adalah teks yang dapat dibaca oleh manusia. Kode Sumber adalah kode asli, yang dihasilkan oleh manusia atau kecerdasan sejati lainnya, tidak diterjemahkan secara mekanis dan tidak dapat segera direproduksi dari sumber (benar) (langsung atau tidak langsung).

Jika sesuatu dapat dihasilkan, selain itu data, bukan kode.

Saya akan mengatakan semuanya adalah data . Bahkan kode sumber. Terutama kode sumber! Kode sumber hanyalah data dalam bahasa yang dirancang untuk menyelesaikan tugas pemrograman. Data ini harus diterjemahkan, ditafsirkan, dikompilasi, dihasilkan sesuai kebutuhan ke dalam bentuk lain - data - beberapa di antaranya dapat dieksekusi.

Prosesor mengeluarkan instruksi dari memori. Memori yang sama yang digunakan untuk data. Sebelum prosesor menjalankan instruksi, program dimuat ke dalam memori sebagai data .

Jadi, semuanya data , bahkan kode .

Mengingat [kode yang dihasilkan adalah data], bukankah seluruh gagasan pembuatan kode ini merupakan kesalahpahaman?

Sangat baik untuk memiliki beberapa langkah dalam kompilasi, salah satunya dapat berupa pembuatan kode perantara sebagai teks.

Yaitu, jika ada generator kode untuk sesuatu, maka mengapa tidak menjadikan sesuatu itu fungsi yang tepat yang dapat menerima parameter yang diperlukan dan melakukan tindakan yang benar bahwa kode "akan dihasilkan" akan dilakukan?

Itu satu cara, tetapi ada yang lain.


Output dari pembuatan kode adalah teks, yang merupakan sesuatu yang dirancang untuk digunakan oleh manusia.

Tidak semua bentuk teks dimaksudkan untuk konsumsi manusia. Secara khusus, kode yang dihasilkan (sebagai teks) biasanya ditujukan untuk konsumsi kompiler bukan konsumsi manusia.


Kode sumber dianggap asli: master - apa yang kami edit & kembangkan; apa yang kami arsipkan menggunakan kontrol kode sumber. Kode yang dihasilkan, bahkan ketika teks yang dapat dibaca manusia, biasanya dibuat ulang dari kode sumber asli . Kode yang dibuat, secara umum, tidak harus berada di bawah kendali sumber karena kode tersebut dibuat ulang selama proses pembuatan.


1
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
maple_shaft

65

Alasan praktis

OK, saya tahu kode itu juga data. Yang tidak saya mengerti adalah, mengapa menghasilkan kode sumber?

Dari hasil edit ini, saya menganggap Anda bertanya pada tingkat yang agak praktis, bukan Ilmu Komputer teoretis.

Alasan klasik untuk menghasilkan kode sumber dalam bahasa statis seperti Java adalah bahwa bahasa seperti itu tidak benar-benar datang dengan alat yang mudah digunakan dalam bahasa untuk melakukan hal-hal yang sangat dinamis. Sebagai contoh, kembali pada hari-hari formatif Jawa, itu tidak mungkin untuk dengan mudah membuat kelas dengan nama dinamis (mencocokkan nama tabel dari DB) dan metode dinamis (mencocokkan atribut dari tabel itu) dengan tipe data dinamis (pencocokan jenis atribut tersebut). Terutama karena Java menempatkan banyak kepentingan, bahkan jaminan, untuk dapat menangkap kesalahan ketik pada waktu kompilasi.

Jadi, dalam pengaturan seperti itu, seorang programmer hanya dapat membuat kode Java dan menulis banyak baris kode secara manual. Seringkali, programmer akan menemukan bahwa setiap kali tabel berubah, ia harus kembali dan mengubah kode untuk mencocokkan; dan jika dia lupa itu, hal-hal buruk terjadi. Oleh karena itu, programmer akan sampai pada titik di mana ia menulis beberapa alat yang melakukannya untuknya. Dan karenanya jalan mulai menghasilkan kode yang lebih cerdas.

(Ya, Anda dapat membuat bytecode on the fly, tetapi memprogram hal seperti itu di Jawa tidak akan menjadi sesuatu yang programmer acak akan lakukan hanya di antara menulis beberapa baris kode domain.)

Bandingkan ini dengan bahasa-bahasa yang sangat dinamis, misalnya Ruby, yang saya anggap antitesisnya terhadap Jawa dalam banyak hal (perhatikan bahwa saya mengatakan ini tanpa menilai salah satu pendekatan; keduanya berbeda). Ini adalah 100% normal dan standar untuk secara dinamis menghasilkan kelas, metode dll pada saat runtime, dan yang paling penting, programmer dapat melakukannya dengan sepele tepat dalam kode, tanpa pergi ke tingkat "meta". Ya, hal-hal seperti Ruby on Rails datang dengan pembuatan kode, tetapi kami menemukan dalam pekerjaan kami bahwa pada dasarnya kami menggunakannya sebagai semacam "mode tutorial" canggih untuk programmer baru, tetapi setelah beberapa saat ia menjadi berlebihan (karena ada sedikit kode untuk menulis di ekosistem itu bahwa ketika Anda tahu apa yang Anda lakukan, menulisnya secara manual lebih cepat daripada membersihkan kode yang dihasilkan).

Ini hanya dua contoh praktis dari "dunia nyata". Kemudian Anda memiliki bahasa seperti LISP di mana kodenya adalah data, secara harfiah. Di sisi lain, dalam bahasa yang dikompilasi (tanpa mesin runtime seperti Java atau Ruby), ada (atau dulu, saya belum mengikuti fitur C ++ modern ...) tidak ada konsep mendefinisikan kelas atau nama metode saat runtime, jadi pembuatan kode proses build adalah alat pilihan untuk sebagian besar hal (contoh spesifik C / C ++ lainnya adalah hal-hal seperti flex, yacc dll.).


1
Saya pikir ini lebih baik daripada jawaban yang lebih banyak dipilih. Secara khusus, contoh yang disebutkan dengan Java dan pemrograman basis data melakukan pekerjaan yang jauh lebih baik untuk benar-benar mengatasi mengapa pembuatan kode digunakan dan merupakan alat yang valid.
Panzercrisis

Saat ini, apakah mungkin di Jawa untuk membuat tabel dinamis dari DB? Atau hanya dengan menggunakan ORM?
Noumenon

"(atau dulu, saya belum mengikuti fitur C ++ modern ...)" tentunya ini telah dimungkinkan dalam C ++ selama lebih dari dua dekade berkat fungsi pointer? Saya belum mengujinya, tetapi saya yakin itu mungkin untuk mengalokasikan array char, mengisinya dengan kode mesin dan kemudian melemparkan pointer ke elemen pertama ke sebuah fungsi pointer dan kemudian menjalankannya? (Dengan asumsi platform target tidak memiliki langkah keamanan untuk menghentikan Anda melakukan hal itu, yang mungkin bisa dilakukan.)
Pharap

1
"mengalokasikan array char, mengisinya dengan kode mesin dan kemudian melemparkan sebuah pointer ke elemen pertama ke sebuah pointer fungsi dan kemudian menjalankannya?" Selain sebagai perilaku yang tidak terdefinisi, itu adalah C ++ yang setara dengan "menghasilkan bytecode on the fly". Itu jatuh ke dalam kategori yang sama "tidak dipertimbangkan oleh programmer biasa"
Caleth

1
@Pharap, "pasti ini dimungkinkan di C ++ selama lebih dari dua dekade" ... Saya harus tertawa kecil; sekitar 2 dekade sejak saya terakhir kali berkode C ++. :) Tapi kalimat saya tentang C ++ dirumuskan dengan buruk. Saya telah sedikit mengubahnya, seharusnya lebih jelas apa yang saya maksud, sekarang.
AnoE

44

mengapa menghasilkan kode?

Karena pemrograman dengan kartu punch (atau kode alt di notepad ) sangat menyebalkan.

Jika itu dilakukan karena alasan kinerja, maka itu terdengar seperti kekurangan dari kompiler.

Benar. Saya tidak peduli dengan kinerja kecuali saya terpaksa.

Jika sedang dilakukan untuk menjembatani dua bahasa, maka itu terdengar seperti kurangnya antarmuka perpustakaan.

Hmm, tidak tahu apa yang Anda bicarakan.

Terlihat seperti ini: Kode sumber yang dibuat dan disimpan selalu dan selamanya menjadi masalah di pantat. Itu ada hanya untuk satu alasan. Seseorang ingin bekerja dalam satu bahasa sementara yang lain bersikeras untuk bekerja dalam bahasa lain dan tidak ada yang mau repot-repot mencari cara untuk beroperasi di antara mereka sehingga salah satu dari mereka mencari cara untuk mengubah bahasa favorit mereka menjadi bahasa yang dipaksakan sehingga mereka dapat melakukan apa mereka ingin.

Yang baik-baik saja sampai saya harus memeliharanya. Pada titik mana Anda semua bisa mati.

Apakah ini anti pola? Tidak, tidak. Banyak bahasa bahkan tidak akan ada jika kita tidak mau mengucapkan selamat tinggal pada kekurangan bahasa sebelumnya dan menghasilkan kode bahasa yang lebih lama adalah berapa banyak bahasa baru dimulai.

Ini adalah basis kode yang tersisa dalam tambal sulam Frankenstein rakasa setengah dikonversi yang saya tidak tahan. Kode yang dihasilkan adalah kode yang tidak tersentuh. Aku benci melihat kode yang tidak tersentuh. Namun orang-orang terus memeriksanya. MENGAPA? Anda mungkin juga memeriksa di executable.

Nah sekarang saya mengomel. Maksud saya adalah kita semua "menghasilkan kode". Saat Anda memperlakukan kode yang dihasilkan seperti kode sumber, Anda membuat saya gila. Hanya karena sepertinya kode sumber tidak membuatnya menjadi kode sumber.


41
Jika Anda menghasilkannya, itu bukan kode SUMBER. Ini kode perantara. Aku akan menangis sekarang.
candied_orange

65
ARG !!! Tidak masalah seperti apa itu !!! Teks, biner, DNA, jika itu bukan SUMBER itu bukan apa yang harus Anda sentuh ketika membuat perubahan. Bukan urusan siapa-siapa jika proses kompilasi saya memiliki 42 bahasa perantara yang dilaluinya. Berhenti menyentuh mereka. Berhenti memeriksanya. Buat perubahan pada sumbernya.
candied_orange

24
XML adalah teks dan jelas tidak dimaksudkan untuk konsumsi manusia. :-)
Nick Keighley

38
@utku: "Jika sesuatu tidak dimaksudkan untuk dikonsumsi oleh manusia, itu tidak boleh berupa teks": Saya benar-benar tidak setuju. Beberapa contoh balasan dari atas kepala saya: protokol HTTP, pengkodean MIME, file PEM - hampir semua hal yang menggunakan base64 di mana saja. Ada banyak alasan untuk menyandikan data ke aliran aman 7-bit, bahkan jika tidak ada manusia yang melihatnya. Belum lagi ruang yang jauh lebih besar dari hal-hal yang biasanya tidak boleh berinteraksi dengan manusia, tetapi mereka mungkin ingin sesekali: mencatat file, /etc/file di Unix, dll.
Daniel Pryden

12
Saya tidak berpikir "pemrograman dengan kartu punch" berarti apa yang Anda pikirkan artinya. Aku pernah ke sana, saya sudah melakukan itu, dan ya, itu adalah rasa sakit; tetapi tidak memiliki koneksi ke "kode yang dihasilkan." Setumpuk kartu berlubang hanyalah jenis file lainnya - seperti file pada disk, atau file pada tape, atau file pada kartu SD. Kembali pada hari itu, kami akan menulis data ke tumpukan kartu, dan membaca data dari mereka. Jadi, jika alasan kita menghasilkan kode adalah karena pemrograman dengan kartu punch adalah menyusahkan, maka itu menyiratkan bahwa pemrograman dengan segala jenis penyimpanan data adalah rasa sakit.
Solomon Slow

41

mengapa menghasilkan kode sumber

Kasus penggunaan yang paling sering digunakan untuk generator kode yang saya harus kerjakan dalam karir saya adalah generator yang

  • mengambil beberapa meta-deskripsi tingkat tinggi untuk beberapa jenis model data atau skema basis data sebagai input (mungkin skema relasional, atau semacam skema XML)

  • dan menghasilkan kode CRUD boiler-plate untuk kelas akses data sebagai output, dan mungkin hal-hal tambahan seperti SQL atau dokumentasi yang sesuai.

Manfaatnya di sini adalah bahwa dari satu baris spesifikasi input pendek, Anda mendapatkan 5 hingga 10 baris kode debuggable, tipe-safe, bug-free (diasumsikan output generator sudah matang) kode Anda dinyatakan harus menerapkan dan memelihara secara manual. Anda dapat membayangkan seberapa banyak ini mengurangi upaya pemeliharaan dan pengembangan.

Izinkan saya juga menjawab pertanyaan awal Anda

Apakah pembuatan kode sumber merupakan pola anti

Tidak, bukan pembuatan kode sumber per se, tetapi memang ada beberapa jebakan. Sebagaimana dinyatakan dalam The Pragmatic Programmer , seseorang harus menghindari penggunaan generator kode ketika menghasilkan kode yang sulit dimengerti . Jika tidak, peningkatan upaya untuk menggunakan atau men-debug kode ini dapat dengan mudah lebih besar daripada upaya yang disimpan dengan tidak menulis kode secara manual.

Saya juga ingin menambahkan bahwa itu adalah ide yang baik untuk memisahkan bagian-bagian kode yang dihasilkan dari kode yang ditulis secara fisik dengan cara re-generation tidak menimpa perubahan manual. Namun, saya juga telah berurusan dengan situasi lebih dari satu kali di mana tugasnya adalah untuk memigrasikan beberapa kode yang ditulis dalam bahasa lama X ke yang lain, bahasa Y yang lebih modern, dengan maksud untuk pemeliharaan setelahnya dalam bahasa Y. Ini adalah penggunaan yang valid kasus untuk pembuatan kode satu kali.


Saya setuju dengan jawaban ini. Menggunakan sesuatu seperti Torsi untuk java, saya dapat melakukan pembuatan file sumber java secara otomatis, dengan bidang yang cocok dengan database sql. Ini membuat operasi kasar jauh lebih mudah. Manfaat utama adalah keamanan jenis, termasuk hanya bisa referensi bidang yang ada di database (Terima kasih lengkapi otomatis).
MTilsted

Ya, untuk bahasa yang diketik secara statis, ini adalah bagian yang penting: Anda dapat memastikan kode tulisan tangan Anda benar - benar cocok dengan yang dihasilkan.
Paŭlo Ebermann

"migrasikan beberapa kode yang ditulis dalam bahasa lama" - meskipun begitu, pembuatan kode satu kali mungkin sangat menyusahkan. Misalnya, setelah beberapa perubahan manual Anda mendeteksi bug di generator dan perlu mengulang generasi setelah perbaikan. Untungnya, git atau sejenisnya biasanya dapat meringankan rasa sakit.
maaartinus

13

mengapa menghasilkan kode sumber?

Saya mengalami dua kasus penggunaan untuk kode yang dihasilkan (saat membangun, dan tidak pernah check in):

  1. Secara otomatis menghasilkan kode boilerplate seperti getter / setter, toString, equals, dan hashCode dari bahasa yang dibangun untuk menentukan hal-hal seperti itu (misalnya proyek lombok untuk Java)
  2. Secara otomatis menghasilkan kelas tipe DTO dari beberapa spesifikasi antarmuka (REST, SOAP, apa pun) untuk kemudian digunakan dalam kode utama. Ini mirip dengan masalah jembatan bahasa Anda, tetapi pada akhirnya menjadi lebih bersih dan sederhana, dengan penanganan jenis yang lebih baik daripada mencoba menerapkan hal yang sama tanpa kelas yang dihasilkan.

15
Kode yang sangat berulang dalam bahasa yang tidak ekspresif. Misalnya saya harus menulis kode yang penting melakukan hal yang sama pada banyak struktur data yang serupa tetapi tidak identik. Mungkin bisa dilakukan dengan sesuatu seperti template C ++ (hei bukankah itu pembuatan kode?). Tapi saya menggunakan C. Pembuatan kode menyelamatkan saya menulis banyak kode yang hampir sama.
Nick Keighley

1
@NickKeighley Mungkin toolchain Anda tidak mengizinkan Anda untuk menggunakan bahasa lain yang lebih cocok?
Wilson

7
Anda biasanya tidak dapat memilih dan memilih bahasa implementasi Anda. Proyek itu di C, itu bukan pilihan.
Nick Keighley

1
@ Willson bahasa yang lebih ekspresif sering menggunakan pembuatan kode (mis. Makro lisp, ruby ​​on rails), mereka hanya tidak perlu disimpan sebagai teks untuk sementara.
Pete Kirkham

4
Ya, pembuatan kode pada dasarnya adalah meta-pemrograman. Bahasa seperti Ruby memungkinkan Anda melakukan meta-pemrograman dalam bahasa itu sendiri, tetapi C tidak jadi Anda harus menggunakan pembuatan kode.
Sean Burton

13

Sussmann memiliki banyak hal menarik untuk dikatakan tentang hal-hal seperti itu dalam klasiknya "Struktur dan interpretasi program komputer", terutama tentang dualitas kode-data.

Bagi saya, penggunaan utama pembuatan kode adhoc adalah menggunakan kompiler yang tersedia untuk mengonversi beberapa bahasa spesifik domain kecil menjadi sesuatu yang dapat saya tautkan ke program saya. Pikirkan BNF, pikirkan ASN1 (Sebenarnya, jangan, ini jelek), pikirkan spreadsheet kamus data.

Bahasa khusus domain sepele dapat menghemat waktu, dan mengeluarkan sesuatu yang dapat dikompilasi oleh alat bahasa standar adalah cara yang harus dilakukan ketika membuat hal-hal seperti itu, yang ingin Anda edit, parser yang diretas tanpa sepele dalam bahasa asli apa pun Anda berada menulis, atau BNF untuk yang dibuat secara otomatis?

Dengan mengeluarkan teks yang kemudian diumpankan ke beberapa kompiler sistem, saya mendapatkan semua optimisasi kompiler dan konfigurasi khusus sistem tanpa harus memikirkannya.

Saya secara efektif menggunakan bahasa input kompilator hanya sebagai representasi perantara, apa masalahnya? File teks tidak secara inheren kode sumber, mereka bisa menjadi IR untuk kompiler , dan jika mereka terlihat seperti C atau C ++ atau Java atau apa pun, siapa yang peduli?

Sekarang jika Anda sulit berpikir Anda dapat mengedit OUTPUT parser bahasa mainan, yang jelas-jelas akan mengecewakan saat seseorang mengedit file bahasa input dan membangun kembali, jawabannya adalah untuk tidak melakukan IR yang dihasilkan secara otomatis ke repo, memilikinya dihasilkan oleh rantai alat Anda (Dan menghindari orang-orang seperti itu dalam grup dev Anda, mereka biasanya lebih senang bekerja di bidang pemasaran).

Ini bukan kegagalan ekspresi dalam bahasa kita, sebagai ekspresi dari fakta bahwa kadang-kadang Anda bisa mendapatkan (atau memijat) bagian dari spesifikasi menjadi bentuk yang dapat secara otomatis dikonversi menjadi kode, dan yang biasanya akan menghasilkan jauh lebih sedikit bug dan jauh lebih mudah untuk dipelihara. Jika saya bisa memberikan pengujian dan konfigurasi pada kami spreadsheet yang dapat mereka atur dan alat yang kemudian mereka jalankan yang mengambil data itu dan mengeluarkan file hex lengkap untuk flash pada ECU saya maka itu adalah waktu yang sangat menghemat waktu karena seseorang menerjemahkan secara manual pengaturan terbaru menjadi seperangkat konstanta dalam bahasa hari ini (Lengkap dengan kesalahan ketik).

Hal yang sama dengan membangun model di Simulink dan kemudian menghasilkan C dengan RTW kemudian mengkompilasi untuk menargetkan dengan alat apa pun yang masuk akal, C menengah tidak dapat dibaca, jadi apa? Matlab RTW level tinggi hanya perlu mengetahui subset C, dan kompiler C menangani detail platform. Satu-satunya waktu manusia harus merendahkan diri melalui C yang dihasilkan adalah ketika skrip RTW memiliki bug, dan hal semacam itu jauh lebih mudah untuk di-debug dengan IR yang dapat dibaca manusia secara nominal kemudian dengan hanya pohon parse biner.

Anda tentu saja dapat menulis hal-hal seperti itu untuk menghasilkan bytecode atau bahkan kode yang dapat dieksekusi, tetapi mengapa Anda melakukan itu? Kami punya alat untuk mengonversi IR ke hal-hal itu.


Ini bagus, tapi saya akan menambahkan bahwa ada tradeoff ketika menentukan IR mana yang akan digunakan: menggunakan C sebagai IR membuat beberapa hal lebih mudah dan hal-hal lain lebih sulit, bila dibandingkan dengan, katakanlah, bahasa assembly x86. Pilihannya bahkan lebih signifikan ketika memilih antara, katakanlah, kode bahasa Jawa dan kode byte Java, karena ada lebih banyak operasi yang hanya ada dalam satu atau bahasa lain.
Daniel Pryden

2
Tetapi bahasa rakitan X86 menghasilkan IR yang buruk saat menargetkan inti ARM atau PPC! Semua hal merupakan pertukaran dalam rekayasa, itulah sebabnya mereka menyebutnya Rekayasa. Orang akan berharap bahwa kemungkinan bytecode Java adalah superset ketat dari kemungkinan bahasa Jawa, dan bahwa ini umumnya benar ketika Anda semakin dekat dengan logam terlepas dari toolchain dan di mana Anda menyuntikkan IR.
Dan Mills

Oh, saya sepenuhnya setuju: komentar saya adalah sebagai jawaban atas paragraf terakhir Anda mempertanyakan mengapa Anda pernah mengeluarkan kode byt atau hal-hal tingkat rendah - kadang-kadang Anda memang membutuhkan tingkat yang lebih rendah. (Khususnya di Jawa, ada banyak hal berguna yang dapat Anda lakukan dengan bytecode yang tidak dapat Anda lakukan dalam bahasa Jawa itu sendiri.)
Daniel Pryden

2
Saya tidak setuju, tetapi ada biaya untuk menggunakan IR lebih dekat ke logam, tidak hanya dalam mengurangi generalitas, tetapi pada kenyataan bahwa Anda biasanya bertanggung jawab untuk lebih banyak optimasi tingkat rendah yang benar-benar menjengkelkan. Fakta bahwa kita pada umumnya akhir-akhir ini berpikir dalam hal mengoptimalkan pilihan algoritma daripada implementasi adalah refleksi seberapa jauh kompiler telah datang, kadang-kadang Anda harus benar-benar dekat dengan logam dalam hal ini, tetapi berpikir dua kali sebelum membuang kompiler kemampuan untuk mengoptimalkan dengan menggunakan level IR yang terlalu rendah.
Dan Mills

1
"Mereka biasanya lebih bahagia bekerja di pemasaran" Catty, tapi lucu.
dmckee

13

Jawaban pragmatis: apakah pembuatan kode diperlukan dan bermanfaat? Apakah ini memberikan sesuatu yang benar-benar sangat berguna dan diperlukan untuk basis kode kepemilikan, atau apakah itu hanya menciptakan cara lain dalam melakukan sesuatu dengan cara yang berkontribusi lebih banyak overhead intelektual untuk hasil yang kurang optimal?

OK, saya tahu kode itu juga data. Yang tidak saya mengerti adalah, mengapa menghasilkan kode? Mengapa tidak membuatnya menjadi fungsi yang dapat menerima parameter dan menindaklanjutinya?

Jika Anda harus mengajukan pertanyaan ini dan tidak ada jawaban yang jelas, maka mungkin pembuatan kode itu berlebihan dan hanya berkontribusi eksotisme dan banyak overhead intelektual ke basis kode Anda.

Sementara itu jika Anda mengambil sesuatu seperti OpenShadingLanguage: https://github.com/imageworks/OpenShadingLanguage

... maka pertanyaan seperti itu tidak perlu diajukan karena mereka segera dijawab oleh hasil yang mengesankan.

OSL menggunakan kerangka kerja kompilator LLVM untuk menerjemahkan jaringan shader menjadi kode mesin dengan cepat (tepat pada waktunya, atau "JIT"), dan dalam prosesnya sangat mengoptimalkan shader dan jaringan dengan pengetahuan penuh tentang parameter shader dan nilai runtime lainnya yang tidak bisa telah diketahui ketika shader dikompilasi dari kode sumber. Sebagai hasilnya, kami melihat jaringan shading OSL kami mengeksekusi 25% lebih cepat dari pada shader setara buatan tangan di C! (Begitulah cara shader lama kita bekerja di penyaji kita.)

Dalam kasus seperti itu Anda tidak perlu mempertanyakan keberadaan pembuat kode. Jika Anda bekerja dalam jenis domain VFX ini, maka tanggapan langsung Anda biasanya lebih pada baris, "tutup mulut dan ambil uangku!" atau, "wow, kita juga perlu membuat sesuatu seperti ini."


menerjemahkan jaringan shader menjadi kode mesin . Ini terdengar seperti kompiler daripada generator kode, bukan?
Utku

2
Pada dasarnya dibutuhkan jaringan nodal pengguna menghubungkan dan menghasilkan kode perantara yang dikompilasi JIT oleh LLVM. Perbedaan antara kompiler dan pembuat kode adalah jenis fuzzy. Apakah Anda lebih memikirkan garis-garis fitur pembuatan kode dalam bahasa seperti templat dalam C ++ atau preproses C?

Saya sedang memikirkan generator yang akan menghasilkan kode sumber.
Utku

Saya melihat, di mana outputnya masih untuk konsumsi manusia saya kira. OpenSL juga menghasilkan kode sumber perantara tetapi kode tingkat rendah yang dekat dengan perakitan untuk konsumsi LLVM. Ini biasanya bukan kode yang dimaksudkan untuk dipertahankan (melainkan programmer mempertahankan node yang digunakan untuk menghasilkan kode). Sebagian besar waktu saya pikir jenis-jenis generator kode lebih cenderung disalahgunakan daripada cukup berguna untuk membenarkan nilainya, terutama jika Anda harus terus-menerus membuat ulang kode sebagai bagian dari proses pembangunan Anda. Kadang-kadang mereka masih memiliki tempat asli meskipun untuk mengatasi kekurangan ...

... bahasa yang tersedia saat digunakan untuk domain tertentu. QT memiliki salah satu yang kontroversial dengan meta-object compiler (MOC). MOC mengurangi pelat ketel yang biasanya Anda perlukan untuk menyediakan properti dan refleksi dan sinyal dan slot dan sebagainya dalam C ++, tetapi tidak sedemikian jauh untuk secara jelas membenarkan keberadaannya. Saya sering berpikir QT bisa lebih baik tanpa beban rumit dari pembuatan kode MOC.

8

Tidak, menghasilkan kode perantara bukanlah anti-pola. Jawaban untuk bagian lain dari pertanyaan Anda, "Mengapa melakukannya?", Adalah pertanyaan yang sangat luas (dan terpisah), meskipun saya akan memberikan beberapa alasan.

Konsekuensi historis dari tidak adanya kode perantara yang dapat dibaca manusia

Mari kita ambil C dan C ++ sebagai contoh karena mereka adalah bahasa yang paling terkenal.

Anda harus memperhatikan bahwa prosesi logis mengkompilasi output kode C bukan kode mesin melainkan kode perakitan yang dapat dibaca manusia. Demikian juga, kompiler C ++ lama digunakan untuk secara fisik mengkompilasi kode C ++ ke dalam kode C. Dalam rangkaian peristiwa itu, Anda bisa mengkompilasi dari kode 1 yang dapat dibaca manusia ke kode 2 yang dapat dibaca manusia ke kode 3 yang dapat dibaca manusia ke kode mesin. "Mengapa?" Kenapa tidak?

Jika kode antara yang dapat dibaca manusia tidak pernah dibuat, kami mungkin bahkan tidak memiliki C atau C ++ sama sekali. Itu tentu saja kemungkinan; orang mengambil jalan yang paling tidak tahan terhadap tujuan mereka, dan jika beberapa bahasa lain memperoleh dukungan lebih dulu karena stagnasi pengembangan C, C mungkin telah mati saat masih muda. Tentu saja, Anda bisa berdebat, "Tapi mungkin kita akan menggunakan bahasa lain, dan mungkin akan lebih baik." Mungkin, atau mungkin akan lebih buruk. Atau mungkin kita semua masih akan menulis dalam pertemuan.

Mengapa menggunakan kode perantara yang dapat dibaca manusia?

  1. Terkadang kode perantara diinginkan agar Anda dapat memodifikasinya sebelum langkah berikutnya dalam membangun. Saya akui poin ini adalah yang terlemah.
  2. Kadang-kadang itu karena karya asli tidak dilakukan dalam bahasa yang dapat dibaca manusia sama sekali tetapi dalam alat pemodelan GUI.
  3. Kadang-kadang Anda perlu melakukan sesuatu yang sangat berulang, dan bahasa tidak boleh memenuhi apa yang Anda lakukan karena itu adalah hal yang khusus atau hal yang rumit sehingga tidak memiliki bisnis yang meningkatkan kompleksitas atau tata bahasa bahasa pemrograman hanya untuk mengakomodasi kamu.
  4. Terkadang Anda perlu melakukan sesuatu yang sangat berulang, dan tidak ada cara yang mungkin untuk memasukkan apa yang Anda inginkan ke dalam bahasa dengan cara yang umum; baik itu tidak dapat diwakili oleh atau konflik dengan tata bahasa bahasa.
  5. Salah satu tujuan komputer adalah untuk mengurangi upaya manusia, dan terkadang kode yang tidak mungkin disentuh lagi (kemungkinan pemeliharaan rendah) dapat memiliki meta-code yang ditulis untuk menghasilkan kode Anda yang lebih lama dalam sepersepuluh waktu; jika saya bisa melakukannya dalam 1 hari bukannya 2 minggu dan itu tidak mungkin untuk dipertahankan pernah, maka saya lebih baik menghasilkan itu - dan pada kesempatan bahwa seseorang 5 tahun dari sekarang kesal karena mereka benar-benar tidak perlu untuk mempertahankan itu, maka mereka dapat menghabiskan 2 minggu menuliskannya sepenuhnya jika mereka mau, atau terganggu oleh 1 minggu mempertahankan kode yang canggung (tapi kami masih 1 minggu di depan pada saat itu), dan itu jika pemeliharaan itu perlu dilakukan sama sekali .
  6. Saya yakin ada lebih banyak alasan yang saya abaikan.

Contoh

Saya telah mengerjakan proyek sebelumnya di mana kode perlu dihasilkan berdasarkan data atau informasi dalam beberapa dokumen lain. Sebagai contoh, satu proyek memiliki semua pesan jaringan dan data konstan yang didefinisikan dalam spreadsheet dan alat yang akan melalui spreadsheet dan menghasilkan banyak kode C ++ dan Java yang memungkinkan kami bekerja dengan pesan-pesan itu.

Saya tidak mengatakan itu adalah cara terbaik untuk mengatur proyek itu (saya bukan bagian dari startup-nya), tetapi itulah yang kami miliki, dan itu adalah ratusan (mungkin bahkan ribuan, tidak yakin) struktur dan objek serta konstanta yang sedang dihasilkan; pada titik itu mungkin sudah terlambat untuk mencoba mengulanginya dalam sesuatu seperti Rhapsody. Tetapi bahkan jika itu diperbaiki dalam sesuatu seperti Rhapsody, maka kita masih memiliki kode yang dihasilkan dari Rhapsody .

Juga, memiliki semua data dalam spreadsheet itu bagus dalam satu cara: itu memungkinkan kami untuk mewakili data dengan cara yang kami tidak bisa miliki jika semuanya hanya dalam file kode sumber.

Contoh 2

Ketika saya melakukan beberapa pekerjaan dalam konstruksi compiler, saya menggunakan alat Antlr untuk melakukan lexing dan parsing saya. Saya menetapkan tata bahasa, kemudian saya menggunakan alat untuk memuntahkan satu ton kode dalam C ++ atau Java, kemudian saya menggunakan kode yang dihasilkan di samping kode saya sendiri dan memasukkannya ke dalam build.

Bagaimana lagi yang seharusnya dilakukan? Mungkin Anda bisa menemukan cara lain; mungkin ada cara lain. Tetapi untuk pekerjaan itu, cara lain tidak akan lebih baik daripada kode lex / parse yang dihasilkan yang saya miliki.


Saya telah menggunakan kode perantara sebagai semacam format file dan jejak debugging ketika kedua sistem tidak kompatibel tetapi memiliki api yang stabil dari beberapa jenis, dalam bahasa scripting yang sangat esoteris. Bukankah dimaksudkan untuk dibaca secara manual tetapi bisa dengan cara yang sama dengan xml. Tapi ini lebih umum daripada yang Anda pikirkan setelah semua halaman web bekerja seperti ini, seperti yang ditunjukkan oleh seseorang.
joojaa

7

Apa yang Anda lewatkan adalah penggunaan kembali .

Kami memiliki alat luar biasa untuk mengubah teks kode sumber menjadi biner, yang disebut kompiler. Masukan-inputnya didefinisikan dengan baik (biasanya!), Dan telah melalui banyak pekerjaan untuk memperbaiki cara kerjanya. Jika Anda benar-benar ingin menggunakan kompiler untuk melakukan beberapa operasi, Anda ingin menggunakan kompiler yang ada dan tidak menulis sendiri.

Banyak orang menciptakan bahasa pemrograman baru dan menulis kompiler mereka sendiri. Cukup banyak tanpa kecuali, mereka semua melakukan ini karena mereka menikmati tantangan, bukan karena mereka membutuhkan fitur yang disediakan bahasa. Segala sesuatu yang mereka lakukan dapat dilakukan dalam bahasa lain; mereka hanya menciptakan bahasa baru karena mereka suka fitur-fitur itu. Apa yang tidak akan mendapatkannya adalah kompiler yang disetel dengan baik, cepat, efisien, dan optimal. Ini akan memberi mereka sesuatu yang dapat mengubah teks menjadi biner, tentu saja, tetapi itu tidak akan sebagus semua kompiler yang ada .

Teks bukan hanya sesuatu yang dibaca dan ditulis manusia. Komputer di rumah sempurna dengan teks juga. Sebenarnya format seperti XML (dan format terkait lainnya) berhasil karena mereka menggunakan teks biasa. Format file biner seringkali tidak jelas dan kurang didokumentasikan, dan pembaca tidak dapat dengan mudah menemukan cara kerjanya. XML relatif mendokumentasikan diri, sehingga memudahkan orang untuk menulis kode yang menggunakan file berformat XML. Dan semua bahasa pemrograman diatur untuk membaca dan menulis file teks.

Jadi, misalkan Anda ingin menambahkan beberapa fasilitas baru untuk membuat hidup Anda lebih mudah. Mungkin itu alat tata letak GUI. Mungkin itu adalah antarmuka sinyal-dan-slot yang disediakan Qt . Mungkin dengan cara itu , Code Composer Studio TI memungkinkan Anda mengonfigurasi perangkat yang bekerja dengan Anda dan menarik pustaka yang tepat ke build. Mungkin butuh kamus data dan pengetikan otomatis dan definisi variabel global (ya, ini masih banyak hal dalam perangkat lunak tertanam). Apa pun itu, cara paling efisien untuk memanfaatkan kompiler yang ada adalah dengan membuat alat yang akan mengambil konfigurasi apa pun itu dan secara otomatis menghasilkan kode dalam bahasa pilihan Anda.

Sangat mudah untuk dikembangkan dan mudah untuk diuji, karena Anda tahu apa yang terjadi dan Anda dapat membaca kode sumber yang dikeluarkannya. Anda tidak perlu menghabiskan waktu bertahun-tahun untuk membangun kompiler untuk menyaingi GCC. Anda tidak perlu mempelajari bahasa baru yang lengkap, atau mengharuskan orang lain melakukannya. Yang perlu Anda lakukan adalah mengotomatiskan area kecil yang satu ini, dan yang lainnya tetap sama. Pekerjaan selesai.


Masih keuntungan dari berbasis teks XML adalah hanya bahwa jika perlu , dapat dibaca & ditulis oleh manusia (mereka biasanya tidak repot setelah bekerja, tetapi tentu saja dilakukan selama pengembangan). Dalam hal kinerja dan efisiensi ruang, format biner umumnya jauh lebih baik (yang sangat sering tidak masalah, karena hambatannya ada di tempat lain).
leftaroundabout

@leftaroundabout Jika Anda membutuhkan kinerja dan efisiensi ruang, tentu saja. Alasan banyak aplikasi beralih ke format berbasis XML hari ini adalah karena kinerja dan efisiensi ruang bukan kriteria teratas yang dulu, dan sejarah telah menunjukkan betapa buruknya format file biner dipertahankan. (Dokumen MS Word lama untuk contoh klasik!) Intinya tetap - teks sama cocok untuk komputer untuk dibaca sebagai manusia.
Graham

Tentu saja, format biner yang dirancang dengan buruk dapat benar-benar berkinerja lebih buruk daripada format teks yang dipikirkan dengan baik, dan bahkan format biner yang baik seringkali tidak jauh lebih ringkas daripada XML yang dikemas dengan beberapa algoritma kompresi tujuan umum. IMO yang terbaik dari kedua dunia adalah dengan menggunakan spesifikasi yang dapat dibaca manusia melalui tipe data aljabar, dan secara otomatis menghasilkan representasi biner yang efisien dari AST jenis ini. Lihat misalnya perpustakaan datar .
leftaroundabout

7

Sedikit jawaban yang lebih pragmatis, fokus pada mengapa dan bukan pada apa yang ada dan bukan kode sumber. Perhatikan bahwa menghasilkan kode sumber adalah bagian dari proses pembuatan dalam semua kasus ini - jadi file yang dihasilkan tidak harus menemukan jalan mereka ke kontrol sumber.

Interoprabilitas / kesederhanaan

Ambil Google's Protocol Buffer, contoh utama: Anda menulis satu deskripsi protokol tingkat tinggi yang kemudian dapat digunakan untuk menghasilkan implementasi dalam berbagai bahasa - seringkali bagian sistem yang berbeda ditulis dalam bahasa yang berbeda.

Alasan implementasi / teknis

Take TypeScript - browser tidak dapat mengartikannya sehingga proses build menggunakan transpiler (code to code translator) untuk menghasilkan JavaScript. Sebenarnya banyak bahasa kompilasi yang baru atau esoterik dimulai dengan pengubahan ke C sebelum mereka mendapatkan kompiler yang tepat.

Kemudahan penggunaan

Untuk proyek yang disematkan (pikirkan IoT) yang ditulis dalam C dan hanya menggunakan satu biner (RTOS atau tanpa OS), cukup mudah untuk menghasilkan larik C dengan data yang akan dikompilasi seolah-olah kode sumber normal, sebagai pilihan untuk menghubungkannya secara langsung sebagai sumber daya.

Sunting

Memperluas pada protobuf: pembuatan kode memungkinkan objek yang dihasilkan menjadi kelas kelas satu dalam bahasa apa pun. Dalam bahasa yang dikompilasi, parser generik akan dengan keharusan mengembalikan struktur nilai kunci - yang berarti Anda mendapatkan banyak kode boilerplate, Anda melewatkan beberapa pemeriksaan waktu kompilasi (pada kunci dan jenis nilai khususnya), mendapatkan kinerja yang lebih buruk dan tidak ada penyelesaian kode. Bayangkan semua orang void*di C atau yang besar std::variantdi C ++ (jika Anda memiliki C ++ 17), beberapa bahasa mungkin tidak memiliki fitur seperti itu sama sekali.


Untuk alasan pertama, saya pikir ide OP adalah untuk memiliki implementasi generik di setiap bahasa (yang mengambil deskripsi buffer protokol dan kemudian mem-parsing / menggunakan format on-the-wire). Mengapa ini lebih buruk daripada menghasilkan kode?
Paŭlo Ebermann

@ PaŭloEbermann terlepas dari argumen kinerja yang biasanya interpretasi generik seperti itu membuat mustahil untuk menggunakan pesan-pesan itu sebagai objek kelas satu dalam bahasa yang dikompilasi (dan mungkin diinterpretasikan) - dalam bahasa C ++ misalnya penerjemah seperti itu akan dengan keharusan mengembalikan struktur nilai kunci . Tentu saja Anda bisa mendapatkan kv itu ke dalam kelas Anda, tetapi itu bisa berubah menjadi banyak kode boilerplate. Dan ada juga penyelesaian kode. Dan kompilasi pengecekan waktu - kompiler Anda tidak akan memeriksa apakah literal Anda tidak memiliki kesalahan ketik.
Jan Dorniak

Saya setuju ... bisakah Anda menambahkan ini ke dalam jawabannya?
Paŭlo Ebermann

@ PaŭloEbermann selesai
Jan Dorniak

6

Apakah pembuatan kode sumber merupakan pola anti?

Ini adalah solusi untuk bahasa pemrograman yang kurang ekspresif. Tidak perlu membuat kode dalam bahasa yang mengandung meta-pemrograman bawaan yang memadai.


3
Ini juga merupakan solusi untuk harus menulis kompiler kode objek penuh, turun-ke-asli-untuk bahasa yang lebih ekspresif. Hasilkan C, biarkan kompiler dengan pengoptimal yang baik mengurus sisanya.
Blrfl

Tidak selalu. Kadang-kadang Anda memiliki satu atau lebih database yang berisi beberapa definisi untuk sinyal misalnya pada bus. Kemudian Anda ingin menggabungkan informasi ini, mungkin melakukan beberapa pemeriksaan konsistensi dan kemudian menulis kode yang menghubungkan antara sinyal yang datang dari bus dan variabel yang Anda harapkan ada dalam kode Anda. Jika Anda dapat menunjukkan kepada saya bahasa yang memiliki meta-pemrograman yang membuatnya mudah untuk menggunakan beberapa klien yang disediakan lembar Excel, database dan sumber data lainnya dan membuat kode yang saya butuhkan, dengan beberapa pemeriksaan yang diperlukan pada validitas dan konsistensi data, maka dengan semua cara tunjukkan padaku.
CodeMonkey

@CodeMonkey: sesuatu seperti implementasi ActiveRecord Ruby on Rails 'terlintas dalam pikiran. Tidak perlu menduplikasi skema tabel database dalam kode. Hanya memetakan kelas ke tabel dan menulis logika bisnis menggunakan nama kolom sebagai properti. Saya tidak bisa membayangkan pola apa pun yang bisa dihasilkan oleh pembuat kode yang juga tidak bisa dikelola oleh Ruby meta-programming. Templat C ++ juga sangat kuat, meskipun agak misterius. Macro Lisp adalah sistem meta-pemrograman lain yang kuat dalam bahasa.
kevin cline

@ kevincline yang saya maksud adalah kode yang didasarkan pada beberapa data dari basis data (dapat dibuat dari basis data), tetapi bukan basis data itu sendiri. Yaitu saya memiliki informasi tentang sinyal mana yang saya terima di Excel Tabel A. Saya memiliki Basis Data B dengan informasi tentang sinyal-sinyal ini, dll. Sekarang saya ingin memiliki kelas yang mengakses sinyal-sinyal ini. Tidak ada koneksi ke database atau lembar Excel pada mesin yang menjalankan kode. Menggunakan C ++ Templating yang sangat rumit untuk menghasilkan kode ini pada waktu kompilasi, alih-alih pembuat kode sederhana. Saya akan memilih codegen.
CodeMonkey

6

Pembuatan kode sumber tidak selalu merupakan anti-pola. Sebagai contoh, saya saat ini sedang menulis kerangka kerja yang dengan spesifikasi yang diberikan menghasilkan kode dalam dua bahasa yang berbeda (Javascript dan Jawa). Kerangka kerja menggunakan Javascript yang dihasilkan untuk merekam tindakan browser pengguna, dan menggunakan kode Java di Selenium untuk benar-benar menjalankan tindakan ketika kerangka kerja berada dalam mode replay. Jika saya tidak menggunakan pembuatan kode, saya harus secara manual memastikan bahwa keduanya selalu sinkron, yang rumit dan juga merupakan duplikasi logis dalam beberapa cara.

Namun jika seseorang menggunakan pembuatan kode sumber untuk mengganti fitur seperti generik, maka itu anti-pola.


Anda dapat, tentu saja, menulis kode Anda sekali dalam ECMAScript dan menjalankannya di Nashorn atau Badak di JVM. Atau, Anda dapat menulis JVM dalam ECMAScript (atau mencoba mengkompilasi Avian ke WebAssembly menggunakan Emscripten) dan menjalankan kode Java Anda di browser. Saya tidak mengatakan itu adalah ide-ide besar (well, mereka mungkin ide-ide yang mengerikan :-D), tetapi setidaknya mereka mungkin jika tidak layak.
Jörg W Mittag

Secara teori, itu mungkin, tetapi itu bukan solusi umum. Apa yang terjadi jika saya tidak dapat menjalankan salah satu bahasa di dalam yang lain? Sebagai contoh, hal tambahan: Saya baru saja membuat model Netlogo sederhana menggunakan pembuatan kode dan memiliki dokumentasi sistem interaktif, yang selalu sinkron dengan perekam dan replayer. Dan secara umum, membuat persyaratan dan kemudian menghasilkan kode menjaga hal-hal yang berjalan secara semantik bersama dalam sinkronisasi.
Hristo Vrigazov

6

Apakah saya melewatkan sesuatu di sini?

Mungkin contoh yang bagus di mana kode perantara ternyata menjadi alasan kesuksesan? Saya dapat menawarkan Anda HTML.

Saya percaya HTML itu penting dan sederhana - penting untuk membuat peramban, memungkinkan untuk memulai peramban seluler lebih awal, dll. Seperti yang diperlihatkan percobaan lebih lanjut (Java applet, Flash) - bahasa yang lebih kompleks dan kuat menyebabkan lebih banyak masalah . Ternyata pengguna benar-benar terancam oleh applet Java dan mengunjungi situs web tersebut sama amannya dengan mencoba retakan game yang diunduh melalui DC ++. Plain HTML, di sisi lain, tidak cukup berbahaya untuk memungkinkan kami memeriksa situs apa pun dengan keyakinan memadai tentang keamanan perangkat kami.

Namun, HTML tidak akan berada di dekat tempat itu sekarang jika bukan komputer yang dihasilkan. Jawaban saya bahkan tidak akan muncul di halaman ini sampai seseorang secara manual menulis ulang dari database menjadi file HTML. Untungnya Anda dapat membuat HTML yang dapat digunakan di hampir semua bahasa pemrograman :)

Yaitu, jika ada generator kode untuk sesuatu, maka mengapa tidak menjadikan sesuatu itu fungsi yang tepat yang dapat menerima parameter yang diperlukan dan melakukan tindakan yang benar bahwa kode "akan dihasilkan" akan dilakukan?

Bisakah Anda bayangkan cara yang lebih baik untuk menampilkan pertanyaan dan semua jawaban dan komentar kepada pengguna daripada menggunakan HTML sebagai kode antar-dihasilkan?


Ya, saya bisa membayangkan cara yang lebih baik. HTML adalah warisan keputusan oleh Tim Berners-Lee untuk memungkinkan pembuatan cepat peramban web hanya teks. Itu baik-baik saja pada saat itu, tetapi kami tidak akan melakukan hal yang sama dengan manfaat melihat ke belakang. CSS telah membuat semua jenis elemen presentasi (DIV, SPAN, TABLE, UL, dll.) Tidak diperlukan.
kevin cline

@ kevincline Saya tidak mengatakan bahwa HTML tidak cacat, saya menunjukkan bahwa memperkenalkan bahasa markup (yang dapat dihasilkan oleh suatu program) bekerja dengan sangat baik dalam hal ini.
Džuris

Jadi HTML + CSS lebih baik daripada hanya HTML. Saya bahkan telah menulis dokumentasi internal untuk beberapa proyek yang telah saya kerjakan secara langsung dalam HTML + CSS + MathJax. Tetapi sebagian besar halaman web yang saya kunjungi tampaknya diproduksi oleh pembuat kode.
David K

3

mengapa menghasilkan kode sumber?

Karena lebih cepat dan lebih mudah (dan lebih rentan kesalahan) daripada menulis kode secara manual, terutama untuk tugas yang membosankan dan berulang. Anda juga dapat menggunakan alat tingkat tinggi untuk memverifikasi dan memvalidasi desain Anda sebelum menulis satu baris kode.

Kasus penggunaan umum:

  • Alat pemodelan seperti Rose atau Visual Paradigm;
  • Tinggi er bahasa tingkat seperti SQL Tertanam atau bahasa definisi antarmuka yang harus preprocessed menjadi sesuatu compilable;
  • Generator Lexer dan parser seperti flex / bison;

Adapun "mengapa tidak hanya menjadikannya fungsi dan meneruskan parameter ke itu secara langsung", perhatikan bahwa tidak satu pun di atas adalah lingkungan eksekusi di dalam dan dari diri mereka sendiri. Tidak ada cara untuk menautkan kode Anda terhadap mereka.


2

Terkadang, bahasa pemrograman Anda tidak memiliki fasilitas yang Anda inginkan, sehingga sebenarnya tidak mungkin untuk menulis fungsi atau makro untuk melakukan apa yang Anda inginkan. Atau mungkin Anda bisa melakukan apa yang Anda inginkan, tetapi kode untuk menulisnya akan jelek. Skrip Python sederhana (atau serupa) kemudian dapat menghasilkan kode yang diperlukan sebagai bagian dari proses build Anda, yang kemudian Anda masukkan #includeke file sumber aktual.

Bagaimana saya tahu ini? Karena ini adalah solusi yang telah saya capai beberapa kali ketika bekerja dengan berbagai sistem yang berbeda, yang terbaru SourcePawn. Skrip Python sederhana yang mem-parsing baris kode sumber sederhana dan menghasilkan dua atau tiga baris kode yang dihasilkan jauh lebih baik daripada secara manual membuat kode yang dihasilkan, ketika Anda berakhir dengan dua lusin baris seperti itu (membuat semua cvars saya).

Kode sumber demonstrasi / contoh tersedia jika orang menginginkannya.


1

Diperlukan bentuk teks agar mudah dikonsumsi oleh manusia. Komputer juga memproses kode dalam bentuk teks dengan cukup mudah. Oleh karena itu kode yang dihasilkan harus dihasilkan dalam bentuk yang paling mudah dibuat dan paling mudah dikonsumsi oleh komputer, dan itu adalah teks yang sangat mudah dibaca.

Dan ketika Anda menghasilkan kode, proses pembuatan kode itu sendiri sering perlu di-debug - oleh manusia. Sangat, sangat berguna jika kode yang dihasilkan dapat dibaca manusia sehingga manusia dapat mendeteksi masalah dalam proses pembuatan kode. Bagaimanapun, seseorang harus menulis kode untuk menghasilkan kode. Itu tidak terjadi karena udara yang tipis.


1

Membuat Kode, sekali saja

Tidak semua generasi kode sumber adalah kasus menghasilkan beberapa kode, dan kemudian tidak pernah menyentuhnya; kemudian meregenerasi dari sumber asli ketika perlu memperbarui.

Terkadang Anda menghasilkan kode hanya sekali, dan kemudian membuang sumber asli, dan bergerak maju mempertahankan sumber baru.

Ini kadang-kadang terjadi ketika porting kode dari satu bahasa ke bahasa lain. Khususnya jika seseorang tidak berharap untuk nantinya porting atas perubahan baru dalam asli (misalnya kode bahasa lama tidak akan dipertahankan, atau itu sebenarnya lengkap (misalnya dalam kasus beberapa fungsi matematika)).

Satu kasus umum adalah bahwa menulis generator kode untuk melakukan ini, mungkin hanya benar-benar menerjemahkan 90% dari kode dengan benar. dan kemudian 10% terakhir perlu diperbaiki dengan tangan. Yang jauh lebih cepat daripada menerjemahkan 100% dengan tangan.

Generator kode seperti itu seringkali sangat berbeda dengan jenis generator kode yang f2cdihasilkan oleh penerjemah bahasa penuh (seperti Cython atau ). Karena tujuannya adalah membuat kode perawatan sekali. Mereka sering dijadikan nomor 1, untuk melakukan apa yang harus mereka lakukan. Dalam banyak hal itu adalah versi tingkat berikutnya dari menggunakan kode regex / find-replace to port. "Alat bantu porting" bisa dibilang.

Membuat Kode, sekali saja, dari misalnya goresan situs web.

Terkait erat adalah jika Anda menghasilkan kode dari beberapa sumber yang tidak ingin Anda akses lagi. Misalnya, jika tindakan yang diperlukan untuk menghasilkan kode tidak dapat diulang, atau konsisten, atau melakukan itu mahal. Saya sedang mengerjakan sepasang proyek saat ini: DataDeps.jl dan DataDepsGenerators.jl .

DataDeps.jl membantu pengguna mengunduh data (seperti kumpulan data ML standar). Untuk melakukan ini diperlukan apa yang kita sebut sebagai RegistrasiBlock. Itu adalah beberapa kode yang menetapkan beberapa metadata, seperti tempat mengunduh file dari, dan sebuah checksum, dan sebuah pesan yang menjelaskan kepada pengguna istilah / kodisi / apa status lisensi pada data tersebut.

Menulis blok itu bisa mengganggu. Dan informasi itu sering tersedia dalam (terstruktur atau tidak terstruktur) dari situs web tempat data dihosting. Jadi DataDepsGenerators.jl, menggunakan webscraper untuk menghasilkan RegistrationBlockCode, untuk beberapa situs yang menampung banyak data.

Mungkin tidak menghasilkan mereka dengan benar. Jadi dev menggunakan kode yang dihasilkan dapat dan harus memeriksa dan memperbaikinya. Kemungkinannya adalah mereka ingin memastikan tidak melewatkan informasi lisensi misalnya.

Yang penting, pengguna / pengembang yang bekerja dengan DataDeps.jl tidak perlu menginstal atau menggunakan webscraper untuk menggunakan kode RegistrationBlock yang dihasilkan. (Dan tidak perlu mengunduh dan menginstal scraper web menghemat waktu yang adil. Khususnya untuk CI menjalankan)

Menghasilkan kode sumber sekali bukan antipattern. dan biasanya tidak bisa diganti dengan metaprogramming.


"report" adalah kata bahasa Inggris yang berarti selain port "lagi". Coba "port ulang" untuk membuat kalimat itu lebih jelas. (Mengomentari karena terlalu kecil untuk sunting yang disarankan.)
Peter Cordes

Tangkapan yang bagus @PeterCordes yang saya ulang.
Lyndon White

Lebih cepat tetapi berpotensi jauh lebih sedikit perawatannya, tergantung pada seberapa mengerikan kode yang dihasilkan. Fortran ke C adalah sesuatu di masa lalu (kompiler C lebih banyak tersedia, sehingga orang akan menggunakan f2c+ cc), tetapi kode yang dihasilkan tidak benar-benar titik awal yang baik untuk versi C dari program, AFAIK.
Peter Cordes

1
Berpotensi, berpotensi tidak. Bukan kesalahan dalam konsep generator kode bahwa beberapa pembuat kode membuat kode yang tidak dapat dipelihara. Secara khusus, alat kerajinan tangan, yang tidak harus menangkap setiap kasus sering dapat membuat kode yang sangat bagus. Jika 90% dari kode hanya daftar konstanta array misalnya maka menghasilkan konstruktor array sebagai satu off dapat dengan mudah dilakukan dengan sangat baik, dan usaha yang rendah. (Di sisi lain, output kode C oleh Cython tidak dapat dipertahankan oleh manusia. Karena tidak dimaksudkan untuk menjadi. Sama seperti yang Anda katakan untuk f2ckembali pada hari itu)
Lyndon White

1
Tabel besar adalah argumen paling sederhana yang paling sederhana. Serupa dapat dikatakan untuk mengatakan mengubah for-loop atau kondisi. Memang sedberjalan jauh, tetapi kadang-kadang seseorang membutuhkan kekuatan yang lebih ekspresif. Garis antara logika program dan data seringkali bagus. Terkadang perbedaannya tidak berguna. JSON adalah (/ dulu) hanya kode konstruktor objek javascript. Dalam contoh saya, saya juga membuat kode konstruktor objek (apakah ini data? Mungkin (mungkin tidak karena kadang-kadang memiliki panggilan fungsi). Apakah lebih baik diperlakukan sebagai kode? Ya.)
Lyndon White

1

Pembuatan kode "sumber" adalah indikasi kekurangan bahasa yang dihasilkan. Apakah menggunakan alat untuk mengatasi ini merupakan pola anti? Sama sekali tidak - biarkan saya jelaskan.

Biasanya pembuatan kode digunakan karena terdapat definisi level yang lebih tinggi yang dapat menggambarkan kode yang dihasilkan jauh lebih sedikit verbose daripada bahasa level yang lebih rendah. Jadi pembuatan kode memfasilitasi efisiensi dan kesederhanaan.

Ketika saya menulis c ++, saya melakukannya karena memungkinkan saya untuk menulis kode lebih efisien daripada menggunakan assembler atau kode mesin. Kode mesin tetap dihasilkan oleh kompiler. Pada awalnya, c ++ hanyalah sebuah preprocessor yang menghasilkan kode C. Bahasa tujuan umum sangat bagus untuk menghasilkan perilaku tujuan umum.

Dengan cara yang sama, dengan menggunakan DSL (bahasa khusus domain) dimungkinkan untuk menulis singkat, tetapi mungkin kode terbatas untuk tugas tertentu. Ini akan membuatnya kurang rumit untuk menghasilkan perilaku kode yang benar. Ingat bahwa kode adalah sarana untuk dan berakhir . Apa yang dicari pengembang adalah cara yang efisien untuk menghasilkan perilaku.

Idealnya generator dapat membuat kode cepat dari input yang lebih mudah untuk dimanipulasi dan dipahami. Jika ini terpenuhi tidak menggunakan generator adalah anti-pola . Anti-pola ini biasanya berasal dari anggapan bahwa kode "murni" adalah "bersih", seperti halnya seorang pekerja kayu atau pengrajin lain mungkin melihat penggunaan alat-alat listrik, atau penggunaan CNC untuk "menghasilkan" benda kerja (pikirkan emas) palu ).

Di sisi lain, jika sumber kode yang dihasilkan lebih sulit untuk mempertahankan atau menghasilkan kode yang tidak cukup efisien pengguna jatuh ke dalam perangkap menggunakan alat yang salah (kadang-kadang karena palu emas yang sama ).


0

Pembuatan kode sumber benar-benar berarti kode yang dihasilkan adalah data. Tetapi ini adalah data kelas satu, data yang dapat dimanipulasi oleh sisa program.

Dua jenis data yang paling umum yang saya ketahui yang terintegrasi ke dalam kode sumber adalah informasi grafis tentang windows (jumlah dan penempatan berbagai kontrol), dan ORM. Dalam kedua kasus, integrasi melalui pembuatan kode memudahkan memanipulasi data, karena Anda tidak harus melalui langkah-langkah "khusus" tambahan untuk menggunakannya.

Ketika bekerja dengan Mac asli (1984), dialog dan definisi jendela dibuat menggunakan editor sumber daya yang menyimpan data dalam format biner. Menggunakan sumber daya ini dalam aplikasi Anda lebih sulit daripada jika "format biner" adalah Pascal.

Jadi, tidak, pembuatan kode sumber bukanlah anti-pola, ini memungkinkan pembuatan data bagian dari aplikasi, yang membuatnya lebih mudah digunakan.


0

Pembuatan kode adalah anti-pola ketika harganya lebih mahal daripada yang dicapai. Situasi ini terjadi ketika pembuatan berlangsung dari A ke B di mana A hampir bahasa yang sama dengan B, tetapi dengan beberapa ekstensi kecil yang dapat dilakukan hanya dengan pengkodean dalam A dengan sedikit upaya daripada semua perkakas khusus dan pembuatan staging untuk A ke B .

Imbalan tersebut lebih menghambat terhadap pembuatan kode dalam bahasa yang tidak memiliki fasilitas pemrograman meta (makro struktural) karena komplikasi dan ketidakmampuan mencapai metaprogramming melalui pementasan pemrosesan teks eksternal.

Pertukaran yang buruk bisa juga terkait dengan jumlah penggunaan. Bahasa A dapat secara substansial berbeda dari B, tetapi seluruh proyek dengan generator kode kustomnya hanya menggunakan A di satu atau dua tempat kecil, sehingga jumlah total kompleksitas (bit kecil A, ditambah generator kode A -> B, ditambah staging build sekitarnya) melebihi kompleksitas solusi yang baru saja dilakukan pada B.

Pada dasarnya, jika kita berkomitmen pada pembuatan kode, kita mungkin harus "pergi besar atau pulang": membuatnya memiliki semantik substansial, dan sering menggunakannya, atau tidak repot-repot.


Mengapa Anda menghapus paragraf "Ketika Bjarne Stroustrup pertama kali menerapkan C ++ ..."? Saya pikir itu menarik.
Utku

@Utku Jawaban lain mencakup hal ini dari sudut pandang penyusunan keseluruhan, bahasa yang canggih, di mana sisa proyek seluruhnya ditulis. Saya tidak berpikir itu mewakili mayoritas dari apa yang disebut "pembuatan kode".
Kaz

0

Saya tidak melihat ini dinyatakan dengan jelas (saya memang melihatnya tersentuh oleh satu atau dua jawaban, tetapi tampaknya tidak terlalu jelas)

Membuat kode (seperti yang Anda katakan, seolah-olah itu adalah data) bukan masalah - ini adalah cara untuk menggunakan kembali kompiler untuk tujuan sekunder.

Mengedit kode yang dihasilkan adalah salah satu anti-pola paling berbahaya yang pernah Anda temui. Jangan lakukan ini.

Paling-paling, mengedit kode yang dihasilkan menarik banyak kode yang buruk ke dalam proyek Anda (set SELURUH kode sekarang benar-benar SUMBER KODE - tidak ada lagi data). Paling buruk, kode yang ditarik ke program Anda sangat berlebihan, sampah dengan nama buruk yang hampir sepenuhnya tidak dapat dipelihara.

Saya kira kategori ketiga adalah kode yang Anda gunakan sekali (generator gui?) Lalu edit untuk membantu Anda memulai / belajar. Ini adalah sedikit dari masing-masing - itu BISA menjadi cara yang baik untuk memulai tetapi generator GUI Anda akan ditargetkan menggunakan kode "Generatable" yang tidak akan menjadi awal yang baik bagi Anda sebagai seorang programmer - Selain itu, Anda mungkin tergoda untuk menggunakannya lagi untuk GUI kedua yang berarti menarik kode SUMBER berlebihan ke sistem Anda.

Jika alat Anda cukup pintar untuk melarang pengeditan apa pun dari kode yang dihasilkan, lakukan saja. Jika tidak, saya akan menyebutnya salah satu pola anti-terburuk di luar sana.


0

Kode dan data keduanya adalah: Informasi.

Data adalah informasi persis dalam bentuk yang Anda butuhkan (dan nilainya). Kode juga merupakan informasi, tetapi dalam bentuk tidak langsung atau menengah. Intinya, kode juga merupakan bentuk data.

Lebih khusus lagi, kode adalah informasi bagi mesin untuk mengeluarkan manusia dari memproses informasi sendiri.

Melepaskan manusia dari pemrosesan informasi adalah motif terpenting. Langkah menengah dapat diterima selama mereka membuat hidup mudah. Itu sebabnya ada alat pemetaan informasi menengah. Seperti generator kode, kompiler, transpiler, dll.

mengapa menghasilkan kode sumber? Mengapa tidak membuatnya menjadi fungsi yang dapat menerima parameter dan menindaklanjutinya?

Katakanlah seseorang menawarkan Anda fungsi pemetaan seperti itu, yang implementasinya tidak jelas bagi Anda. Selama fungsinya berjalan seperti yang dijanjikan, apakah Anda akan peduli apakah secara internal itu menghasilkan kode sumber atau tidak?


0

Jika sesuatu dapat dihasilkan, maka hal itu adalah data, bukan kode.

Sejauh yang Anda tentukan nanti tentang kode itu adalah data, proposisi Anda berkurang menjadi "Jika sesuatu dapat dihasilkan, maka benda itu bukan kode." Jadi, bisakah Anda mengatakan bahwa kode rakitan yang dihasilkan oleh kompiler C bukan kode? Bagaimana jika kebetulan itu bertepatan dengan kode perakitan yang saya tulis dengan tangan? Anda dipersilakan untuk pergi ke sana jika Anda mau, tetapi saya tidak akan ikut dengan Anda.

Mari kita mulai dengan definisi "kode". Tanpa terlalu teknis, definisi yang cukup bagus untuk keperluan diskusi ini adalah "instruksi yang dapat ditindaklanjuti dengan mesin untuk melakukan perhitungan."

Karena itu, bukankah seluruh gagasan pembuatan kode sumber ini merupakan kesalahpahaman?

Ya, proposisi awal Anda adalah bahwa kode tidak dapat dibuat, tetapi saya menolak proposisi itu. Jika Anda menerima definisi saya tentang "kode" maka seharusnya tidak ada masalah konseptual dengan pembuatan kode secara umum.

Yaitu, jika ada generator kode untuk sesuatu, maka mengapa tidak menjadikan sesuatu itu fungsi yang tepat yang dapat menerima parameter yang diperlukan dan melakukan tindakan yang benar bahwa kode "akan dihasilkan" akan dilakukan?

Nah itu pertanyaan yang sama sekali berbeda, tentang alasan mempekerjakan pembuatan kode, bukan tentang sifatnya. Anda mengusulkan alternatif yang alih-alih menulis atau menggunakan pembuat kode, satu menulis fungsi yang menghitung hasilnya secara langsung. Namun dalam bahasa apa? Lewat sudah hari-hari ketika seseorang menulis secara langsung dalam kode mesin, dan jika Anda menulis kode Anda dalam bahasa lain maka Anda bergantung pada pembuat kode dalam bentuk kompiler dan / atau assembler untuk menghasilkan program yang benar-benar berjalan.

Jadi, mengapa Anda lebih suka menulis di Java atau C atau Lisp atau apa pun? Bahkan assembler? Saya menegaskan bahwa itu sebagian karena bahasa-bahasa tersebut menyediakan abstraksi untuk data dan operasi yang membuatnya lebih mudah untuk mengekspresikan rincian perhitungan yang ingin Anda lakukan.

Hal yang sama juga berlaku untuk kebanyakan generator kode level yang lebih tinggi. Kasing prototipe mungkin generator pemindai dan pengurai seperti lexdan yacc. Ya, Anda bisa menulis pemindai dan pengurai langsung dalam bahasa C atau dalam bahasa pemrograman lain pilihan Anda (bahkan kode mesin mentah), dan kadang-kadang orang melakukannya. Tetapi untuk masalah kompleksitas yang signifikan, menggunakan tingkat tinggi, bahasa tujuan khusus seperti lex's atau yacc's membuat kode tulisan tangan lebih mudah untuk menulis, membaca, dan memelihara. Biasanya jauh lebih kecil juga.

Anda juga harus mempertimbangkan apa yang sebenarnya Anda maksud dengan "pembuat kode". Saya akan mempertimbangkan preprocessing C dan instantiation template C ++ sebagai latihan dalam pembuatan kode; apakah Anda keberatan dengan ini? Jika tidak, maka saya pikir Anda perlu melakukan beberapa senam mental untuk merasionalisasi menerima itu tetapi menolak rasa generasi kode lainnya.

Jika itu dilakukan karena alasan kinerja, maka itu terdengar seperti kekurangan dari kompiler.

Mengapa? Anda pada dasarnya berpendapat bahwa seseorang harus memiliki program universal di mana pengguna memasukkan data, beberapa diklasifikasikan sebagai "instruksi" dan yang lain sebagai "input", dan yang mulai melakukan perhitungan dan memancarkan lebih banyak data yang kita sebut "output". (Dari sudut pandang tertentu, orang mungkin menyebut program universal seperti itu sebagai "sistem operasi".) Tetapi mengapa Anda mengira bahwa kompiler harus sama efektifnya dalam mengoptimalkan program tujuan umum seperti halnya dalam mengoptimalkan program yang lebih khusus program? Kedua program memiliki karakteristik dan kemampuan yang berbeda.

Jika sedang dilakukan untuk menjembatani dua bahasa, maka itu terdengar seperti kurangnya antarmuka perpustakaan.

Anda mengatakan bahwa seolah-olah memiliki perpustakaan antarmuka universal-ke-beberapa derajat tentu akan menjadi hal yang baik. Mungkin memang demikian, tetapi dalam banyak kasus perpustakaan seperti itu akan besar dan sulit untuk ditulis dan dipelihara, dan mungkin bahkan lambat. Dan jika binatang seperti itu sebenarnya tidak ada untuk melayani masalah tertentu yang ada, lalu siapa Anda yang bersikeras bahwa seseorang harus diciptakan, ketika pendekatan pembuatan kode dapat menyelesaikan masalah dengan lebih cepat dan mudah?

Apakah saya melewatkan sesuatu di sini?

Beberapa hal, saya pikir.

Saya tahu bahwa kode adalah data juga. Yang tidak saya mengerti adalah, mengapa menghasilkan kode sumber? Mengapa tidak membuatnya menjadi fungsi yang dapat menerima parameter dan menindaklanjutinya?

Pembuat kode mentransformasikan kode yang ditulis dalam satu bahasa menjadi kode dalam bahasa yang berbeda, biasanya tingkat yang lebih rendah. Anda bertanya, lalu, mengapa orang ingin menulis program menggunakan banyak bahasa, dan terutama mengapa mereka mungkin ingin mencampur bahasa dari tingkat yang berbeda secara subyektif.

Tapi saya sudah menyentuh itu. Seseorang memilih bahasa untuk tugas tertentu berdasarkan sebagian pada kejelasan dan ekspresifnya untuk tugas itu. Karena kode yang lebih kecil memiliki lebih sedikit bug rata-rata dan lebih mudah dipelihara, ada juga bias terhadap bahasa tingkat yang lebih tinggi, setidaknya untuk pekerjaan skala besar. Tetapi program yang kompleks melibatkan banyak tugas, dan seringkali beberapa di antaranya dapat ditangani secara lebih efektif dalam satu bahasa, sedangkan yang lain lebih efektif atau lebih ringkas ditangani dalam bahasa lain. Menggunakan alat yang tepat untuk pekerjaan itu terkadang berarti menggunakan pembuatan kode.


0

Menjawab pertanyaan dalam konteks komentar Anda:

Tugas kompiler adalah mengambil kode yang ditulis dalam bentuk yang bisa dibaca manusia dan mengubahnya menjadi bentuk yang bisa dibaca mesin. Oleh karena itu, jika kompiler tidak dapat membuat kode yang efisien, maka kompiler tidak melakukan tugasnya dengan baik. Apakah itu salah?

Kompiler tidak akan pernah dioptimalkan untuk tugas Anda. Alasannya sederhana: ini dioptimalkan untuk melakukan banyak tugas. Ini adalah alat tujuan umum yang digunakan oleh banyak orang untuk berbagai tugas. Setelah Anda tahu apa tugas Anda, Anda dapat mendekati kode dengan cara khusus domain, membuat pengorbanan yang tidak bisa dilakukan oleh kompiler.

Sebagai contoh, saya telah bekerja pada perangkat lunak di mana analis mungkin perlu menulis beberapa kode. Mereka dapat menulis algoritme mereka dalam C ++, dan menambahkan semua batas pemeriksaan dan trik memoisasi yang mereka andalkan, tetapi itu membutuhkan pengetahuan banyak tentang cara kerja kode. Mereka lebih suka menulis sesuatu yang sederhana, dan biarkan saya melempar algoritma untuk menghasilkan kode C ++ akhir. Kemudian saya dapat melakukan trik-trik eksotis untuk memaksimalkan kinerja seperti analisis statis yang tidak akan pernah saya harapkan selama analis saya bertahan. Pembuatan kode memungkinkan mereka untuk menulis dengan cara khusus domain yang memungkinkan mereka mengeluarkan produk dengan lebih mudah daripada alat tujuan umum apa pun.

Saya juga telah melakukan yang sebaliknya. Saya memiliki pekerjaan lain yang telah saya lakukan yang memiliki mandat "tidak menghasilkan kode." Kami masih ingin membuat hidup lebih mudah bagi mereka yang menggunakan perangkat lunak, jadi kami menggunakan pemrograman metap template dalam jumlah besar untuk membuat kompiler membuat kode dengan cepat. Jadi, saya hanya perlu bahasa tujuan C ++ untuk melakukan pekerjaan saya.

Namun, ada yang menangkap. Itu sangat sulit untuk menjamin bahwa kesalahan yang dibaca. Jika Anda pernah menggunakan template metaprogrammed kode sebelumnya, Anda tahu bahwa satu kesalahan tidak bersalah dapat menghasilkan kesalahan yang mengambil 100 baris nama kelas dan argumen templat untuk memahami apa yang salah. Efek ini sangat jelas sehingga proses debugging yang disarankan untuk kesalahan sintaks adalah "Gulir melalui log kesalahan sampai Anda melihat pertama kali salah satu file Anda memiliki kesalahan. Pergi ke baris itu, dan hanya menyipitnya sampai Anda menyadari apa yang Anda melakukan kesalahan. "

Seandainya kami menggunakan pembuatan kode, kami bisa memiliki kemampuan penanganan kesalahan yang jauh lebih kuat, dengan kesalahan yang dapat dibaca manusia. C'est la vie.


0

Ada beberapa cara berbeda dalam menggunakan pembuatan kode. Mereka dapat dibagi dalam tiga kelompok utama:

  • Menghasilkan kode dalam bahasa yang berbeda sebagai hasil dari langkah dalam proses kompilasi. Untuk kompiler biasa, ini akan menjadi bahasa tingkat rendah, tetapi bisa juga ke bahasa tingkat tinggi lain seperti dalam kasus bahasa yang dikompilasi ke JavaScript.
  • Membuat atau mengubah kode dalam bahasa kode sumber sebagai langkah dalam proses kompilasi. Inilah yang makro lakukan.
  • Menghasilkan kode dengan alat secara terpisah dari proses kompilasi biasa. Output dari ini adalah kode yang hidup sebagai file bersama dengan kode sumber reguler dan dikompilasi bersama dengannya. Misalnya kelas entitas untuk ORM mungkin dihasilkan secara otomatis dari skema database, atau objek transfer data dan antarmuka layanan mungkin dihasilkan dari spesifikasi antarmuka seperti file WSDL untuk SOAP.

Saya kira Anda berbicara tentang jenis ketiga kode yang dihasilkan, karena ini adalah bentuk yang paling kontroversial. Dalam dua bentuk pertama kode yang dihasilkan adalah langkah menengah yang sangat bersih dipisahkan dari kode sumber. Tetapi dalam bentuk ketiga tidak ada pemisahan formal antara kode sumber dan kode yang dihasilkan, kecuali kode yang dihasilkan mungkin memiliki komentar yang mengatakan "jangan edit kode ini". Itu masih membuka risiko pengembang mengedit kode yang dihasilkan yang akan sangat jelek. Dari sudut pandang kompiler, kode yang dihasilkan adalah kode sumber.

Namun demikian, bentuk-bentuk kode yang dihasilkan dapat benar-benar berguna dalam bahasa yang diketik secara statis. Misalnya ketika integrasi dengan entitas ORM, sangat berguna untuk memiliki pembungkus yang sangat diketik untuk tabel database. Tentu Anda bisa menangani integrasi secara dinamis saat runtime, tetapi Anda akan kehilangan keamanan jenis dan dukungan alat (penyelesaian kode). Manfaat utama dari jenis bahasa statis adalah dukungan dari sistem tipe pada jenis penulisan daripada hanya pada saat runtime. (Sebaliknya, jenis pembuatan kode ini tidak terlalu lazim dalam bahasa yang diketik secara dinamis, karena dalam bahasa seperti itu tidak ada manfaatnya dibandingkan dengan konversi runtime.)

Yaitu, jika ada generator kode untuk sesuatu, maka mengapa tidak menjadikan sesuatu itu fungsi yang tepat yang dapat menerima parameter yang diperlukan dan melakukan tindakan yang benar bahwa kode "akan dihasilkan" akan dilakukan?

Karena keamanan jenis dan penyelesaian kode adalah fitur yang Anda inginkan pada waktu kompilasi (dan saat menulis kode dalam IDE), tetapi fungsi reguler hanya dijalankan pada saat runtime.

Mungkin ada jalan tengah: F # mendukung konsep penyedia tipe yang pada dasarnya sangat mengetik antarmuka yang dihasilkan secara pemrograman pada waktu kompilasi. Konsep ini mungkin bisa menggantikan banyak penggunaan pembuatan kode, dan memberikan pemisahan perhatian yang lebih bersih.


0

Set instruksi prosesor pada dasarnya penting , tetapi bahasa pemrograman bisa bersifat deklaratif . Menjalankan program yang ditulis dalam bahasa deklaratif pasti membutuhkan beberapa jenis pembuatan kode. Seperti disebutkan dalam jawaban ini dan lainnya, alasan utama untuk menghasilkan kode sumber dalam bahasa yang dapat dibaca manusia adalah untuk mengambil keuntungan dari optimasi canggih yang dilakukan oleh kompiler.


-3

Jika sesuatu dapat dihasilkan, maka hal itu adalah data, bukan kode.

Anda salah jalan. Itu harus dibaca

Jika sesuatu dapat dimasukkan ke generator untuk ditafsirkan , maka hal itu adalah kode, bukan data.

Ini format sumber untuk tahap kompilasi itu, dan format sink masih berupa kode.


1
Definisi kode sumber salah . Kode sumber sebagian besar untuk manusia yang mengerjakannya (dan fakta itu mendefinisikannya, lihat juga apa perangkat lunak bebas oleh FSF). Kode assembler yang dihasilkan dengan gcc -fverbose-asm -O -Sbukan kode sumber (dan bukan hanya atau sebagian besar data), bahkan jika itu adalah beberapa bentuk teks selalu diumpankan ke GNU asdan kadang-kadang dibaca oleh manusia.
Basile Starynkevitch

Juga, banyak implementasi bahasa mengkompilasi ke kode C , tetapi yang dihasilkan C bukan kode sumber asli (misalnya tidak dapat dengan mudah dikerjakan oleh manusia).
Basile Starynkevitch

Akhirnya, perangkat keras Anda (misalnya chip AMD atau Intel, atau motherboard komputer Anda) menafsirkan kode mesin (yang jelas bukan kode sumber). BTW IBM1620 memiliki kode mesin keyboard typable (BCD), tetapi fakta itu tidak menjadikannya "kode sumber". Semua kode bukan sumber.
Basile Starynkevitch

@BasileStarynkevitch Ah, Anda membuat saya di sana. Saya seharusnya tidak mencoba terlalu menekan pernyataan cerdas saya, atau mereka mengubah artinya. Benar, kode sumber harus merupakan kode paling orisinal yang dimasukkan ke dalam tahap kompilasi pertama.
Bergi

Tidak ada kode sumber yang merupakan kode untuk manusia. Sangat sulit dan subjektif untuk didefinisikan sebagai musik (vs suara). Ini bukan masalah mencari perangkat lunak yang mengkonsumsinya.
Basile Starynkevitch
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.