Mengapa tidak ada operator penugasan majemuk untuk operator logis (seperti ||, && dll)?

20

Menurut ECMA-262, bagian 11.13, berikut adalah daftar lengkap dari operator penugasan senyawa: *= /= %= += -= <<= >>= >>>= &= ^= |=.

Menurut bagian 11.11, var c = a || bakan memasukkan anilai ke dalam cjika ToBoolean(a)benar dan akan memasukkan bnilai ke dalam csebaliknya. Dengan demikian, logika OR sering digunakan sebagai operator gabungan, misalnya

function (options) {
    options = options || {};
}

Cukup sering, menyatu digunakan untuk menentukan nilai default untuk variabel, seperti yang ditunjukkan di atas: a = a || b.

Tampaknya operator penugasan senyawa ||=akan sangat berguna, yang memungkinkan untuk menulis kode di atas secara lebih pendek dan lebih bersih: a ||= b. Namun, tidak ada di sana (meskipun *=, +=dan operator penugasan majemuk lainnya).

Pertanyaannya adalah, mengapa?

penartur
sumber
2
Saya sangat bingung bahwa operator% = bahkan ada. Siapa yang memutuskan itu perlu? Beberapa operator tampak seperti keputusan desain bahasa yang buruk.
Jonathan Rich
2
@ JonathanRich: mengapa tidak memiliki% =? Jika Anda akan memiliki salah satu operator penugasan ini, cepat atau lambat beberapa pengembang (seperti penartur) akan bertanya-tanya mengapa operator "lebih setara" daripada yang lain.
kevin cline
4
@JonathanRich Crypto menggunakan modulus secara signifikan. Furthemore, ada ortogonalitas yang diinginkan dengan sisa aritmatika untuk operator penugasan aritmatika (jika salah satu mengharapkan +=, *=, -=, /=, kenapa tidak %=bekerja?).
4
@ JonathanRich: Operator sangat berguna ketika Anda memiliki sesuatu yang melingkar dan ingin menormalkannya, misalnya angle %= 360atau vertexIndex %= numberOfVertices(untuk daftar titik dari poligon tertutup).
Sebastian Negraszus

Jawaban:

12

Salah satu alasan yang mungkin adalah bahwa operator logis &&dan ||memiliki perilaku "korsleting". Operan tangan kanan &&dan ||tidak dievaluasi kecuali perlu. Mungkin karena alasan ini perancang bahasa memutuskan bahwa makna ekspresi seperti a ||= f()itu tidak jelas, sehingga operator seperti itu lebih baik ditinggalkan.

kevin cline
sumber
2
Iya nih. Misalnya, banyak orang percaya bahwa itu a ||= bharus ditafsirkan a = a || b, tetapi sebenarnya bisa a || a = b(seperti di Ruby ). Mereka mungkin berbeda jika setter memiliki efek samping. Memilih satu mungkin buruk bagi pengguna di kamp lain. Saya pribadi suka a || a = bcaranya (cara Ruby), tetapi saya tidak yakin apakah semua orang senang dengan itu.
Franklin Yu
8

Jawaban umum untuk semua pertanyaan tentang "mengapa fitur bahasa ini tidak diterapkan" adalah bahwa tim yang merancang bahasa memutuskan bahwa manfaatnya tidak melebihi biaya.

Biaya dapat mengambil banyak bentuk. Dibutuhkan waktu dan upaya untuk mengimplementasikan fitur bahasa, tetapi ada juga biaya intrinsik kompleksitas: apakah fitur membuat bahasa lebih kompleks atau ambigu, tidak sebanding dengan manfaat potensialnya?

||=Operator hipotetis melakukan sesuatu yang secara fundamental berbeda dari operator penugasan majemuk lainnya. Sementara operator lain bersifat matematika murni, operator ini berbeda: ia menggantikan satu nilai dengan yang lain (dalam konteks yang Anda jelaskan).

Mengingat ini ambiguitas (operator melakukan dua fungsi yang berbeda, tergantung pada konteksnya), tidak sulit untuk melihat mengapa itu tidak termasuk dalam bahasa. Meskipun Anda menyatakan perubahan itu

function (options) {
    options = options || {};
}

untuk

function (options) {
    options ||= {};
}

untuk melakukan null coalescing adalah fitur yang berharga, manfaatnya jauh lebih tidak jelas bagi saya. Jika substitusi nilai terjadi, tampaknya logis (dan lebih jelas) untuk memiliki kedua nilai di sisi kanan tanda sama dengan, untuk memberikan indikasi visual bahwa substitusi tersebut dapat terjadi.

C # mengambil jalur yang berbeda, dan menggunakan operator khusus untuk penggabungan nol.

Robert Harvey
sumber
1
Saat membaca kode, contoh pertama di sana berbunyi lebih alami - "opsi sama dengan opsi atau tidak sama sekali" - dibandingkan dengan yang kedua - "opsi atau sama dengan tidak ada". Saya pikir ini hanyalah alasan lain untuk tidak memasukkan operator "atau yang sederajat"
Andy Hunt
Pembukaan yang bagus untuk jawaban Anda. Dan saya pikir awal jawaban Anda termasuk dalam wiki untuk tag.
3
@AndyBursh Logika yang sama dapat diterapkan ke operator penugasan majemuk. "X sama dengan X kali 2" berbunyi lebih alami dibandingkan dengan "X kali sama dengan 2".
penartur
2
Perhatikan bahwa mengetik foo = foo || barmengharuskan Anda mengetik foodua kali. Ini rumit dan juga rentan terhadap pengetikan ulang kesalahan ketik.
Phrogz
1
Saya pikir Anda salah memahami arti "matematika", mungkin Anda pernah mendengar tentang aljabar boolean. Saya setuju bahwa memaksa non-boolean untuk digunakan ||=sebagai operator penggabungan nol tidak intuitif dan pada kenyataannya terlihat tumpul dalam bentuk kode. Di mana itu menjadi berguna adalah ketika Anda mencoba melakukan matematika boolean. function fulfill(inValue) { if(resolved || rejected) return false; /* Do stuff here */ return true; } resolved ||= fulfill(value)
joshperry
3

Anda benar itu ||= adalah konstruksi yang berguna. Itu ada di Perl.

Faktanya, Perl menyediakan semua ini :

**=    +=    *=    &=    <<=    &&=   -=    /=    
|=     >>=   ||=   .=    %=     ^=    //=   x=

Beberapa di antaranya sangat bagus (.= menambahkan sesuatu ke akhir string), yang lain kurang begitu ( &&=??? Saya kira variabel akan diatur ke sisi kanan jika keduanya dan variabel benar. Tapi mengapa Anda pernah melakukan ini ?)

Apa yang termasuk dalam bahasa sebenarnya adalah fitur dari filosofi desainnya.


sumber
3
stackoverflow.com/questions/12589467/… untuk apa &&=artinya / tidak.
Mat