Maaf untuk judul waffly - jika saya bisa menghasilkan judul yang ringkas, saya tidak perlu mengajukan pertanyaan.
Misalkan saya memiliki tipe daftar yang tidak dapat diubah. Ini memiliki operasi Foo(x)
yang mengembalikan daftar abadi dengan argumen yang ditentukan sebagai elemen tambahan di akhir. Jadi untuk membangun daftar string dengan nilai "Hello", "immutable", "world" Anda bisa menulis:
var empty = new ImmutableList<string>();
var list1 = empty.Foo("Hello");
var list2 = list1.Foo("immutable");
var list3 = list2.Foo("word");
(Ini adalah kode C #, dan saya paling tertarik dengan saran C # jika Anda merasa bahasanya penting. Ini bukan pertanyaan bahasa yang mendasar, tetapi idiom bahasa mungkin penting.)
Yang penting adalah bahwa daftar yang ada tidak diubah oleh Foo
- jadi empty.Count
masih akan mengembalikan 0.
Cara lain (yang lebih idiomatis) untuk mencapai hasil akhir adalah:
var list = new ImmutableList<string>().Foo("Hello")
.Foo("immutable")
.Foo("word");
Pertanyaan saya adalah: apa nama terbaik untuk Foo?
EDIT 3 : Seperti yang saya ungkapkan kemudian, nama tipe mungkin sebenarnya tidak ImmutableList<T>
, yang membuat posisi jelas. Bayangkan sebaliknya bahwa itu TestSuite
dan itu tidak dapat diubah karena seluruh kerangka itu bagian dari itu tidak dapat diubah ...
(Akhir pengeditan 3)
Opsi yang saya buat sejauh ini:
Add
: umum di .NET, tetapi menyiratkan mutasi dari daftar asliCons
: Saya percaya ini adalah nama normal dalam bahasa fungsional, tetapi tidak berarti bagi mereka yang tidak berpengalaman dalam bahasa tersebutPlus
: favorit saya sejauh ini, itu tidak menyiratkan mutasi kepada saya . Rupanya ini juga digunakan di Haskell tetapi dengan harapan yang sedikit berbeda (seorang programmer Haskell mungkin berharap untuk menambahkan dua daftar bersama daripada menambahkan nilai tunggal ke daftar lainnya).With
: konsisten dengan beberapa konvensi tidak berubah lainnya, tetapi tidak memiliki "penambahan" yang sama persis untuk itu IMO.And
: tidak terlalu deskriptif.- Kelebihan operator untuk +: Saya benar-benar tidak suka ini; Saya biasanya berpikir operator hanya boleh diterapkan pada tipe level yang lebih rendah. Saya bersedia dibujuk!
Kriteria yang saya gunakan untuk memilih adalah:
- Memberikan kesan yang benar dari hasil pemanggilan metode (yaitu bahwa itu adalah daftar asli dengan elemen tambahan)
- Buat sejelas mungkin bahwa itu tidak mengubah daftar yang ada
- Kedengarannya masuk akal ketika dirantai bersama seperti pada contoh kedua di atas
Silakan tanyakan lebih detail jika saya tidak membuat diri saya cukup jelas ...
EDIT 1: Berikut alasan saya untuk memilih Plus
untuk Add
. Pertimbangkan dua baris kode ini:
list.Add(foo);
list.Plus(foo);
Dalam pandangan saya (dan ini adalah hal pribadi) yang terakhir jelas buggy - itu seperti menulis "x + 5;" sebagai pernyataan sendiri. Baris pertama sepertinya tidak apa-apa, sampai Anda ingat itu tidak berubah. Sebenarnya, cara operator plus itu sendiri tidak mengubah operan adalah alasan lain mengapa Plus
favorit saya. Tanpa sedikit kekuatiran operator overloading, masih memberikan konotasi yang sama, yang termasuk (bagi saya) tidak bermutasi operan (atau target metode dalam kasus ini).
EDIT 2: Alasan untuk tidak menyukai Tambahkan.
Berbagai jawaban secara efektif: "Pergilah dengan Add. Itulah yang DateTime
dilakukannya, dan String
memiliki Replace
metode dll yang tidak membuat kekekalan menjadi jelas." Saya setuju - ada yang diutamakan di sini. Namun, saya telah melihat banyak orang menelepon DateTime.Add
atau String.Replace
dan mengharapkan mutasi . Ada banyak pertanyaan newsgroup (dan mungkin SO yang saya gali) yang dijawab oleh "Anda mengabaikan nilai pengembalian String.Replace
; string tidak berubah, string baru akan dikembalikan."
Sekarang, saya harus mengungkapkan kehalusan pertanyaan - jenisnya mungkin sebenarnya bukan daftar yang tidak dapat diubah, tetapi jenis yang tidak bisa diubah. Secara khusus, saya sedang mengerjakan kerangka tolok ukur di mana Anda menambahkan tes ke suite, dan itu menciptakan suite baru. Mungkin jelas bahwa:
var list = new ImmutableList<string>();
list.Add("foo");
tidak akan mencapai apa-apa, tapi itu menjadi banyak murkier ketika Anda mengubahnya ke:
var suite = new TestSuite<string, int>();
suite.Add(x => x.Length);
Sepertinya itu harus baik-baik saja. Bagi saya, ini membuat kesalahan lebih jelas:
var suite = new TestSuite<string, int>();
suite.Plus(x => x.Length);
Itu hanya memohon untuk:
var suite = new TestSuite<string, int>().Plus(x => x.Length);
Idealnya, saya ingin pengguna saya tidak perlu diberi tahu bahwa test suite tidak dapat diubah. Saya ingin mereka jatuh ke dalam lubang kesuksesan. Ini mungkin tidak mungkin, tetapi saya ingin mencoba.
Saya minta maaf karena terlalu menyederhanakan pertanyaan asli dengan hanya berbicara tentang jenis daftar yang tidak dapat diubah. Tidak semua koleksi cukup deskriptif seperti ImmutableList<T>
:)