Kompiler pertama ditulis oleh Grace Hopper pada tahun 1952 sedangkan interpreter Lisp ditulis pada tahun 1958 oleh murid John McCarthy Steve Russell. Menulis kompiler sepertinya masalah yang jauh lebih sulit daripada seorang juru bahasa. Jika demikian, mengapa kompiler pertama ditulis enam tahun sebelum penerjemah pertama?
history
compiler
interpreters
anguyen
sumber
sumber
Jawaban:
Itu mungkin benar hari ini, tetapi saya berpendapat bahwa itu tidak terjadi sekitar 60 tahun yang lalu. Beberapa alasan mengapa:
sumber
Poin mendasar adalah bahwa lingkungan perangkat keras komputasi tahun 1950-an membuatnya sedemikian rupa sehingga hanya sebuah kompiler yang layak diberikan pemrosesan batch yang berorientasi pada komputer saat itu.
Pada saat itu antarmuka pengguna yang lebih baik terutama terbatas pada kartu punch dan printer teletype . Pada tahun 1961 sistem SAGE menjadi tampilan Cathode-Ray Tube (CRT) pertama di komputer. Jadi sifat interpreter yang interaktif tidak disukai atau alami sampai kemudian.
Banyak komputer pada 1950-an menggunakan switch panel depan untuk memuat instruksi, dan outputnya hanyalah deretan lampu / LED, dan penggemar bahkan menggunakan switch & LED panel depan ke tahun 1970-an. Mungkin Anda terbiasa dengan Altair 8800 yang terkenal itu .
Keterbatasan perangkat keras lainnya juga membuat juru bahasa menjadi tidak layak. Ada ketersediaan ekstrim terbatas memori primer (misalnya RAM) di komputer pada 1950-an. Sebelum sirkuit terintegrasi semikonduktor (yang tidak datang sampai 1958) memori terbatas pada memori inti magnetik atau memori jalur tunda yang diukur dalam bit atau kata - kata , tanpa awalan. Dikombinasikan dengan lambatnya memori penyimpanan sekunder (misalnya disk atau kaset), akan dianggap boros, jika tidak mustahil memiliki banyak memori yang digunakan untuk penerjemah, bahkan sebelum program yang ditafsirkan dimuat.
Keterbatasan memori masih menjadi faktor utama ketika tim yang dipimpin oleh John Backus di IBM menciptakan compiler FORTRAN pada tahun 1954-57. Kompiler inovatif ini hanya berhasil karena kompiler yang mengoptimalkan .
Sebagian besar komputer di tahun 1950-an nyaris tidak memiliki Sistem Operasi apa pun , apalagi fitur-fitur modern seperti penghubung dinamis dan manajemen memori virtual, sehingga gagasan seorang penerjemah terlalu radikal dan tidak praktis pada waktu itu.
Tambahan
Bahasa tahun 1950-an adalah primitif. Mereka termasuk hanya kecil segelintir operasi, sering dipengaruhi baik oleh instruksi perangkat keras yang mendasari atau definisi masalah penggunaan ditargetkan mereka.
Pada waktu itu, komputer jarang menjadi komputer tujuan umum dalam arti yang kita pikirkan tentang komputer saat ini. Bahwa mereka dapat diprogram ulang tanpa harus dibangun kembali dianggap sebagai konsep revolusioner - sebelumnya orang telah menggunakan mesin elektromekanis (biasanya kalkulator) untuk menghitung atau menghitung jawaban (sebagian besar aplikasi pada tahun 1950 bersifat numerik).
Dari sudut pandang Ilmu Komputer, kompiler dan interpreter sama-sama penerjemah , dan secara umum memiliki kompleksitas yang sama untuk diimplementasikan.
sumber
Bahasa pemrograman pertama cukup sederhana (tidak ada rekursi misalnya) dan dekat dengan arsitektur mesin yang juga sederhana. The terjemahan kemudian proses sederhana .
Kompiler lebih sederhana sebagai sebuah program daripada seorang juru bahasa yang harus menyatukan data untuk eksekusi program dan tabel untuk menginterpretasikan kode sumber. Dan penerjemah akan mengambil lebih banyak ruang , untuk dirinya sendiri, untuk kode sumber program dan untuk tabel simbolik.
Memori bisa sangat langka (untuk alasan biaya dan arsitektur) sehingga kompiler bisa menjadi program yang berdiri sendiri yang menimpa sistem operasi (saya memang menggunakan salah satunya). OS harus dimuat ulang setelah dikompilasi untuk menjalankan program yang dikompilasi. ... yang membuatnya jelas bahwa menjalankan juru bahasa untuk pekerjaan nyata sama sekali bukan pilihan .
Memang benar, kesederhanaan yang diperlukan dari kompiler adalah sedemikian rupa sehingga kompiler tidak terlalu bagus (optimasi kode masih dalam masa pertumbuhan, ketika dipertimbangkan sama sekali). Kode mesin tulisan tangan memiliki, setidaknya sampai akhir tahun enam puluhan di beberapa tempat, reputasi secara signifikan lebih efisien daripada kode yang dihasilkan kompiler. Bahkan ada konsep rasio ekspansi kode , yang membandingkan ukuran kode yang dikompilasi dengan pekerjaan programmer yang sangat baik. Biasanya lebih besar dari 1 untuk sebagian besar (semua?) Kompiler, yang berarti program lebih lambat, dan, lebih penting lagi, program yang lebih besar membutuhkan lebih banyak memori. Ini masih menjadi masalah di tahun enam puluhan.
Ketertarikan kompiler adalah kemudahan pemrograman, terutama bagi pengguna yang tidak menghitung spesialis, seperti ilmuwan di berbagai bidang. Minat ini bukan kinerja kode. Tapi tetap saja, waktu programmer dianggap sumber yang murah. Biaya itu dalam waktu komputer, hingga 1975-1980, ketika biaya beralih dari perangkat keras ke perangkat lunak. Yang berarti bahwa bahkan kompiler tidak dianggap serius oleh beberapa profesional .
Biaya waktu komputer yang sangat tinggi adalah alasan lain untuk mendiskualifikasi penafsir , sampai-sampai ide itu sangat menggelikan bagi kebanyakan orang.
Kasus Lisp sangat istimewa, karena itu adalah bahasa yang sangat sederhana yang membuatnya layak (dan komputer menjadi sedikit lebih besar di 58). Lebih penting lagi, interpreter Lisp adalah bukti konsep mengenai self definability Lisp ( meta-circularity ), terlepas dari masalah kegunaan.
Keberhasilan Lisp sebagian besar disebabkan oleh kenyataan bahwa definisi diri ini membuatnya menjadi testbed yang sangat baik untuk mempelajari struktur pemrograman dan merancang bahasa baru (dan juga untuk kenyamanannya untuk komputasi simbolik).
sumber
Saya tidak setuju dengan premis pertanyaan.
Adm. Kompiler pertama Hopper (A-0) lebih seperti linker atau bahasa makro. Dia menyimpan subrutin pada kaset (masing-masing diberi nomor) dan program-programnya akan ditulis sebagai daftar subrutin dan argumen. Kompiler akan menyalin subrutin yang diminta dari tape dan memesannya kembali ke dalam program yang lengkap.
Dia menggunakan kata "kompilasi" dalam arti yang sama seperti seseorang menyusun antologi puisi: mengumpulkan berbagai item menjadi satu volume.
Kompiler pertama itu tidak memiliki lexer atau parser, sejauh yang saya tahu, yang membuatnya menjadi leluhur jauh dari kompiler modern. Dia kemudian membuat kompiler lain (B-0, alias FLOW-MATIC) dengan tujuan sintaksis yang lebih mirip bahasa Inggris, tetapi tidak selesai sampai 1958 atau 1959 - sekitar waktu yang sama dengan interpreter Lisp.
Karena itu, saya pikir pertanyaannya sendiri agak keliru. Tampaknya para penyusun dan penafsir ikut berevolusi hampir persis pada saat yang sama, tidak diragukan lagi karena berbagi gagasan yang akan membuat banyak ilmuwan berpikir sepanjang garis yang sama pada masa itu.
Jawaban yang lebih baik dengan kutipan di sini: https://stackoverflow.com/a/7719098/122763 .
sumber
Bagian lain dari persamaan adalah bahwa kompiler adalah abstraksi langkah di atas assembler. Pertama, kami memiliki kode mesin hard-coded. "Kami" adalah assembler. Setiap lompatan dan offset, dll. Dihitung tangan menjadi hex (atau oktal) dan kemudian ditinju ke pita kertas atau kartu. Jadi ketika perakit datang ke tempat kejadian, itu adalah penghemat waktu yang sangat besar. Langkah selanjutnya adalah assembler makro. Itu memberi kemampuan untuk menulis makro yang akan berkembang menjadi seperangkat instruksi mesin. Jadi Fortran dan Cobol adalah langkah maju yang besar. Kurangnya sumber daya (penyimpanan, memori, dan siklus CPU) berarti bahwa penerjemah serba guna harus menunggu teknologi tumbuh. Kebanyakan penerjemah awal adalah mesin byte-code (seperti Java atau CLR saat ini, tetapi dengan kemampuan yang jauh lebih sedikit). UCSD Pascal adalah bahasa yang sangat populer (dan cepat). MS Basic adalah mesin kode byte di bawah tenda.
Dalam hal overhead instruksi, itu benar-benar tergantung pada prosesor apa yang sedang dijalankan. Industri ini mengalami pergolakan besar RISC vs CISC untuk sementara waktu. Saya pribadi menulis assembler untuk IBM, Data General, Motorola, Intel (ketika mereka muncul), TI, dan beberapa lainnya. Ada perbedaan yang cukup signifikan dalam set instruksi, register, dll. Yang akan mempengaruhi apa yang diperlukan untuk "menafsirkan" kode-p.
Sebagai referensi waktu, saya mulai pemrograman di perusahaan telepon sekitar tahun 1972.
sumber
Jika Anda tidak menyimpan semuanya dalam memori, kode yang dikompilasi jauh lebih cepat. Jangan lupa, bahwa pada saat-saat ini fungsi digabungkan dengan kode yang dikompilasi. Jika Anda tidak mengkompilasi, Anda tidak tahu fungsi apa yang Anda perlukan. Jadi, Anda memanggil fungsi dari ... Oh, belum dari disk, kami berada di awal 50-ikatan, tetapi dari kartu! Dalam runtime!
Tentu saja, adalah mungkin untuk menemukan solusi, tetapi mereka belum ditemukan, karena bahasa sangat sederhana dan tidak jauh dari kode mesin. Dan kompilasi itu mudah dan cukup.
sumber
Sebelum kompiler pertama ditulis, orang menulis kode assembler yang merupakan kemajuan besar dibandingkan dengan kode biner biasa. Pada saat itu, ada argumen kuat bahwa kode yang dikompilasi oleh kompiler akan kurang efisien daripada kode assembler - pada saat itu hubungan (biaya komputer) dengan (biaya programmer) jauh, jauh berbeda dari hari ini. Jadi ada resistensi yang kuat terhadap kompiler dari sudut pandang itu.
Tetapi kompiler jauh lebih efisien daripada penerjemah. Jika Anda menyarankan untuk menulis juru bahasa pada saat itu, orang akan mengira Anda gila. Dapatkah Anda bayangkan membeli komputer jutaan dolar dan kemudian menghabiskan 90% dari kekuatannya untuk menafsirkan kode?
sumber
Sebelum program pengulangan dapat ditafsirkan, harus disimpan dalam media yang dapat dibaca berulang kali. Dalam kebanyakan kasus, satu-satunya media yang cocok adalah RAM. Karena kode biasanya akan dimasukkan pada kartu berlubang yang - untuk bahasa yang dapat dibaca manusia - kemungkinan besar kosong, beberapa jenis pemrosesan harus dilakukan pada kode sebelum disimpan dalam RAM. Dalam banyak kasus, memproses teks kartu berlubang menjadi bentuk yang sesuai untuk eksekusi langsung oleh prosesor sebenarnya tidak lebih sulit daripada memprosesnya menjadi bentuk yang dapat ditangani secara efisien melalui juru bahasa.
Perhatikan bahwa tujuan dari kompiler awal bukan untuk menghasilkan file kode bahasa-bahasa atau objek-perakitan pada disk, melainkan untuk mengakhiri kode dalam RAM yang siap dijalankan. Ini sebenarnya sangat mudah ketika tidak ada sistem operasi yang menghalangi. Kompiler dapat menghasilkan kode mulai dari satu ujung memori dan mengalokasikan variabel dan target cabang mulai dari yang lain. Jika pernyataan ditandai dengan label "1234", kompiler akan menyimpan dalam variabel yang disebut "1234" instruksi untuk melompat ke alamat pembuatan kode saat ini, membuat variabel itu jika tidak ada. Pernyataan "goto 1234" akan membuat variabel "1234" jika tidak ada, dan kemudian melompat ke variabel itu [yang diharapkan akan memiliki lompatan ke lokasi yang tepat disimpan di dalamnya sebelum pernyataan itu dijalankan].
goto
label yang belum didefinisikan, karena ia tahu kapangoto
kompilasi di mana ia akan melompat - ke variabel. Itu mungkin bukan cara yang paling efisien untuk menghasilkan kode, tetapi itu cukup untuk ukuran program yang diharapkan dapat ditangani oleh komputer.sumber
Karena penerjemah membutuhkan kompiler untuk bekerja.
Pernyataan di atas tidak benar. Sebenarnya, Anda dapat membuat juru bahasa tanpa pernah menggunakan atau berinteraksi dengan kompiler. Tetapi hasil dari melakukan ini tidak akan terlihat seperti apa yang saya pikir Anda maksud dengan istilah-istilah itu.
Dalam arti yang ketat, kompiler dan penerjemah melakukan hal yang sama sekali berbeda. Compiler membaca teks dari beberapa sumber, dan mengubahnya menjadi beberapa format lain: bahasa assembly, kode mesin, bahasa tingkat tinggi lainnya, struktur data, atau apa pun. Seorang penerjemah, sementara itu, mengambil struktur data dari beberapa jenis, dan melakukan instruksi berdasarkan itu.
Apa yang kita anggap sebagai "kompiler" saat ini sebenarnya adalah kompiler yang telah dipasangkan dengan generator kode : program yang mengambil data dari beberapa sumber, dan kode keluaran dalam beberapa format berdasarkan pada apa yang dilihatnya. Itu penggunaan yang cukup intuitif untuk kompiler, dan itu adalah salah satu hal pertama yang dibuat untuk kompiler. Tetapi jika Anda melihatnya dengan cara lain, ini tampak sangat mirip dengan apa yang dilakukan penerjemah. Selalu mengeluarkan kode alih-alih melakukan operasi yang lebih umum, tetapi prinsipnya sama.
Jika kita melihatnya dari sisi lain, seorang juru bahasa perlu mendapatkan datanya dari suatu tempat . Ini hanya data, jadi Anda bisa membangunnya dengan cara yang sama seperti membangun data apa pun lainnya. Karena kita sedang berbicara tentang interpretasi, tampaknya wajar bahwa Anda dapat membangun data Anda berdasarkan instruksi dalam file teks. Tetapi untuk melakukan itu, Anda perlu sesuatu untuk dibaca dalam teks dan membuat struktur data Anda, dan itu adalah kompiler . Ini terhubung ke juru alih-alih ke generator kode, tapi itu adalah kompiler yang sama.
Itu sebabnya kompiler ditulis terlebih dahulu. Gagasan menafsirkan struktur data bukanlah hal baru bahkan ketika kompiler disusun, tetapi kompiler adalah "mata rantai yang hilang" yang memungkinkan pemrogram membangun struktur tersebut dari teks.
sumber
Faktor lain: Ketika kompiler pertama ditulis, biaya waktu mesin jauh lebih tinggi daripada sekarang. Juru bahasa menggunakan lebih banyak waktu mesin.
sumber