Apa istilah untuk fungsi yang ketika dipanggil berulang kali, memiliki efek yang sama dengan memanggil satu kali?

96

(Dengan asumsi lingkungan single-threaded)

Fungsi yang memenuhi kriteria ini adalah:

bool MyClass::is_initialized = false;

void MyClass::lazy_initialize()
{
    if (!is_initialized)
    {
        initialize(); //Should not be called multiple times
        is_initialized = true;
    }
}

Intinya, saya bisa memanggil fungsi ini beberapa kali dan tidak khawatir tentang hal itu menginisialisasi MyClassbeberapa kali

Fungsi yang tidak memenuhi kriteria ini mungkin:

Foo* MyClass::ptr = NULL;

void initialize()
{
    ptr = new Foo();
}

Memanggil initialize()beberapa kali akan menyebabkan kebocoran memori

Motivasi

Akan menyenangkan untuk memiliki satu kata ringkas untuk menggambarkan perilaku ini sehingga fungsi yang diharapkan memenuhi kriteria ini dapat dikomentari dengan baik (terutama berguna saat menggambarkan fungsi antarmuka yang diharapkan akan ditimpa)

Rufus
sumber
67
Bagi pemilih dekat: sementara memang benar bahwa 99,999% (perkiraan kasar) dari semua pertanyaan "nama-hal-itu" di luar topik karena mereka tidak memiliki satu pun, benar, tidak ambigu, jawaban obyektif dan penamaan itu murni subyektif dan berdasarkan opini, yang satu ini memang memiliki jawaban objektif tunggal, benar, tidak ambigu, yang diberikan oleh OP sendiri.
Jörg W Mittag
30
Memanggilnya berkali-kali memang memiliki efek, karena mungkin ada kode lain yang mengubah 'var' di antaranya.
RemcoGerlich
7
Mengapa pertanyaan ini ditanyakan, jika OP tahu jawabannya pada saat bertanya ? Apakah ada alasan selain bangunan rep / poin / karma?
dotancohen
13
@dotancohen Tanya Jawab gaya T adalah gaya utama di StackExchange.
glglgl
17
@glglgl: Saya setuju, untuk pertanyaan dengan prestasi. Apa manfaatnya pertanyaan ini? Saya sangat khawatir bahwa kami akan mulai mendapatkan setiap pertanyaan CS 101 yang ditanyakan dan segera dijawab oleh OP, setiap istilah CS yang ditanyakan dan segera didefinisikan oleh OP, dan setiap pro dan kontra algoritma dasar yang dipertanyakan kemudian segera dijawab oleh OP ( belum tentu OP ini). Apakah itu situs yang kita inginkan dari rekayasa perangkat lunak.SE?
dotancohen

Jawaban:

244

Jenis fungsi / operasi ini disebut Idempotent

Idempotence (UK: / ˌɪdɛmˈpoʊtəns /, [1] US: / ˌaɪdəm - /) [2] adalah properti operasi tertentu dalam matematika dan ilmu komputer di mana mereka dapat diterapkan beberapa kali tanpa mengubah hasil di luar aplikasi awal.

Dalam matematika, ini berarti bahwa jika f adalah idempoten, f ( f (x)) = f (x), yang sama dengan mengatakan ff = f .

Dalam ilmu komputer, ini berarti bahwa jika f(x);idempoten, f(x);sama dengan f(x); f(x);.

Catatan: Makna ini tampaknya berbeda, tetapi di bawah semantik negara denotasional , kata "idempoten" sebenarnya memiliki makna yang sama persis dalam matematika dan ilmu komputer.

Rufus
sumber
Komentar bukan untuk diskusi panjang; percakapan ini telah dipindahkan ke obrolan .
maple_shaft
51

Istilah yang tepat untuk ini (seperti Woofas menyebutkan ) adalah idempotensi. Saya ingin menambahkan bahwa sementara Anda dapat memanggil func1metode Anda idempoten, Anda tidak dapat menyebutnya sebagai fungsi murni . Sifat-sifat fungsi murni adalah dua: ia harus idempoten dan tidak boleh memiliki efek samping, yang berarti, tidak ada mutasi variabel statis lokal, variabel non-lokal, argumen referensi yang dapat diubah atau aliran I / O.

Alasan saya menyebutkan ini adalah bahwa fungsi idempoten dengan efek samping juga tidak baik, karena secara teknis idempoten mengacu pada hasil pengembalian fungsi, dan bukan pada efek samping. Jadi secara teknis func2metode Anda idempoten, karena output tidak berubah sesuai dengan input.

Anda kemungkinan besar ingin menentukan bahwa Anda ingin fungsi murni. Contoh fungsi murni adalah sebagai berikut:

int func1(int var)
{
    return var + 1;
}

Lebih banyak bacaan dapat ditemukan di artikel Wikipedia "Fungsi murni" .

Neil
sumber
37
Saya pikir definisi idempotensi Anda terlalu sempit, atau dengan kata lain, Anda menggunakan definisi matematika idempotensi, bukan pemrograman. Sebagai contoh, metode PUTdan DELETEHTTP disebut idempoten tepat karena mengeksekusi efek sampingnya beberapa kali memiliki efek yang sama dengan mengeksekusi mereka hanya sekali. Anda mengatakan "berarti idempotensi f∘f = f", sedangkan dalam pemrograman, yang kami maksudkan "mengeksekusi fmemiliki efek yang sama dengan mengeksekusi f; f". Perhatikan bahwa Anda dapat dengan mudah mengubah makna kedua menjadi yang pertama dengan menambahkan parameter "dunia".
Jörg W Mittag
23
@Neil "Idempotensi hanyalah istilah matematika." Tidak bukan, itu juga digunakan dalam jaringan dan sistem komunikasi / distribusi server klien juga dan digambarkan sebagai JörgWMittag menggambarkannya. Ini adalah konsep yang berguna karena memungkinkan beberapa permintaan ke server / klien dengan operasi / pesan yang sama tanpa mengubah apa yang ingin dilakukan pesan asli. Ini berguna ketika Anda memiliki komunikasi yang tidak dapat diandalkan, dan Anda perlu mencoba kembali perintah karena pesan klien dijatuhkan atau server membalasnya.
opa
7
Anda harus masuk ke detail lebih lanjut tentang perbedaan antara murni dan idempoten. Func1 contoh Anda tidak idempoten karena func1(1) != func1(func1(1)).
Tezra
5
Kemurnian dan idempoten berbeda. Fungsi murni tidak harus idempoten dalam arti matematis (itu jelas idempoten dalam hal efek samping, karena tidak ada idempoten). Fungsi idempoten (dalam arti pemrograman) tidak harus murni, seperti dalam contoh yang diberikan oleh OP. Juga, seperti yang disebutkan dalam opa, idempotensi adalah properti yang bermanfaat dengan penggunaan yang sangat berbeda dari kemurnian. Definisi kemurnian Anda sebagai "idempoten dan tanpa efek samping" salah atau paling tidak menyesatkan, downvoting.
Frax
5
Dalam konteks pemrograman, tidak ada "efek samping", tetapi jika Anda memperluas definisi untuk memasukkan ini, maka fungsi idempoten dan fungsi murni akan berarti hal yang sama. Tidak, mereka tidak akan bermaksud hal yang sama sekali. Idempoten, tidak murni: void f(int var) { someGlobalVariable = var; }. Murni, tidak idempoten: int func1(int var) { return var + 1; }.
JLRishe
6

Istilahnya adalah Idempotensi . Perhatikan di bawah ini bahwa ada perbedaan yang jelas antara fungsi Idempoten (Dipanggil secara rekursif; Blok kode kedua dan definisi Matematika), dan idempoten fungsional (Dipanggil berulang kali dengan input yang sama secara berurutan; Blok kode pertama dan sering istilah yang dimaksud dalam Pemrograman).

Fungsi f dengan efek samping dikatakan idempoten di bawah komposisi sekuensial f; f jika, ketika dipanggil dua kali dengan daftar argumen yang sama, panggilan kedua tidak memiliki efek samping dan mengembalikan nilai yang sama dengan panggilan pertama [kutipan diperlukan] (dengan asumsi tidak ada prosedur lain yang dipanggil antara akhir panggilan pertama dan awal panggilan kedua).

Misalnya, pertimbangkan kode Python berikut:

x = 0

def setx(n):
    global x
    x = n

setx(5)
setx(5)

Di sini, setx idempoten karena panggilan kedua ke setx (dengan argumen yang sama) tidak mengubah status program yang terlihat: x sudah diatur ke 5 di panggilan pertama, dan sekali lagi diatur ke 5 di panggilan kedua, sehingga menjaga nilai yang sama. Perhatikan bahwa ini berbeda dari idempotensi di bawah komposisi fungsi f ∘ f. Misalnya, nilai absolut idempoten di bawah komposisi fungsi:

def abs(n):
    if n < 0:
        return -n
    else:
        return n

abs(-5) == abs(abs(-5)) == abs(5) == 5
Tezra
sumber
3

Dalam fisika saya pernah mendengar ini disebut sebagai proyeksi :

Proyeksi adalah suatu transformasi linear P dari ruang vektor untuk dirinya sendiri sehingga P 2 = P . Artinya, setiap kali P diterapkan dua kali ke nilai apa pun, itu memberikan hasil yang sama seperti jika diterapkan sekali (idempoten).

Secara grafis, ini masuk akal jika Anda melihat kartun proyeksi vektor :

masukkan deskripsi gambar di sini

Dalam gambar, sebuah 1 adalah proyeksi dari sebuah ke b , yang seperti aplikasi pertama dari fungsi Anda. Proyeksi berikutnya dari suatu 1 ke b memberikan hasil yang sama dengan 1 . Dengan kata lain, ketika Anda memanggil proyeksi berulang kali, itu memiliki efek yang sama dengan memanggilnya sekali.

Peringatan yang adil: Saya belum pernah mendengar ini digunakan di luar fisika, jadi kecuali Anda memiliki tipe-tipe di tim Anda, Anda mungkin membingungkan semua orang.

pengguna1717828
sumber
2
Ini memang contoh konkret yang bagus tentang bagaimana fungsi idempoten dapat divisualisasikan (secara matematis, dan terutama dalam bidang geometri vektor / aljabar linier). Sementara "idempotence" fungsi perangkat lunak adalah konsep yang sangat dekat, saya tidak berpikir pengembang / ilmuwan komputer sering menggunakan kata "proyeksi" dalam konteks ini ("fungsi proyeksi" dalam rekayasa perangkat lunak lebih suka merujuk pada fungsi yang mengambil objek dan mengembalikan objek baru yang berasal darinya, atau properti dari objek itu, misalnya)
Pac0
2
@ Pac0 Oh, baiklah. Saya bekerja di pinggiran antara sains dan pemrograman, dan tidak menyadari kata itu sudah kelebihan beban. Saya dapat memikirkan beberapa contoh yang dibuat-buat di tempat kerja di mana saya akan menggunakan terminologi ini, tapi saya akui bekerja dengan orang-orang yang bersedia menerima jargon sains setiap hari :-)
user1717828
3

Ini adalah algoritma Deterministic karena diberi input yang sama (dalam hal ini tidak ada input), ia akan selalu menghasilkan output yang sama.

Dalam ilmu komputer, algoritma deterministik adalah algoritma yang, diberi input tertentu, akan selalu menghasilkan output yang sama, dengan mesin yang mendasarinya selalu melewati urutan negara yang sama. Algoritme deterministik sejauh ini merupakan jenis algoritma yang paling banyak dipelajari dan dikenal, serta salah satu yang paling praktis, karena dapat dijalankan pada mesin nyata secara efisien.

Database SQL tertarik pada fungsi Deterministik .

Fungsi deterministik selalu memberikan jawaban yang sama ketika memiliki input yang sama. Sebagian besar fungsi SQL bawaan dalam SQLite bersifat deterministik. Sebagai contoh, fungsi abs (X) selalu mengembalikan jawaban yang sama selama input X-nya sama.

Suatu fungsi harus deterministik jika digunakan dalam menghitung indeks.

Misalnya, di SQLite, fungsi non-deterministik berikut tidak dapat digunakan dalam indeks: random(), changes(), last_insert_rowid()dan sqlite3_version().

Stephen Quan
sumber
6
Penanya func2adalah deterministik (tidak ada efek acak yang terlibat), tetapi sudah dinyatakan sebagai melanggar properti yang ia cari.
Draco18s
Bahwa hasil yang sama dihasilkan oleh pengulangan tidak sama dengan mengatakan hasil yang sama dihasilkan oleh bersarang atau rantai. Fungsi deterministik penting untuk hasil caching, lebih daripada untuk pengindeksan / hashing.
mckenzm
3

Selain jawaban lain, jika ada input spesifik ke functon yang memiliki properti ini, itu adalah titik tetap , titik invarian atau titik perbaikan fungsi. Misalnya, 1 untuk daya apa pun sama dengan 1, jadi (1ⁿ) ⁿ = 1ⁿ = 1.

Kasus khusus dari program yang menghasilkan dirinya sendiri sebagai output adalah quine .

Davislor
sumber
Quines adalah perangkat lunak karena set Cantor adalah matematika :-). Dan tentu saja quines tidak idempoten - mereka gagal ketika output sudah ada atau mereka "merusak" hasil sebelumnya dan menulis output baru, meskipun identik.
Carl Witthoft