Fungsi hanya mengembalikan parameter yang tidak berubah, tidak berguna?

15

Saya baru saja menemukan fungsi ini di proyek tempat saya bekerja:

  -- Just returns the text unchanged.
  -- Note: <text> may be nil, function must return nil in that case!
  function Widget:wtr(text)
      return text
  end

Sayang sekali, coder tidak lagi bekerja di perusahaan. Mengapa seseorang membuat fungsi yang tidak melakukan apa-apa, tetapi mengembalikan parameter yang dipanggilnya?

Apakah ada kegunaan untuk fungsi seperti itu, tidak ditentukan untuk contoh ini, tetapi secara keseluruhan dalam hal apa pun?

Disebabkan oleh

function aFunction(parameter)
    return parameter
end

Berakhir di

aFunction(parameter) == parameter

Mengapa saya menulis sesuatu seperti

aFunction(parameter) == whatIWantToCheck

dari pada

parameter == whatIWantToCheck

?

Sempie
sumber
kemungkinan duplikat dari gaya Coding untuk panggilan fungsi berantai
gnat
13
@gnat Bagaimana di Bumi duplikat itu?
Kilian Foth
13
Hah? Fungsi ini mengembalikan parameternya - rantai melibatkan pengembalian this.
Kilian Foth
11
@gnat Pertanyaannya adalah mengapa seseorang akan pernah menulis fungsi yang tidak melakukan apa pun kecuali mengembalikan dirinya sendiri. Ya, Anda bisa mengembalikan objek atau nilai tertentu untuk memungkinkan metode chaining, tapi itu bukan pertanyaannya. Pertanyaannya adalah mengapa seseorang akan pernah menulis sesuatu seperti int getParam(int param) { //DO NOTHING return param; } Dari perspektif metode rantai itu adalah panggilan yang benar-benar berlebihan dan tidak perlu karena Anda dapat meninggalkan fungsi OP dari rantai metode dan itu tidak akan membuat perbedaan tunggal.
ZeroStatic
4
Ini mungkin offtopic dan tidak berlaku untuk lua, tetapi ada kasus penggunaan yang valid untuk ini di PHP - dalam versi yang lebih lama, new Foo()->method();bukan sintaks yang valid, dan konstruk like function with($what) { return $what; }; with(new Foo())->method();digunakan sebagai solusinya.
DCoder

Jawaban:

57

Pertanyaan Anda seperti menanyakan apa gunanya angka nol jika setiap kali Anda menambahkannya ke sesuatu, Anda mendapatkan nilai yang sama kembali. Fungsi identitas seperti nol untuk fungsi. Agak tidak berguna dengan sendirinya, tetapi kadang-kadang berguna sebagai bagian dari ekspresi menggunakan fungsi tingkat tinggi, di mana Anda dapat mengambil fungsi sebagai parameter atau mengembalikannya sebagai hasilnya. Itu sebabnya sebagian besar bahasa pemrograman fungsional memiliki idatau identitydi perpustakaan standar mereka.

Dengan kata lain, itu membuat fungsi default yang berguna. Sama seperti Anda mungkin ingin menetapkan offset = 0sebagai integer default, meskipun itu membuat offset tidak melakukan apa pun, mungkin berguna untuk dapat ditetapkan filterFunction = identitysebagai fungsi default, meskipun itu membuat filter tidak melakukan apa pun.

Karl Bielefeldt
sumber
Bukankah seharusnya fungsi filter mengembalikan nilai boolean? Dalam hal ini fungsi filter "nol" akan menjadi yang mengembalikan true.
Kirill Rakhman
1
@cypressious Fungsi peta, lalu.
sapi
6
Atau menempelkannya di bawah konsep desain: Pola objek
kosong
@cypressious, itu akan menjadi untuk predikat yang diteruskan sebagai argumen ke fungsi filtertingkat tinggi. filterFungsi orde pertama memiliki tipe [a] -> [a],
Karl Bielefeldt
Misalnya di C # saya sering menggunakan.OrderBy(x => x)
CodesInChaos
27

Tentu. Bayangkan API eksternal yang memungkinkan Anda mengambil hal-hal dari tempat yang benar-benar Anda butuhkan, tetapi Anda harus menentukan kriteria filter dan output formatters untuk setiap permintaan, bahkan jika Anda menginginkan semua hasil dan ingin mendapatkannya persis seperti yang disimpan.

Maka Anda harus menciptakan fungsi "terima segalanya" yang sepele dan "kembali tidak berubah" yang sepele untuk mendapatkan data. wtradalah pseudo-formatter yang sepele. Jika Anda sering menggunakan API itu, akan sangat berguna untuk memiliki fungsi pseudo-helper ini di sekitar daripada harus membuat fungsi anonim setiap kali Anda menanyakan sesuatu. (Anda mungkin mempertimbangkan untuk menyebutnya identitydaripada wtragar segera jelas itu tidak melakukan apa-apa.)

Kilian Foth
sumber
Saya belum benar-benar memahami artinya, tetapi itulah skenario yang sebenarnya. Saya mungkin mengerti setelah beberapa saat, mengerjakan proyek ini sambil tetap mengingat jawaban Anda, saya pikir. atm itu terlihat tidak berguna bagi saya, ... jika saya mendapatkan data mentah, mengapa saya ingin fungsi memberi saya data mentah lagi, ...
Sempie
3
@Sempie Sekali lagi, jika API membutuhkan fungsi pemformatan, satu-satunya cara untuk mendapatkan teks yang tidak diubah adalah jika fungsi tidak melakukan apa pun pada teks.
Doval
3
Dengan kata lain: Jika Anda memiliki fungsi yang memerlukan argumen filter / format untuk dilewati, dan Anda benar-benar tidak dapat menggunakan nullsebagai argumen, Anda menggunakan fungsi filter kosong yang memfilter dengan 'tidak ada' untuk membuat program berhenti mengeluh.
ZeroStatic
3
@Sempie Anda telah bekerja dengan SQL, bukan? Anda tahu bagaimana cara memasukkan atau tidak memasukkan WHEREklausa? Secara longgar itu adalah masalah gula sintaksis. Pada dasarnya tidak adanya WHEREklausa persis sama seperti jika Anda memiliki WHEREklausa yang berjalan terus dan memungkinkan semuanya. Fakta bahwa perancang SQL membiarkan Anda tidak menentukan WHEREklausa, alih-alih memaksa Anda meletakkan satu klausa, bahkan ketika klausa menerima semuanya, adalah gula sintaksis yang kurang lebih, dan mereka baru saja memberi Anda opsi itu untuk kenyamanan sederhana. ..
Panzercrisis
5
Mungkin perlu dicatat bahwa dalam banyak kasus lebih cepat dan lebih bersih untuk memiliki kode tanpa syarat memanggil metode virtual atau delegasi yang mungkin atau mungkin tidak melakukan sesuatu yang bermanfaat, daripada memiliki kode menentukan apakah panggilan diperlukan dan lewati jika tidak.
supercat
15

Bukankah itu hanya polimorfisme?

Dari pengalaman saya dengan Qt tr() dan wtr()metode seharusnya digunakan (di sana, di Qt ) dalam pelokalan Widgetteks.

Jadi, dengan kembali teks tidak berubah metode ini hanya mengatakan: Widget does no localization (translation of the text) by default. Override this function to enable your own logic.

GreenScape
sumber
1
tidak menyadari ini adalah masalah QT - ini jelas jawabannya.
Corley Brigman
8

Kasus yang sangat umum untuk ini adalah 'fungsionalitas yang ditambahkan nanti'. Jadi programmer berpikir bahwa mungkin ada beberapa perubahan pada fungsi itu nanti. Karena Anda mengaksesnya sebagai fungsi dan bukan sebagai parameter itu sendiri, Anda dapat dengan mudah mengubahnya secara global. Katakanlah Anda memiliki indeks dengan:

function getIndex(index)
    return index
end

dan karena indeks Anda mulai dari 0, ini tidak masalah. Anda kemudian mengubah komponen di tempat lain, komponen ini membutuhkan Anda untuk menerjemahkan indeks Anda mulai dari 1. Anda harus menambahkan ratusan indeks +1 di mana-mana dalam kode Anda. Tetapi dengan metode seperti ini, cukup katakan:

 function getIndex(index)
    return index+1
end

dan kamu baik-baik saja. Fungsi seperti ini dapat dengan cepat mengarah pada rekayasa berlebihan tetapi pada beberapa titik mereka banyak masuk akal!

reggaemuffin
sumber
2
Ya, meskipun perlu dicatat bahwa doctstring dari fungsi yang diposting oleh OP tidak menyarankan bahwa ini adalah tujuan dari fungsi dalam kasusnya.
Mark Amery
6

Fungsi rintisan seperti ini adalah umum dalam situasi jenis-warisan. Kelas dasar mungkin tidak berguna, tetapi kelas turunan mungkin melakukan berbagai hal dengan input. Mendeklarasikan fungsi rintisan di kelas dasar memungkinkan semua kelas turunan memiliki fungsi nama itu, dan kelas turunan individu untuk menimpanya dengan sesuatu yang lebih rumit dan berguna.

jackr
sumber
5

Satu skenario tambahan mirip dengan penggunaan properti python dan C #, tetapi dalam bahasa yang tidak memiliki fitur.

Secara umum, Anda dapat mendeklarasikan sesuatu hanya sebagai anggota kelas; katakanlah, 'namai' sebagai string. Ini berarti Anda mengaksesnya seperti ini:

someobject.name

Kemudian, Anda memutuskan bahwa nama tersebut benar-benar harus bergantung pada apa yang ada di objek. Jadi itu harus benar-benar berfungsi. Ups! Bahkan tanpa argumen, itu berarti semua kode yang mengaksesnya sekarang harus diubah

someobject.name()

Tetapi jika Anda memiliki banyak contoh panggilan ini, kemungkinan tidak ada yang salah dengan itu cukup rendah - di suatu tempat perubahan ini tidak akan dilakukan, program akan macet ketika Anda sampai ke titik itu, dll.

Properti di C # / Python memungkinkan Anda untuk menggantikan fungsi dalam untuk apa yang dulunya atribut, sementara masih memungkinkan untuk diakses seperti atribut yaitu tanpa perubahan. Anda bahkan tidak perlu merencanakan sebelumnya.

Jika bahasa Anda tidak memiliki itu, Anda harus merencanakan ke depan, tetapi Anda masih bisa mendukungnya seperti yang dilakukan orang sebelumnya dengan menjadikannya fungsi dari awal yang tidak melakukan apa-apa. Pada awalnya, itu tidak akan melakukan sesuatu yang menarik, dan sepertinya itu harus dihapus, dan banyak fungsi jenis ini tidak pernah berubah. Tetapi kemudian, jika Anda menyadari bahwa benar-benar setiap kali Anda menelepon Widget.wtrAnda perlu menghapus beberapa karakter khusus, itu bukan masalah besar - itu sudah berfungsi, Anda hanya menambahkan itu dan Anda selesai.

TL; DR Ini hanya bisa menjadi programmer yang bijaksana merencanakan ke depan untuk perubahan di masa depan.

Corley Brigman
sumber
3
Itu masuk akal jika metode ini bergantung pada hal lain, tetapi tidak. Ini bukan properti, pengambil / penyetel atau bidang. Ini adalah metode yang saat ini tidak melakukan apa pun. Satu-satunya cara dia merencanakan perubahan di masa depan adalah jika logika metode ini harus berubah.
Matthew Steeples
1
Tidak harus ... itu berarti saat ini, saya tidak memproses data ini, tetapi nanti, jika saya ingin memprosesnya, setiap pengguna dari data itu mendapatkan data yang diproses secara gratis. Contoh bodoh: Katakanlah Anda mencetak string ke layar, dan biasanya Anda lakukan print data. Kemudian, Anda menyadari bahwa semua string harus menjadi huruf besar - Anda harus mencari setiap cetakan dalam program Anda dan mengubahnya menjadi print data.upper(). Tetapi jika Anda memiliki def cdata(data): return datadan di mana-mana mengatakan print cdata(data), maka Anda hanya mengubah def cdata(data): return data.upper()dan itu satu-satunya perubahan.
Corley Brigman
Saya mengerti maksud Anda di sana. Itu lebih masuk akal
Matthew Steeples
2

Bukan tidak berguna, sebenarnya ini bisa sangat berguna, karena membuat kode Anda lebih seragam dan fleksibel.

Katakan, misalnya, bahwa Anda memiliki daftar orang dan dropdown untuk dipilih pengguna jika kami ingin melihat "semua" atau hanya mereka yang "pria" atau "wanita".

Anda dapat menangani "semua" sebagai kasus khusus, dalam hal ini Anda akan memerlukan tambahan jika dan untuk memeriksa kasus ini secara eksplisit, atau Anda dapat memiliki fungsi filter yang hanya mengembalikan parameternya (mis. Memungkinkan semuanya untuk dilewati), ditugaskan untuk digunakan untuk kasus "semua".

Hejazzman
sumber
4
Itu tidak sesuai dengan skenario. Maksud saya fungsi yang mengembalikan parameternya dan, dalam kasus apa pun, tidak melakukan hal lain.
Sempie
@Sempie: Itu yang dia katakan. Jika Anda memiliki Filterkelas atau antarmuka dengan MaleFilterdan FemaleFiltersubclass, dan kode Anda memerlukan beberapa filter, filter yang tidak melakukan apa pun (mengembalikan parameternya tidak berubah) adalah cara Anda menangani All. Fungsi tidak pernah melakukan apa pun, tetapi dapat diganti dengan yang tidak.
Magus
@Magus, tetapi dalam skenario Anda, fungsinya adalah semacam placeholder yang baik, akan diganti nanti, atau hanya ada karena fungsi lama menjadi usang tetapi program membutuhkan passthrough ini. Bagaimanapun, ini bukan serah terima. Fungsi tidak memberikan parameter tidak berubah ke fungsi lain, seperti yang mungkin dilakukan filter, tetapi mengembalikannya ke fungsi panggilan.
Sempie
@Sempie Tidak, ini bukan placeholer bukan itu digunakan sebagai passthrough sementara. Ini adalah gagasan pengkodean (dan matematika) yang berguna, fungsi "identitas". Dan, ya, itu masih serah terima, apakah mengembalikannya ke "fungsi lain" atau ke fungsi panggilan. Kuncinya adalah bahwa fungsi "identitas" dapat menjadi salah satu dari banyak fungsi yang mungkin dipanggil oleh fungsi panggilan, dan digunakan untuk menghindari jika dan casing khusus ketika fungsi yang disebut tidak perlu melakukan apa pun.
Hejazzman