Apakah sintaks bahasa pemrograman tergantung pada implementasinya?

12

Meskipun, pertanyaan saya mungkin sama sekali tidak relevan, tetapi saya telah merasakan pola antara sebagian besar bahasa pemrograman dan implementasi resmi mereka.

Bahasa yang ditafsirkan (byte-ditafsirkan?) Seperti Python, Lua dll. Biasanya memiliki sintaks yang sangat lunak dan mudah dan umumnya bertipe kurang atau tidak mengharuskan pengembang untuk secara eksplisit menulis jenis variabel dalam kode sumber;

Bahasa yang dikompilasi seperti C, C ++, Pascal dll. Biasanya memiliki sintaks yang ketat, umumnya memiliki jenis dan sebagian besar membutuhkan lebih banyak kode / waktu pengembangan

Bahasa yang implementasi resminya dikompilasi dengan JIT seperti Java / C # biasanya merupakan kompromi unik antara keduanya dengan beberapa fitur terbaik dari keduanya.

Beberapa bahasa pemrograman terkompilasi yang lebih modern seperti D dan Vala (dan implementasi Java GNU GJC) mungkin pengecualian untuk aturan ini dan menyerupai Sintaks dan fitur bahasa yang dikompilasi JIT seperti Java dan C #.

Pertanyaan pertama saya adalah, apakah ini benar-benar relevan? Atau apakah ini hanya kebetulan bahwa sebagian besar bahasa yang ditafsirkan memiliki sintaks mudah, yang dikompilasi JIT memiliki sintaks dan fitur moderat dll.

Kedua, jika ini bukan kebetulan, lalu mengapa demikian? Seperti, misalnya, dapatkah beberapa fitur hanya diimplementasikan dalam bahasa pemrograman jika Anda, katakanlah, mengkompilasi JIT?

ApprenticeHacker
sumber
@YannisRizos maaf, ini bukan kutipan. Saya hanya ingin menyorotnya. Saya akan mengeditnya.
ApprenticeHacker
1
Keren, saya pikir itu bukan kutipan tapi itu bisa menyebabkan penjawab berpikir itu salah dan tidak mencoba untuk membantahnya (atau secara membuta setuju dengan itu) ... Saya telah memperhatikan pola yang sama tetapi sayangnya tidak memiliki yang baik menjawab.
yannis
@ R. Martinho, maaf maaf, saya tidak menyadarinya. Saya akan mengeditnya (lagi).
ApprenticeHacker
4
Perl diketik secara dinamis untuk tipe yang ditentukan pengguna, diketik secara statis berkenaan dengan array yang membedakan, hash, skalar, dan subrutin, dan sangat diketik melalui penggunaan yang ketat, ditafsirkan dan JIT dikompilasi (tidak pada saat yang sama tentu saja) ... Setiap kali seseorang mencoba untuk memahami desain bahasa, melemparkan beberapa Perl selalu menyenangkan ...
yannis
3
Apa yang Anda maksud dengan "sintaks lunak" vs "sintaks ketat"? Mereka semua bahasa formal dan tidak ada yang akan menjalankan kode sumber dengan kesalahan sintaksis.
nikie

Jawaban:

17

Tidak ada koneksi apa pun antara semantik dan sintaksis. Bahasa yang dikompilasi homoikonik seperti Skema hadir dengan sintaksis yang cukup minimalis. Meta-bahasa terkompilasi tingkat rendah seperti Forth bahkan lebih sederhana dari itu. Beberapa bahasa yang dikompilasi sangat ketat dibangun di atas sintaks sepele (pikirkan ML, Haskell). OTOH, sintaksis Python sangat berat, dalam hal sejumlah aturan sintaksis.

Dan ya, pengetikan tidak ada hubungannya dengan sintaksis, pengetikan ada di sisi semantik bahasa, kecuali itu sesuatu yang sesat seperti C ++, di mana Anda bahkan tidak dapat menguraikan tanpa memiliki semua informasi pengetikan yang tersedia.

Kecenderungan umum adalah bahwa bahasa yang berevolusi terlalu lama dan tidak mengandung perlindungan desain terhadap penyimpangan sintaksis cepat atau lambat akan berkembang menjadi kekejian sintaksis.

Logika SK
sumber
+1 untuk membuat saya mencari "homoikonik" ... Dan untuk anggukan halus ke PHP ...
yannis
1
+1, bahasa yang berevolusi terlalu lama dan tidak mengandung perlindungan desain apa pun , apakah ini juga merujuk ke Delphi / Object-Pascal?
ApprenticeHacker
1
@ Thomas, Anda salah. Semantik yang sama dapat diimplementasikan di atas berbagai gaya sintaks yang sangat luas, bahkan dengan bahasa tanpa sintaksis (seperti Lisp atau Forth). Sintaks yang sama dapat digunakan dengan variasi semantik yang sangat luas - misalnya, sintaksis ekspresi C dan Verilog hampir sama, tetapi semantik berbeda secara dramatis.
SK-logic
1
@ SK-logic - Hanya karena kompleks dan Turing-complete tidak berarti itu bukan bagian yang sangat besar dari sintaks program. Parsing berbagai bahasa adalah Turing-complete, yang tidak secara ajaib membuat parsing sesuatu yang "tidak ada hubungannya dengan sintaks". Sintaks bukan tentang "ruang lingkup", ini tentang aturan untuk struktur pernyataan dalam bahasa - tanpa mengatakan apa-apa tentang apa arti pernyataan itu. Pengecekan tipe dan inferensi tipe beroperasi pada sintaksis program tanpa menjalankannya - mereka menentukan hal-hal tentang struktur program tanpa mengatakan apa pun tentang ...
Jack
1
@ Jack, Anda mencoba mendefinisikan kembali apa itu sintaks. Tidak ada bahasa praktis yang membutuhkan parser lengkap Turing, sebagian besar tidak lebih dari konteks bebas. Dan di sinilah sintaks harus tinggal. Tolong jangan memperpanjang gagasan ini (sudah terlalu meluas) di tempat lain. Dan saya sudah menyebutkan isomorfisme Curry-Howard - ini semua tentang semantik, jauh melampaui aturan kebenaran. Saya pikir, istilah " type checking" sangat kontraproduktif dan tidak boleh digunakan, sangat menyesatkan, tidak mencerminkan sifat sistem tipe.
SK-logic
6

Sebagian besar ini adalah kebetulan.

Bahasa pemrograman telah berkembang dari waktu ke waktu, dan teknologi kompiler dan interpreter telah meningkat. Efisiensi pemrosesan yang mendasarinya (yaitu waktu kompilasi, overhead interpreting, waktu eksekusi, dll.) Juga kurang penting karena platform komputasi arus utama semakin kuat.

Sintaks bahasa memang memiliki dampak - misalnya, Pascal dirancang dengan sangat hati-hati sehingga dapat menggunakan kompiler pass tunggal - yaitu satu pass melewati sumber dan Anda memiliki kode mesin excutable. Ada di sisi lain tidak memperhatikan hal ini, dan kompiler Ada terkenal sulit untuk ditulis - kebanyakan memerlukan lebih dari satu pass. (Satu kompiler Ada yang sangat bagus yang saya gunakan bertahun-tahun yang lalu adalah kompiler 8 pass. Seperti yang Anda bayangkan, itu sangat lambat.)

Jika Anda melihat bahasa lama seperti Fortran (dikompilasi) dan BASIC (ditafsirkan atau dikompilasi) mereka memiliki / memiliki aturan sintaksis dan semantik yang sangat ketat. [Dalam kasus BASIC, itu bukan BASIC tagihan, Anda harus kembali sebelum itu ke aslinya.]

Di sisi lain, melihat hal-hal yang lebih tua lainnya seperti APL (banyak kesenangan) semacam ini mengetik dinamis. Itu juga umumnya ditafsirkan tetapi bisa dikompilasi juga.

Sintaks Lenient adalah yang sulit - jika itu berarti Anda memiliki hal-hal yang opsional atau dapat disimpulkan maka itu berarti bahasanya memiliki kekayaan yang cukup sehingga dapat dimusnahkan. Kemudian lagi, BASIC memilikinya beberapa tahun yang lalu ketika pernyataan "LET" menjadi opsional!

Banyak ide yang sekarang Anda lihat (misalnya, mengetik tanpa atau mengetik dinamis) sebenarnya sangat lama - pertama kali muncul di tahun 1970-an atau awal 1980-an. Cara mereka digunakan, dan bahasa yang digunakan oleh gagasan-gagasan ini telah berubah dan berkembang. Tetapi pada dasarnya, banyak hal baru sebenarnya adalah barang-barang lama yang berpakaian baru.

Berikut adalah beberapa contoh di atas kepala saya:

  • APL: pengetikan dinamis. Umumnya diartikan. Datang dari tahun 1960-an / 1970-an.
  • BASIC: pengetikan kuat atau dinamis. Ditafsirkan atau dikompilasi. 1970-an dan banyak lagi.
  • Fortran: pengetikan yang kuat. Disusun. 1960-an atau lebih awal.
  • Algol68: pengetikan yang kuat. Disusun. 1960-an.
  • PL / 1: pengetikan yang kuat. Disusun. 1960-an.
  • Pascal: pengetikan yang kuat. Disusun. 1970-an. (Tetapi pada 1980-an ada kompiler P-System yang sangat mirip dengan kompiler JIT!)
  • Beberapa implementasi Fortran dan lainnya oleh DEC pada hari-hari awal sebagian dikompilasi dan ditafsirkan sebagian.
  • Smalltalk: pengetikan dinamis. Dikompilasi menjadi bytecode yang ditafsirkan. 1980-an.
  • Prolog: lebih banyak keanehan. Fungsional Dikompilasi (Turbo Prolog, ada orang?). 1980-an.
  • C: mengetik kuat (ha ha). Disusun. 1960-an..Hari ini.
  • Ada: mengetik dengan kuat. Disusun. 1980-an.
  • Perl: pengetikan dinamis. (Sintaks yang kuat). Diterjemahkan. 1990-an (?).

Saya bisa melanjutkan.

  • Nitpickers corner: Banyak bahasa yang ditafsirkan diberi tanda atau "byte dikompilasi" pada saat sumbernya dimuat / dibaca. Ini membuat operasi juru bahasa selanjutnya menjadi lebih sederhana. Terkadang Anda dapat menyimpan versi kode yang dikompilasi dengan byte. Terkadang kamu tidak bisa. Masih ditafsirkan.

Pembaruan: Karena saya tidak cukup jelas.

Mengetik bisa sangat bervariasi.

Pengetikan waktu statis yang tetap dikompilasi adalah umum (misalnya, C, Ada, C ++, Fortan, dll.). Di sinilah Anda mendeklarasikan HAL dari JENIS dan seperti itu selamanya.

Dimungkinkan juga untuk memiliki pengetikan dinamis, di mana benda tersebut mengambil jenis yang ditugaskan padanya. Sebagai contoh, PHP dan BASIC awal, dan APL, di mana Anda akan menetapkan integer ke variabel dan sejak saat itu merupakan tipe integer. Jika Anda kemudian menetapkan string untuknya, maka itu adalah tipe string. Dan seterusnya.

Dan kemudian ada pengetikan yang longgar, misalnya PHP di mana Anda dapat melakukan hal-hal yang benar-benar aneh seperti menetapkan bilangan bulat numerik (dikutip, jadi ini sebuah string) ke variabel dan kemudian menambahkan angka ke dalamnya. (mis. '5' + 5 akan menghasilkan 10). Ini adalah tanah yang aneh, tetapi juga pada saat yang sangat sangat berguna.

NAMUN ini adalah fitur yang dirancang ke dalam bahasa. Implementasinya hanya membuat itu terjadi.

dengan cepat_now
sumber
13
Mengetik dengan kuat bukanlah bagian dari pengetikan dinamis. Ini adalah bagian dari pengetikan yang lemah. Mitra dari pengetikan dinamis adalah pengetikan statis: dalam satu, jenis ekspresi dalam suatu program dapat diketahui secara statis (yaitu tanpa menjalankan program); di lain jenis hanya dapat diketahui secara dinamis (yaitu program harus dijalankan).
R. Martinho Fernandes
Ya dan kedua varian BASIC dan APL melakukan ini pada akhir tahun 1970-an. Jenis APL tidak cukup seperti yang kita pahami saat ini (menjadi hal-hal seperti integer / float yang diketik secara universal tetapi juga bisa berupa vektor, string, dan matriks multi-dimensi).
cepat,
Interpreter Fortran masih banyak digunakan (lihat Cernlib dan PAW). Dan turunannya, ROOT, dibangun di atas penerjemah C ++.
SK-logic
Saya tidak sepenuhnya jelas seberapa kuat / lemah dan statis / dinamis berkaitan dengan sintaks, jujur. Tapi kualitas jawabannya cukup bagus, jadi saya hanya menghindari upvoting. Saya akan mengetik kelas C sebagai "statis / lemah" (itu sepele untuk melihat nilai yang disimpan seolah-olah itu jenis lain, mungkin mendapatkan nilai yang salah).
Vatine
@Vatine - Saya benar-benar akan mengatakan kuat pada waktu kompilasi, tidak ada pada saat run - jika Anda menginginkannya. Anda dapat melakukannya dengan menggunakan pointer dan padanannya dalam banyak bahasa. Bahkan mungkin dalam pascal klasik menggunakan catatan varian, dan di Ada menggunakan UNCHECKED_CONVERSION (meskipun sulit, itu mungkin).
cepat_now
2

Saya pikir itu sebaliknya: implementasi tergantung pada sintaksis. Misalnya, jika sintaks Anda memungkinkan untuk refleksi, maka implementasinya harus menyediakan runtime yang mendukungnya.

StackedCrooked
sumber
@IntermediateHacker: tapi di java, jadi saya harus mengagumkan
sehe
2

Saya biasanya setuju dengan quick_now karena pengamatan Anda terutama adalah hasil dari sejarah. Yang mengatakan, alasan yang mendasarinya bermuara pada sesuatu seperti ini:

The more modern a language is, the more comfortable it should be to use.

(Bukan kutipan sebenarnya, hanya rumusan saya sendiri.) Ketika saya menulis di comfortablesini, saya merujuk pada apa yang Anda panggil best features of both. Lebih tepatnya, saya tidak ingin berbicara untuk atau terhadap pengetikan statis / dinamis atau sintaksis ketat / lunak. Sebaliknya, penting untuk melihat fokus ditempatkan pada pengembang dan meningkatkan tingkat kenyamanan mereka ketika bekerja dengan bahasa tersebut.

Berikut adalah beberapa alasan, yang belum disebutkan dalam jawaban sebelumnya, yang mungkin memberi Anda beberapa ide mengapa Anda mengamati hal-hal ini (dan semuanya didasarkan pada sejarah pemrograman pengembangan bahasa):

  • Kami memiliki ratusan bahasa pemrograman akhir-akhir ini. Ketika yang baru muncul, bagaimana bisa menemukan audiens yang luas? Ini adalah alasan utama, mengapa bahasa baru selalu berusaha meningkatkan tingkat kenyamanan pengembang. Jika bahasa dapat melakukan hal yang sama seperti yang lebih tua, tetapi dapat melakukannya dengan lebih mudah / sederhana / lebih elegan / dll. Anda mungkin ingin mempertimbangkan untuk beralih.

  • Kurva pembelajaran berjalan seiring dengan itu. Di masa lalu, kami hanya memiliki sedikit bahasa dan menginvestasikan waktu untuk belajar bahasa tidak sia-sia. Bahkan jika itu berarti menginvestasikan banyak waktu. Kenyamanan kembali meningkat, jika Anda menemukan bahasa yang dapat dipelajari pengembang dengan sangat cepat. Kompleksitas jenis apa pun (mis., Sintaks yang terlibat rumit) merugikan hal ini, dan karenanya, semakin berkurang dalam bahasa yang lebih baru.

  • Kemajuan teknologi (alasan historis langsung di sini) bertanggung jawab bahwa pembangun kompiler sekarang dapat lebih fokus pada kenyamanan pengembang. Pada hari-hari awal, kami senang bisa membangun kompiler sama sekali. Namun, hal itu seringkali menyiratkan pembatasan berat yang dibuat. Seiring dengan meningkatnya pengetahuan teknologi, kami dapat mengangkat pembatasan ini lagi.

Jadi secara umum, bahasa pemrograman dan kompiler telah melihat perkembangan yang mirip dengan aplikasi pengguna akhir yang khas:

  1. Tahap awal: Ini hal yang keren untuk dimiliki, tetapi teknologi pendarahan nyaris tidak membuatnya bekerja dengan biaya kenyamanan / kegunaan / apa-tidak.
  2. Peningkatan teknologi: Kita dapat membangun hal-hal ini lebih kuat, lebih cepat, dan lebih mudah.
  3. Fokus beralih ke pengguna: Sama halnya dengan gerakan Web2.0 yang berfokus pada pengalaman pengguna, bahasa pemrograman baru fokus pada perspektif pengembang.
jujur
sumber
(Not a quote really, just my own formulation.)Nah, Anda memformatnya sebagai kode, bukan sebagai blockquote, jadi saya tidak berpikir ada yang mengira itu adalah kutipan :)
yannis
3
Kenyamanan jelas tergantung pada rasa (yang selalu sepenuhnya subjektif). Bahasa yang paling nyaman bagi saya dirancang pada tahun 1959, dan saya tidak tahan menghadapi beberapa bahasa yang muncul pada abad ini.
SK-logic
1
Kenyamanan juga tergantung pada tujuannya. Menjalankan PHP atau Prolog pada mikro tertanam 8k untuk pengontrol mesin cuci mungkin "nyaman" untuk diprogram, tetapi juga sangat sulit untuk membuatnya benar-benar cocok dan berjalan dengan kinerja yang dapat diterima.
cepat,
0

Bahasa pemrograman yang diberikan mungkin atau mungkin tidak mengekspos atau membatasi informasi semantik yang cukup bagi kompiler untuk menyimpulkan bagaimana menguranginya menjadi kode yang dapat dieksekusi tanpa menambahkan keputusan runtime ("apa jenis variabel ini?", Dll.) Beberapa bahasa secara eksplisit dirancang untuk membuat kendala ini wajib, atau mudah ditentukan.

Ketika kompiler menjadi lebih pintar, mereka mungkin dapat menebak atau membuat profil informasi yang cukup untuk menghasilkan kode yang dapat dieksekusi untuk jalur yang paling mungkin bahkan untuk bahasa yang tidak dirancang secara eksplisit untuk mengekspos atau membatasi keputusan tersebut.

Namun, bahasa tempat kode (evalString ()) dapat dibuat atau dimasukkan saat runtime (dan hal-hal lain yang tidak dapat disimpulkan atau dikompilasi oleh kompiler) mungkin memerlukan penerjemah atau kompiler JIT agar tersedia saat runtime, bahkan dengan upaya untuk kompilasi mereka.

Di masa lalu, bahasa pemrograman dan implementasinya mungkin telah berkembang sehingga sesuai dengan beberapa kendala perangkat keras, seperti apakah penerjemah mungkin muat dalam 4k atau 16k, atau apakah kompiler mungkin selesai dalam waktu CPU kurang dari satu menit. Ketika mesin menjadi lebih cepat, menjadi mungkin untuk (kembali) mengkompilasi beberapa program yang sebelumnya ditafsirkan secepat programmer dapat menekan tombol kembali, atau menafsirkan kode sumber program yang dikompilasi sebelumnya lebih cepat daripada perangkat keras yang sedikit lebih tua dapat menjalankan executable kompilasi yang dioptimalkan.

hotpaw2
sumber