Pertanyaan serupa ditutup pada SO.
Terkadang ketika kita sedang pemrograman, kita menemukan bahwa beberapa struktur kontrol tertentu akan sangat berguna bagi kita, tetapi tidak secara langsung tersedia dalam bahasa pemrograman kita.
Struktur kontrol alternatif apa yang menurut Anda merupakan cara yang berguna untuk mengatur komputasi?
Tujuannya di sini adalah untuk mendapatkan cara berpikir baru tentang penataan kode, dalam rangka meningkatkan chunking dan penalaran.
Anda dapat membuat sintaksis semantik / semantik yang tidak tersedia sekarang atau mengutip struktur kontrol yang kurang dikenal pada bahasa pemrograman yang ada.
Jawaban harus memberikan ide untuk bahasa pemrograman baru atau meningkatkan bahasa yang sebenarnya.
Anggap ini sebagai brainstorming, jadi posting sesuatu yang Anda anggap gila, tetapi bisa dilakukan dalam beberapa skenario.
Ini tentang pemrograman imperatif.
Jawaban:
Oke, ini pertanyaan yang menyenangkan.
Saya juga ingin memiliki jenderal
else
untuk sementara dan untuk loop, karena ketika kondisi tidak benar pada tes pertama :Ini menghindari komputasi ulang yang canggung dari kondisi atau menyimpannya dalam variabel.
sumber
while ... else
konstruk seperti yang dijelaskan Macneil ke PHP. Saya pikir itu ide yang bagus, karena "ini hasilnya / tidak ada hasil" adalah ungkapan yang cukup umum di aplikasi web.Mengapa tidak tumbuk beberapa jawaban menjadi satu?
Sintaksis konstruk kontrol aliran yang dapat diperluas dan disamaratakan dalam bahasa imperatif akan lebih bermanfaat dan menghibur. Sampai itu muncul, kira saya akan menggunakan Lisp atau sesuatu.
sumber
seventh { ... }
juga.Kontrol struktur sebagai fungsi.
Saya ingin
for
,if
,else
,while
, dll menjadi fungsi, bukan struktur khusus.Saya ingin
return
,try/except
dangoto
menjadi turunan dari kelanjutan.Ini tentu saja kurang berkaitan dengan struktur kontrol tertentu dan lebih berkaitan dengan bagaimana Anda melihat struktur kontrol secara umum, meta struktur kontrol.
sumber
for
,if
,else
, danwhile
sebagai fungsi membuat saya menyimpulkan bahwa parameter untuk fungsi-fungsi perlu malas dieksekusi untuk berperilaku sama dengan konstruksi aslinya. Memiliki kemampuan untuk melakukan eksekusi malas akan menyenangkan.return
, pengecualian, dll. Tapi sekarang programmer ahli memiliki alat tambahan yang kuat di kotak peralatannya jika diperlukan. Selain itu, bahasa IMHO tidak boleh "dibodohi". Bahasa harus memiliki kemampuan untuk mendukung peningkatan keahlian dan pertumbuhan pengetahuan CS.Artikel yang ditautkan pasti benar tentang Loop N + 1/2 Donald Knuth . Dinyatakan dalam C / C ++ / Java:
Ini berguna untuk membaca baris atau karakter dari file, menguji apakah Anda telah mencapai EOF, dan kemudian memprosesnya. Saya sudah terbiasa melihat polanya
for(;;)..if(..)break;
muncul sehingga itu idiomatis bagi saya. (Sebelum saya membaca artikel Knuth, dicetak ulang dalam buku Literate Programming , artikel ini dulunya adalah "wtf?".)Knuth menyarankan kata kunci
loop/while/repeat
:Di mana
S
danT
adalah pemegang tempat untuk serangkaian pernyataan nol atau lebih, danC
merupakan kondisi boolean. Jika tidak adaS
pernyataan maka itu akan menjadi loop sementara, dan jika tidak adaT
pernyataan maka itu akan menjadi loop lakukan.Konstruk ini sendiri dapat digeneralisasikan dengan mengizinkan nol atau lebih
while C
klausa, membuatnya sempurna untuk mengekspresikan loop tak terbatas dan kemudian beberapa kondisi langka yang membutuhkan dua pemeriksaan.Dalam artikel yang sama, Knuth menyarankan mekanisme pensinyalan yang akan menjadi versi lokal dari pengecualian melempar / menangkap (sebagai alternatif untuk menggunakan goto).
Untuk saya? Saya berharap Java mendukung pengoptimalan tail-call, sehingga saya dapat mengekspresikan struktur kontrol umum apa pun yang diperlukan.
Pembaruan: Saya lupa menyebutkan bahwa banyak programmer C / C ++ / Java menyiasati yang satu ini dengan menggunakan tugas yang disematkan dalam kondisi
while
:Menggunakan istilah-istilah dari konstruk Knuth, ini diizinkan kapan
S
danC
dapat digabungkan menjadi satu ekspresi. Beberapa orang benci melihat tugas yang disematkan di atas, sementara yang lain benci melihat yangbreak
difor (;;)
atas. Tetapi ketikaS
danC
tidak dapat digabungkan, seperti ketikaS
memiliki beberapa pernyataan, itufor (;;)
adalah satu-satunya alternatif tanpa kode berulang. Alternatif lain adalah dengan hanya menggandakanS
kode:loop/while/repeat
Alternatif Knuth tampaknya jauh lebih baik.sumber
repeat-until
loop Pascal .do while ... loop until
- baik prasyarat dan postkondisi adalah opsional, dan saya (samar-samar) ingat menggunakan keduanya dalam satu loop. Untuk kondisi menengah Anda, ada Adaexit when ...;
. Keuntungan utamaif ... break;
adalah Anda bisa menulisexit loopname when ...;
untuk keluar dari banyak (tetapi tidak harus semua) loop bersarang sekaligus. Mungkin sedikit lebih terlihat daripada jeda itu juga.Bahasa BCPL memiliki
valueof
ekspresi yang dapat digunakan untuk mengubah urutan pernyataan menjadi ekspresi tunggal:Di mana
some series of statements
bisa apa saja dan keseluruhannyavalueof
dievaluasiv
.Ini bisa berguna di Jawa ketika Anda perlu menghitung argumen untuk memanggil
this()
atausuper()
(yang mengharuskan tidak ada yang terjadi sebelum itu). Tentu saja, Anda bisa saja menulis metode terpisah, tetapi itu mungkin menyebalkan jika Anda perlu memasukkan banyak nilai lokal untuk konteks.Jika Anda dapat menggunakan
final
untuk variabel yang diperlukan, Anda sudah bisa melakukanvalueof
di Java menggunakan kelas dalam anonim:sumber
({ statement1; statement2; ...; result-expr; })
. Saya pernah melihat yang serupa di tempat lain, tetapi saya tidak ingat di mana. Mungkin semua disalin dari BCPL.melakukan hal yang sama seperti:
melakukan hal yang sama seperti:
sumber
unless
.Pada catatan yang berbeda, saya ingin melihat dukungan yang lebih baik untuk iterator dalam bahasa pemrograman. Khususnya, untuk saat Anda ingin turun dua koleksi berpasangan :
Beberapa bahasa dinamis mungkin sudah memiliki ini, atau dengan mudah mendukung melalui perpustakaan dan makro, tetapi saya pikir ini adalah semangat pertanyaan Anda.
Jika kedua set ukurannya tidak sama, maka bisa melempar pengecualian atau Anda bisa memiliki
else
setelah loop untuk memberi sinyal ada perbedaan ukuran.Secara alami, Anda bisa menggeneralisasi ini untuk turun tiga atau lebih daftar.
Pembaruan: Berguna juga untuk melakukan produk Cartesian antar iterables:
yang tidak lebih dari loop bersarang:
Saya sedikit khawatir bahwa antara dua notasi yang saya berikan di sini bahwa ada perbedaan O (n) dan O (n ^ 2) dalam jumlah pasangan, dengan hanya perubahan satu karakter.
sumber
for a, b, c in itertools.product(iter1, iter2, iter3):
memberi Anda produk Cartesian yang dievaluasi dengan malas. Apa itu? Anda ingin permutasi dan kombinasi dari iterator yang diberikan juga?itertools.permutations
,itertools.combinations
.Ada yang disebut "Dijkstra's Loop" (juga disebut "Dijkstra's Guarded Loop"). Itu didefinisikan dalam The Guarded Command Language (GCL) . Anda dapat menemukan beberapa informasi tentang sintaks dan semantik di artikel Wikipedia di atas di bagian 6 Pengulangan: lakukan .
Saat ini saya benar-benar tahu satu bahasa pemrograman yang mendukung struture kontrol ini secara langsung. Ini adalah Oberon-07 (PDF, 70 KB). Dan itu mendukung "Dijkstra's Loop" dalam bentuk pernyataan sementara. Lihatlah bagian 9.6. Sedangkan pernyataan dalam PDF di atas.
PS Ini adalah salinan jawaban SO saya .
sumber
Ekspresi gaya ikon dengan backtracking bawaan.
Python mendapatkan banyak manfaat generator Ikon - dan melakukan pekerjaan yang lebih baik secara umum, IMO. Dan pada prinsipnya backtracking itu hanya semacam lemparan pengecualian, tapi itu adalah kesederhanaan dari ekspresi yang setara dengan ...
untuk menangani kasus gagal seperti pembagian dengan nol.
Di mana Icon menjadi gila - tidak ada operator pembanding yang mengembalikan boolean. Perbandingan selalu berhasil atau memicu kemunduran, dan ada beberapa masalah semantik lain yang sekarang saya dengan susah payah mencoba untuk mengingat bahwa ... well, anggap saja itu mungkin lebih ditekan daripada terlupakan.
Saya selalu berpikir mereka harus memiliki
if
ekspresi tanpa bagian lain -if (condition, success-value)
semacam itu, mundur jika kondisinya kembali salah - dan jatuhkan perbandingan aneh.EDIT saya ingat - jelas banget. Perbandingan dengan dua argumen berhasil atau gagal - tidak menghitung nilai baru untuk kembali. Jadi ketika itu berhasil, apa yang itu kembali? Jawab - salah satu argumen. Tetapi jika Anda menulis
a > b
, yang merupakan argumen logis untuk kembali -a
ataub
? Dan bagaimana jika Anda menulisb < a
? Saya pikir itu selalu mengembalikan argumen yang benar, yang masuk akal seperti apa pun, tetapi biasanya masih tampak seperti argumen yang salah bagi saya.sumber
Ini hanya ide dan sintaksis umum:
Kondisi JUGA selalu dievaluasi. ELSE bekerja seperti biasa.
Ini berfungsi untuk kasus juga. Mungkin itu adalah cara yang baik untuk menghilangkan pernyataan break:
dapat dibaca sebagai:
Saya tidak tahu apakah ini berguna atau mudah dibaca tetapi ini adalah contoh.
sumber
Continuation Passing Style muncul di pikiran. Kemudian, tentu saja, Anda juga ingin memiliki Optimasi Panggilan Ekor .
sumber
goto return ...;
pernyataan, membuat maksud untuk tail-call eksplisit, jadi jika kompiler tidak dapat membuatnya iteratif itu adalah kesalahan.Percabangan utas yang mulus, memiliki sintaksis seperti fungsi, tetapi dijalankan dalam utas yang terpisah dan tidak dapat mengakses data yang pada awalnya tidak diteruskan.
Ketika cabang dipanggil, ia akan segera mengembalikan pegangan.
Pegangan dapat digunakan untuk memeriksa apakah tugas sudah selesai.
Jika hasilnya diminta sebelum eksekusi selesai, utas utama hanya akan menunggu.
Ini tidak akan mencakup skenario multithreading yang lebih maju, melainkan menyediakan cara awal yang mudah diakses untuk memanfaatkan beberapa core.
sumber
handle.finished()
tes, tetapispawn
dansync
hanya itu yang Anda butuhkan untuk 90% tugas pemrograman paralel.Blok FIRST dan THEN berjalan jika salah satu dari 3 kondisi dievaluasi menjadi true. Blok PERTAMA berjalan sebelum blok bersyarat dan LALU berjalan setelah blok bersyarat telah berjalan.
Bersyarat atau penulisan akhir ELSE berikut pernyataan PERTAMA dan KEMUDIAN independen dari blok ini.
Itu bisa dibaca sebagai:
Fungsi-fungsi ini hanyalah sebuah formulir untuk dibaca. Mereka tidak akan menciptakan ruang lingkup. Ini lebih seperti gosub / kembali dari Basic.
Kegunaan dan keterbacaan sebagai bahan diskusi.
sumber
Terkadang saya menemukan diri saya menulis sebuah loop yang perlu melakukan sesuatu yang berbeda selama iterasi pertama. Misalnya, menampilkan tag <th> alih-alih tag <td>.
Saya menangani situasi ini dengan bendera boolean. Sesuatu seperti ini:
Tampaknya konyol untuk memeriksa nilai
first
setiap iterasi ketika itu sebagian besar salah.Saya ingin memiliki opsi pengulangan untuk menentukan badan pengulangan yang berbeda pada iterasi pertama. Tidak perlu untuk variabel yang terpisah. Kode yang dikompilasi tidak perlu satu, juga, karena kode yang dihasilkan akan memiliki dua tubuh, satu untuk iterasi pertama dan satu untuk sisanya.
sumber
print(out, first "<th>" then "<td>")
if (!first) gimme-a-comma ();
sama saja. Namun saya keberatan, jika Anda membungkusnya dengan benar, Anda akan berakhir dengan hal-hal seperti metode gabungan string Python - namun seringkali Anda memerlukan pola dasar, loop yang mendasarinya tidak perlu ditulis ulang sesering itu.if (!first)
, tetapi pengoptimal mikro dapat mengajukan keberatan prediksi cabang.if (!first)
dan membiarkan kompilator pengoptimal memutuskan apakah loop body cukup kecil sehingga membuka gulungan dan menyingkirkanfirst
adalah kemenangan bersih.[disalin dari jawaban saya sendiri di stackoverflow]
ignoring
- Untuk mengabaikan pengecualian yang terjadi pada blok kode tertentu.Dengan konstruk kontrol pengabaian, Anda bisa menulisnya lebih ringkas dan lebih mudah dibaca sebagai:
[Scala menyediakan ini (dan banyak konstruksi kontrol penanganan Pengecualian lainnya) di perpustakaan standarnya, dalam paket util.control. ]
sumber
try..catch
blok kosong adalah satu hal; itu memaksa Anda untuk mengenali kesalahan dan sengaja mengabaikannya; sementara melempar potongan kode di bawah pengabaian global dapat menyebabkan masalah ketika pengecualian tersebut dilemparkan, serta menyebabkan kebiasaan pemrograman yang buruk.try
blok, kecuali daftar pengecualian yang ditangkap dan diabaikan di depan, bukan nanti. Itu bahkan bisa menjadi keuntungan keterbacaan - mis. Membiarkan pembaca tahu bahwa file yang hilang bukan kesalahan bahkan sebelum mereka membaca panggilan terbuka.Dari pada:
Lakukan dengan Python, atau sekarang dengan cara C # juga:
Scala memiliki banyak fitur baru.
Akhirnya, bahasa seperti Clojure dapat diperluas untuk menyediakan fungsionalitas tambahan.
sumber
Saya punya dua ide.
Seringkali saya menemukan bahwa saya mengulangi diri saya dalam
catch
balok-balok. Ini dapat sedikit dibantu melalui metode ekstraksi, tetapi itu dapat menyebabkan kekacauan yang tidak perlu jika metode ini sangat singkat atau tidak layak metode. Jadi, akan lebih baik untuk membuat sarangcatch
:Dalam pemrograman web saya juga sering menemukan diri saya sering melakukan sesuatu seperti ini (ini bukan contoh nyata jadi jangan menganalisis kasus fiksi):
Dalam Javascript (well, ECMAScript, dan mungkin orang lain yang saya tidak kenal), karena nilai apa pun dapat dievaluasi sebagai suatu kondisi,
||
dapat membantu.Saya sangat suka tampilannya, dan saya berharap lebih banyak bahasa, khususnya beberapa di sisi server, memiliki dukungan untuk itu. (PHP dapat mengevaluasi apa pun sebagai suatu kondisi, tetapi mengubah seluruh ekspresi kondisional menjadi boolean alih-alih mempertahankan nilai. Saya tidak tahu tentang Python atau Ruby.) Ini bisa menjadi berat setelah tiga kasus atau lebih, tetapi jika Anda memiliki lebih banyak dari tiga kasus, Anda mungkin juga memiliki desain perangkat lunak yang buruk.
sumber
x if c else y
sintaks ekspresi kondisional , alasan utama yang terjadi adalah karena banyak ekspresi menggunakan semantik ini untuk||
dan&&
secara halus buggy. IIRC kasus umum adalah nilai (seperti nol) yang valid untuk aplikasi yang sedang diperlakukanfalse
, sehingga dibuang sehingga digunakan fallback yang tidak valid sebagai gantinya. Namun - lihat jawaban saya, WRT, bahasa pemrograman Icon, yang dapat memiliki ekspresi sepertiget1() else get2() else default
.Switch umum telah mengatakan di atas:
Dalam Haskell:
sumber
Dalam C # saya ingin menggunakan yang sederhana
switch () { ... }
, tetapi dapat diperluas dengan ekspresi seperti:Dan seterusnya. Sama dengan angka atau jenis lain (yang mendukung
IComparable
,IConvertible
, ...)Ini mungkin membuat kode saya lebih singkat dan mudah dibaca.
sumber
Ini adalah pertanyaan yang menyenangkan, seperti yang dikatakan @Macneil.
Struktur kontrol favorit saya yang tidak biasa, yang saya (batuk sederhana) temukan, adalah eksekusi diferensial .
Ini memiliki kegunaan tertentu. Bagi saya, penggunaan yang luar biasa dalam pemrograman antarmuka pengguna, yang merupakan contoh dari masalah yang lebih umum dari mempertahankan data yang berlebihan dalam korespondensi. Di satu sisi, ada data aplikasi, dan di sisi lain, ada kontrol UI, yang harus disimpan dalam perjanjian. Ini kedengarannya seperti "mengikat" tetapi sebenarnya ada lebih banyak untuk itu.
Biasanya saya mengimplementasikannya dengan macro di C atau C ++. Dalam C # saya harus melakukannya dengan pernyataan yang mengembang. Itu menyakitkan, tetapi berhasil.
Setelah saya menerapkannya dalam hal Lisp macro, dan kemudian itu sangat bersih. Itu tidak memerlukan kehati-hatian dari pihak programmer. Saya bisa melakukan hal yang sama dalam bahasa terstruktur lain jika saya mengambil kesulitan untuk menulis parser lengkap dan kemudian menghasilkan semua hal yang benar. Itu proyek besar, dan saya belum melakukannya.
sumber
Struktur kontrol "tradisional" seperti
for
tentang mengendalikan orang yang bekerja, membuatnya tunduk pada ideologi korup dari elit kapitalis yang berkuasa. Itu sebabnya saya menggunakan struktur kontrol alternatif sepertiph0r
sebagai gantinya. Ini sepertifor
, tetapi lebih radikal: Anda tidak akan ketahuanph0r
mengenakan jas dan dasi, semburkan BS perusahaan.ph0r
tetap nyata, bung.Perangi kekuatan!
sumber
for
Loop paling sederhana-sumber