Bahasa pemrograman di mana setiap ekspresi masuk akal

23

Per rekomendasi saya memposting ulang ini dari Stack Overflow .

Baru-baru ini saya telah memikirkan masalah berikut.

Pertimbangkan kode untuk standar "Halo dunia!" program:

main()
{
    printf("Hello World");

}

Sekarang hampir semua perubahan dalam kode ini akan membuatnya benar-benar tidak berguna, bahkan hampir setiap perubahan akan mencegah kompilasi kode. Sebagai contoh:

main(5
{
    printf("Hello World");

}

Sekarang untuk pertanyaan aktual. Apakah ada bahasa pemrograman di mana setiap kemungkinan kombinasi simbol - yaitu, setiap ekspresi - masuk akal? Saya mencoba memikirkan semacam solusi dan menghasilkan dua:

  1. Postfix dengan sejumlah variabel terbatas. Pada dasarnya semua variabel sudah ditentukan sebelum Anda menulis kode apa pun dan Anda harus bekerja hanya dengan mereka. Secara teoritis Anda dapat daripada melakukan sejumlah operasi sewenang-wenang dengan membentuk rantai banyak program sederhana, masing-masing memberikan hasil kepada orang lain. Kode dapat ditulis sebagai serangkaian karakter dalam notasi postfix;

  2. "Postfix" dengan setumpuk variabel. Variabel disimpan di tumpukan; setiap operasi mengambil dua variabel dari atas dan menempatkan hasilnya di tempatnya. Program berakhir ketika mencapai operasi atau variabel terakhir.

Secara pribadi saya benci keduanya. Tidak hanya terbatas, mereka juga tidak bagus. Mereka bahkan bukan solusi nyata, lebih seperti pemecahan masalah, pada dasarnya "offshoring" beberapa pekerjaan untuk proses eksternal.

Adakah yang punya ide lain bagaimana mengatasi masalah ini?

pengguna1561358
sumber
48
Mengingat compiler , membuat compiler baru yang bekerja sebagai berikut: diberikan sumber , menyebarkannya ke . Jika senang dan menghasilkan executable, maka itu adalah itu, tetapi jika mengeluh maka output executable yang mencetak Compiler menerima setiap string sebagai program yang valid. C s C C C C CCsCCCYou are a bimbo.C
Andrej Bauer
1
BF membutuhkan [ ]perintah yang cocok (Menurut Halaman Wiki). Pikiran saya adalah melihat opcodes CPU. Tetapi meskipun demikian, beberapa pola dapat menghasilkan masalah (misalnya, jika opcode adalah 3 bit, tetapi program Anda hanya 2 bit.) Kecuali untuk masalah ini mungkin padding dengan beberapa 0 bit tambahan, orang dapat berpikir pada CPU dengan set opcode lengkap yang akan memenuhi klaim "setiap string adalah program yang valid". Mungkin tidak berarti, tetapi masih valid.
Ran G.
1
Biarkan perangkat keras Anda menjadi Z-80 CPU dengan 64k RAM. Tulis kompiler yang hanya menyalin kode sumber ASCII-kode ke memori 64k (memotong atau nol-padding jika perlu). Kompiler ini tidak pernah memberikan kesalahan sintaksis.
Ben Crowell
1
@RANG. 'Compiler' yang memproses bitstream apa pun dan memperbaikinya menjadi sedikit kode objek yang valid untuk prosesor yang diberikan, saya pikir, akan memenuhi persyaratan OP. Kemungkinan tidak akan terlalu sulit bahkan untuk sistem dengan set instruksi yang kompleks seperti x86. Saya membaca makalah bertahun-tahun yang lalu tentang validitas byte acak sebagai program x86 dan menemukan bahwa x86 sebenarnya jauh lebih kuat daripada yang diharapkan penulis.
otakucode
2
Tanpa syarat lebih lanjut, pertanyaan ini membosankan: komentar Andrej dan jawaban David memberikan jawaban "sepele". Anda harus memakukan dengan tepat apa yang Anda inginkan.
Raphael

Jawaban:

31

Redcode, bahasa assembly di belakang codewars, secara eksplisit ditulis untuk memiliki sangat sedikit instruksi penghentian, karena kode tersebut sering hancur sebelum akhirnya diberikan, dan semakin banyak kesempatan untuk berhenti, semakin tidak menarik permainannya.

Anda melihat sangat sedikit bahasa seperti itu dalam praktiknya karena kami tidak hanya ingin program berjalan, kami ingin menjalankannya seperti yang kami harapkan. Jika Anda dapat membuat kesalahan ketik dan mengubah cara program berjalan, itu harus cukup dekat dengan perilaku yang diharapkan asli, atau programmer dengan rasa frustrasi.

Ada beberapa prioritas untuk hal-hal seperti itu dengan menggunakan bahasa alami daripada bahasa formal, tapi bukan itu yang saya sebut bidang besar ketika Anda membandingkannya dengan penggunaan bahasa formal. Jika Anda tertarik dengan bahasa pemrograman seperti itu, komunitas pengolah bahasa alami adalah tempat yang saya cari.

Bidang lain yang bisa Anda lihat adalah genetika. Ada beberapa urutan genetik yang tidak valid. Banyak dari mereka yang tidak terlalu efektif dalam reproduksi, tetapi sangat sedikit yang tidak valid.

Cort Ammon - Pulihkan Monica
sumber
1
Genetika sepertinya bukan contoh yang baik. Dalam hal valid atau tidak valid, apakah Anda hanya berbicara tentang replikasi? Karena tentu saja setiap string akan menjadi program yang valid untuk bahasa di mana satu-satunya instruksi yang mungkin replicate this string. Ini sebenarnya bukan bahasa pemrograman yang bermakna, karena tidak ada di dekat Turing Lengkap.
telp
2
@tel: Cort mungkin berbicara tentang sintesis protein melalui mRNA, daripada replikasi. Cukup banyak urutan genetik yang dapat ditranskripsikan dan kemudian dimasukkan ke dalam mesin sintesis protein: apakah protein yang keluar cukup stabil sehingga belum terdegradasi pada saat itu dibuat, dan jika demikian apakah itu melakukan sesuatu yang bermanfaat untuk organisme, adalah masalah lain ...
Steve Jessop
3
Kode genetik bukanlah kode untuk mereproduksi dirinya sendiri. Ini (umumnya) kode untuk protein. Apakah protein itu bermanfaat seringkali merupakan pertanyaan yang berbeda. Tentu saja menjadi lebih menarik. Beberapa bit "kode" dalam urutan genetik berakhir menjadi lebih seperti instruksi di sepanjang baris "kode itu beberapa baris lebih jauh ke bawah - Anda kadang-kadang harus mengabaikannya." Ada segala macam "program" keren yang ditulis sel dan virus untuk saling bertarung.
Joel
TECO adalah contoh dunia nyata lainnya.
cjm
1
@ cjm wow. "API selesai bukan ketika Anda telah selesai menambahkan semuanya, tetapi ketika Anda telah selesai mengambil semuanya." Kecuali jika Anda adalah TECO, maka Anda sudah selesai ketika Anda kehabisan karakter untuk menetapkan makna.
Cort Ammon - Reinstate Monica
16

Gagasan mesin Turing universal hanya menggunakan "bahasa pemrograman" seperti itu: pengkodean mesin Turing sebagai bilangan alami, yang diwakili misalnya dalam biner, sehingga setiap bilangan alami menunjukkan mesin Turing, yaitu program. Dalam bahasa ini, setiap string nol dan satu adalah program.

nn

Saya yakin ada juga bahasa pemrograman esoterik di mana setiap string adalah program; Namun, jika Anda hanya meminta daftar itu, saya pikir pertanyaan Anda di luar topik di sini.

David Richerby
sumber
13

Memperluas bahasa pemrograman sehingga setiap ungkapan masuk akal selalu mungkin, tetapi tidak menarik. Misalnya, Anda bisa menetapkan arti "tidak melakukan apa-apa" pada ungkapan apa pun yang ditolak oleh bahasa asli.

Merancang bahasa pemrograman di mana setiap ekspresi masuk akal dengan cara "Anda dapat menjalankannya" tidak terlalu berguna. Bahasa pemrograman yang baik bukan hanya di mana monyet bisa mengetik pada keyboard dan menulis program yang valid, tetapi bahasa di mana seorang programmer dapat dengan mudah menulis program yang ingin mereka tulis. Menulis program yang valid bukanlah bagian yang sulit dari pemrograman: bagian yang sulit adalah menulis program yang melakukan apa yang diharapkan darinya. Menolak program yang salah jelas sangat membantu dalam hal ini.

Cara lain untuk mengatasi hal ini adalah dengan sepenuhnya mendefinisikan semantik dari semua input yang mungkin, termasuk menentukan apa waktu kompilasi, waktu buka atau kesalahan run-time yang harus dihasilkan untuk setiap input jika ada. Yaitu, "batalkan program setelah mencetak Syntax error at line 42pada aliran kesalahan standar" adalah bagian dari semantik bahasa yang didefinisikan. Setiap ungkapan “masuk akal” karena memiliki makna yang jelas. Apakah itu makna yang bermanfaat? Mungkin - setelah semua, jika programnya jelas salah, menolak itu berguna.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
12

Lihat Jot , bahasa Turing-lengkap berdasarkan logika kombinatori, di mana setiap urutan 0s dan 1s (termasuk urutan kosong) adalah program yang valid.

Petr Pudlák
sumber
2
Ini bukan jawaban ilmu komputer .
Raphael
2
@Abdulrhman Ini lurus ke depan untuk menentukan suatu bijih antara string biner dan bilangan alami. Jadi, Anda dapat menyandikan program apa pun sebagai angka alami jika Anda mau.
CodesInChaos
7
@Raphael Tolong jelaskan, atau sarankan peningkatan jawaban, saya akan dengan senang hati memperbaikinya jika Anda memberikan alasan untuk kritik Anda.
Petr Pudlák
+1, saya akan memberikan jawaban yang sama untuk bahasa pemrograman fiktif berdasarkan bilangan asli tetapi ini serupa. AFAIK tidak ada pemrograman (dalam penggunaan praktis) yang memiliki fitur ini, tetapi seseorang dapat membangun satu menggunakan hanya angka, katakanlah, di mana setiap kombinasi memiliki makna (bertindak sebagai operator dan juga operan) Ini adalah kuncinya
Nikos M.
8

Salah satu contoh yang bagus adalah spasi . Dalam bahasa yang tepat, semua kombinasi operator valid. Operatornya adalah ruang, tab, dan baris baru (khusus "\ n"). Semua karakter lain dianggap sebagai komentar .

Jawaban ini, dan memang pertanyaan Anda (serta seluruh halaman web ini) adalah contoh program spasi putih yang valid (meskipun mereka mungkin tidak melakukan sesuatu yang sangat menarik).

Slebetman
sumber
Saya baru saja memikirkan hal ini setelah memposting jawaban brainfuck saya (jawaban Anda lebih baik karena benar), tetapi saya bertanya-tanya - apakah program kosong masih berupa program? (yaitu jika ketiga karakter tersebut hilang dari seluruh aliran file). - Seperti, jika mobil saya kehilangan semua barang yang membuatnya jadi mobil, apakah masih berupa mobil?
BrainSlugs83
Ini bukan jawaban ilmu komputer . (Juga, "setiap string spasi putih"! = "Setiap string".)
Raphael
2
@Raphael: Tetapi setiap string yang mungkin (termasuk yang tidak mengandung spasi) adalah program spasi putih yang valid - perhatikan bahwa karakter apa pun yang bukan spasi hanyalah komentar dalam bahasa pemrograman spasi
slebetman
2
@slebetman Anda menafsirkan komentar tanda kurung saya terlalu harfiah. Saya sedang berbicara tentang token loop tidak berpasangan. Beberapa masalah serupa di whitespace adalah: Apakah kembali tanpa panggilan sebelumnya berhasil? (disandikan sebagai [LF][Tab][LF]) Apa yang terjadi jika Anda memunculkan tumpukan kosong? Apa yang terjadi jika Anda melompat ke label yang tidak ditentukan? Apa yang terjadi jika Anda mendefinisikan label duplikat?
CodesInChaos
7

Saya ingin membahas gagasan yang telah diberikan banyak poster, bahwa bahasa seperti itu akan "tidak berguna". Mungkin tidak ada gunanya bagi manusia untuk menulis, secara manual, dengan maksud menyelesaikan beberapa tugas tertentu. Namun, meskipun merupakan use-case mayoritas untuk bahasa pemrograman, itu tentu saja bukan satu-satunya use case. Beberapa penggunaan kasus muncul di mana bahasa seperti itu berguna, dan kita bisa melihat ke bidang-bidang tersebut untuk contoh-contoh bahasa tersebut.

Pertama kiasan Cort Amon untuk genetika adalah tempat di: transformasi program pertanyaan (menggantikan )untuk 5) dapat dilihat sebagai mutasi . Jenis manipulasi ini biasa terjadi dalam bidang perhitungan evolusi ; khususnya algoritma genetika melakukan transformasi pada string , sementara pemrograman genetika mengubah program . Dalam kedua kasus tersebut, kami biasanya ingin menetapkan makna untuk setiap kemungkinan, karena itu akan menghasilkan ruang pencarian paling kompak.

Algoritma genetika bergantung pada semacam fungsi evaluasi untuk string; jika kita menggunakan penerjemah bahasa pemrograman sebagai fungsi evaluasi kita, maka kita memiliki skenario di mana bahasa pemrograman yang memberi makna pada semua string yang mungkin berguna. Dalam pemrograman genetika, diasumsikan bahwa fungsi evaluasi kami adalah juru bahasa pemrograman, tetapi kami dapat memilih berbagai representasi untuk program kami; misalnya, banyak sistem beroperasi pada pohon sintaksis abstrak. Jika kita memilih string sebagai representasi kita, maka kita memulihkan skenario yang sama dengan algoritma genetika.

Situasi lain di mana kita mungkin ingin setiap string menjadi program yang valid adalah ketika menghitung program. Ini terkait dengan penambangan yang disebutkan oleh CodesInChaos, tetapi kami mungkin lebih suka beroperasi pada string daripada bilangan alami karena beberapa alasan:

  • Jika ada beberapa struktur dalam bahasa, mis. kita dapat menetapkan arti pada sub-string, ini mungkin hilang ketika menerjemahkan ke bilangan alami. Dalam hal ini kami mungkin lebih suka menggunakan string, untuk alasan tentang dan mengubah sub-string secara lokal, daripada mewakili seluruh program sebagai angka. Ini analog dengan bagaimana kita lebih suka menggunakan operasi bitwise pada int daripada ekspresi aritmatika, ketika masing-masing bit memiliki makna individual. Ini pada dasarnya adalah generalisasi dari skenario evolusi.
  • Kami mungkin ingin membuat program sesuai permintaan; misalnya, kita mungkin mulai menjalankan program yang sama sekali tidak ditentukan, dan hanya menghasilkan (mis. secara acak) instruksi individual (mis. karakter) ketika / jika penunjuk instruksi mencapainya. Ini umum dalam teori informasi algoritmik, di mana program tersebut adalah pita mesin Turing, dan tujuannya adalah untuk mengkarakterisasi perilaku program yang dihasilkan secara acak. Sebagai contoh, kita dapat merumuskan Solomonoff sebelum string arbitrer sebagai probabilitas bahwa mesin Turing universal dengan pita acak akan menghasilkan string itu.

Dalam hal bahasa contoh, banyak sistem perhitungan evolusioner didasarkan pada bahasa stack seperti keluarga Push . Ini cenderung memungkinkan aliran token yang sewenang-wenang (yang dapat kami wakili sebagai karakter individu). Terkadang (seperti contoh Brainfuck dari BrainSlugs83) ada batasan untuk menyeimbangkan tanda kurung; namun, kita dapat mengaitkannya dengan program-program pembatas-sendiri , di mana string seperti [mungkin bukan program yang valid , tetapi ini adalah awalan program yang valid . Jika kita membayangkan kompiler / interpreter membaca kode sumber dari stdin, maka itu tidak akan menolak string seperti [, itu hanya akan menunggu lebih banyak input sebelum melanjutkan.

Bahasa seperti Binary Combinatory Logic dan Binary Lambda Calculus muncul secara langsung karena teori informasi algoritmik, misalnya. dari http://tromp.github.io/cl/cl.html

Desain komputer universal minimalis ini dimotivasi oleh keinginan saya untuk menghasilkan definisi konkret tentang Kompleksitas Kolmogorov, yang mempelajari keacakan objek-objek individual.

Warbo
sumber
2

Bahasa pemrograman yang nyata adalah untuk menyampaikan makna kepada orang , bukan komputer. Karena banyak teks menyenangkan dengan huruf acak-acakan hampir mengambang di sekitar acara, orang dapat membaca omong kosong dan masuk akal darinya, bahkan tanpa memperhatikan mangling. Pikirkan kembali betapa sulitnya menemukan kesalahan ketik dan kesalahan serupa lainnya dalam teks.

Bahasa pemrograman seperti apa yang Anda minta akan membuat orang mengerti apa yang ingin mereka baca, bukan apa yang ditulis. Debugging dalam bahasa di mana ada seperangkat pernyataan hukum terbatas, di mana tidak ada banyak ambiguitas mungkin, sudah cukup sulit. Bahasa yang baik mengurangi kemungkinan interpretasi karena misalnya simbol atau kesalahan ketik yang dialihkan. Bahasa alami juga terkenal karena redundansi mereka, untuk alasan yang sama.

vonbrand
sumber
0

Dalam Bahasa Pemrograman Brainfuck , hampir setiap ekspresi biner yang mungkin dapat diartikan sebagai sebuah program. - Artinya, Anda bisa mengambil program yang benar-benar bagus, mengetikkan banyak sampah ke dalamnya, dan, itu masih dapat dikompilasi / ditafsirkan tanpa masalah.

( Sunting: Ternyata Anda harus mencocokkan kurung buka dan tutup, tetapi jika tidak, hal di atas benar.)

Ini mencapai ini melalui dua metode sederhana ini:

  1. Semua perintah yang dipahami adalah satu byte (Dalam BF mereka semua karakter ASCII tunggal misalnya *).

  2. Semua karakter yang tidak dimengerti, dibuang sebagai komentar.

Bahasa pemrograman Turing lengkap (artinya, ia bisa melakukan apa saja yang bisa dilakukan oleh bahasa lain).

*: Ternyata tidak semua perintah BF adalah byte ASCII tunggal - yaitu tanda kurung HARUS dicocokkan - jadi, bahasa itu tidak memenuhi kriteria pertama di sana. - Tapi bahasa apa pun yang memenuhi kedua kriteria akan memenuhi apa yang diminta OP.

BrainSlugs83
sumber
2
Tidak hanya ini tidak menjawab pertanyaan, itu bukan jawaban ilmu komputer .
Raphael
1
Anda bisa mendefinisikan ulang bahasa untuk menangani mereka dengan cara yang masuk akal. mis. dengan memasukkan tanda kurung pembuka yang cukup di awal program dan menutup tanda kurung di akhir program agar seimbang. Sangat mudah untuk menulis penerjemah yang menangani program seolah-olah tanda kurung itu ada tanpa benar-benar menulis ulang program. Tentu saja memulai program brainfuck dengan braket pembuka agak tidak berguna, karena akan mengabaikan semuanya hingga braket penutup yang cocok.
CodeInChaos
1
@Raphael pertanyaan OP adalah "Apakah ada bahasa pemrograman di mana setiap kemungkinan kombinasi simbol - yaitu, setiap ekspresi - masuk akal?" - jawaban saya adalah "ya, ini adalah contoh yang mendekati, dan inilah teori di baliknya." - Selain menetapkan aturan yang tepat untuk satu kelas bahasa yang akan memenuhi persyaratan OP, saya tidak yakin berapa banyak ruang untuk sains yang ada di sini. Bisakah Anda memberikan contoh atau tautan ke sumber daya apa yang sebenarnya ingin Anda lihat di sini? -- Terima kasih.
BrainSlugs83
2
David dan Gilles memberikan jawaban ilmu komputer. Mereka mengeksplorasi prinsip - prinsip dan tidak hanya mengatakan, "bahasa X melakukan itu (hampir)". Jika Anda membaca jawaban mereka, Anda akan belajar bahwa jawaban dari bentuk yang terakhir juga agak membosankan. Itu bukan salah Anda, tetapi OP - pertanyaannya (sebagai pertanyaan ilmu komputer) membosankan; ada rasa kompleksitas yang keliru.
Raphael
Seseorang dapat dengan mudah "memperbaiki" BF sehingga string apa pun akan diterima: Anda hanya berpura-pura bahwa ada cukup ]karakter di akhir sumber untuk cocok dengan semua yang tidak cocok [, dan cukup [di awal untuk mencocokkan semua yang tidak cocok ]. Semantik [dan ]dapat dengan mudah diubah untuk membuatnya setara dengan ini. (mis. jika tidak ada yang cocok ]maka [hentikan saja eksekusi jika byte pada data pointer nol. ]Hanya melompat ke awal program dalam situasi yang sama.) Bahasa yang dihasilkan akan Turing lengkap dan akan menerima string apa pun.
Nathaniel