Apakah ada alasan mengapa fungsi di sebagian besar (?) Bahasa pemrograman dirancang untuk mendukung sejumlah parameter input tetapi hanya satu nilai balik?
Dalam kebanyakan bahasa, dimungkinkan untuk "mengatasi" batasan itu, misalnya dengan menggunakan parameter-out, pointer kembali atau dengan mendefinisikan / mengembalikan struct / kelas. Tetapi tampaknya aneh bahwa bahasa pemrograman tidak dirancang untuk mendukung beberapa nilai pengembalian dengan cara yang lebih "alami".
Apakah ada penjelasan untuk ini?
def f(): return (1,2,3)
dan kemudian Anda dapat menggunakan tuple-membongkar untuk "split" tupel:a,b,c = f() #a=1,b=2,c=3
. Tidak perlu membuat array dan mengekstrak elemen secara manual, tidak perlu mendefinisikan kelas baru.[a, b] = f()
vs.[a, b, c] = f()
) dan diperoleh di dalamf
olehnargout
. Saya bukan penggemar Matlab tapi ini sebenarnya sangat berguna di kali.Jawaban:
Beberapa bahasa, seperti Python , mendukung banyak nilai pengembalian secara asli, sementara beberapa bahasa seperti C # mendukungnya melalui pustaka dasar mereka.
Tetapi secara umum, bahkan dalam bahasa yang mendukungnya, beberapa nilai pengembalian tidak sering digunakan karena mereka ceroboh:
Sangat mudah untuk keliru urutan nilai pengembalian
(Untuk alasan yang sama ini, banyak orang menghindari memiliki terlalu banyak parameter untuk suatu fungsi; beberapa bahkan menganggapnya sebagai fungsi seharusnya tidak boleh memiliki dua parameter dari jenis yang sama!)
Mereka lebih kuat-diketik, mereka menjaga nilai-nilai kembali dikelompokkan sebagai satu unit logis, dan mereka menjaga nama (properti) nilai-nilai kembali konsisten di semua penggunaan.
Satu tempat mereka berada cukup nyaman dalam bahasa (seperti Python) di mana beberapa nilai kembali dari satu fungsi dapat digunakan sebagai beberapa parameter masukan yang lain. Tapi, kasus penggunaan di mana ini adalah desain yang lebih baik daripada menggunakan kelas cukup ramping.
sumber
()
. Apakah itu satu hal atau nol hal? Secara pribadi, saya akan mengatakan satu hal. Saya dapat menetapkan denganx = ()
baik, sama seperti saya dapat menetapkanx = randomTuple()
. Dalam yang terakhir jika tuple yang dikembalikan kosong atau tidak, saya masih dapat menetapkan satu tuple yang dikembalikanx
.Karena fungsi adalah konstruk matematika yang melakukan perhitungan dan mengembalikan hasil. Memang, banyak yang "di bawah tudung" dari tidak sedikit bahasa pemrograman berfokus hanya pada satu input dan satu output, dengan beberapa input hanya pembungkus tipis di sekitar input - dan ketika output nilai tunggal tidak bekerja, menggunakan satu struktur kohesif (atau tuple, atau
Maybe
) menjadi output (meskipun nilai kembali "tunggal" terdiri dari banyak nilai).Ini tidak berubah karena programmer telah menemukan
out
parameter sebagai konstruksi yang canggung yang berguna hanya dalam skenario terbatas. Seperti halnya banyak hal lain, dukungan tidak ada karena kebutuhan / permintaan tidak ada.sumber
Dalam matematika, fungsi "terdefinisi dengan baik" adalah fungsi di mana hanya ada 1 output untuk input yang diberikan (sebagai catatan, Anda hanya dapat memiliki fungsi input tunggal, dan masih secara semantik mendapatkan beberapa input menggunakan currying ).
Untuk fungsi multi-nilai (mis. Akar kuadrat dari integer positif, misalnya), cukup untuk mengembalikan koleksi, atau urutan nilai.
Untuk jenis fungsi yang Anda bicarakan (mis. Fungsi yang mengembalikan banyak nilai, dari jenis yang berbeda ) Saya melihatnya sedikit berbeda dari yang Anda kira : Saya melihat kebutuhan / penggunaan params sebagai solusi untuk desain yang lebih baik atau struktur data yang lebih bermanfaat. Sebagai contoh, saya lebih suka jika
*.TryParse(...)
metode mengembalikanMaybe<T>
monad daripada menggunakan param. Pikirkan kode ini dalam F #:Dukungan Compiler / IDE / analisis sangat baik untuk konstruksi ini. Ini akan memecahkan sebagian besar "kebutuhan" untuk params. Sejujurnya, saya tidak bisa memikirkan metode lain di mana ini tidak akan menjadi solusi.
Untuk skenario lain - yang saya tidak ingat - cukup Tuple.
sumber
var (value, success) = ParseInt("foo");
yang akan menjadi tipe kompilasi-waktu diperiksa karena(int, bool) ParseInt(string s) { }
dideklarasikan. Saya tahu ini bisa dilakukan dengan obat generik, tapi tetap saja itu akan menjadi tambahan bahasa yang bagus.Selain apa yang telah dikatakan ketika Anda melihat paradigma yang digunakan dalam perakitan ketika fungsi mengembalikannya meninggalkan pointer ke objek yang kembali dalam register tertentu. Jika mereka menggunakan register variabel / multipel, fungsi panggilan tidak akan tahu ke mana harus mendapatkan nilai yang dikembalikan jika fungsi itu ada di pustaka. Sehingga akan membuat menghubungkan ke perpustakaan menjadi sulit dan alih-alih mengatur jumlah pointer yang dapat dikembalikan, mereka pergi dengan satu. Bahasa tingkat yang lebih tinggi tidak memiliki alasan yang sama.
sumber
Banyak kasus penggunaan di mana Anda akan menggunakan beberapa nilai pengembalian di masa lalu sama sekali tidak diperlukan lagi dengan fitur bahasa modern. Ingin mengembalikan kode kesalahan? Lempar pengecualian atau kembalikan
Either<T, Throwable>
. Ingin mengembalikan hasil opsional? KembalikanOption<T>
. Ingin mengembalikan salah satu dari beberapa jenis? KembalikanEither<T1, T2>
serikat pekerja atau yang ditandai.Dan bahkan dalam kasus di mana Anda benar - benar perlu mengembalikan beberapa nilai, bahasa modern biasanya mendukung tupel atau semacam struktur data (daftar, array, kamus) atau objek serta beberapa bentuk pengikatan ikatan atau pencocokan pola, yang membuat pengemasan beberapa nilai Anda menjadi nilai tunggal dan kemudian merusaknya lagi menjadi beberapa nilai sepele.
Berikut adalah beberapa contoh bahasa yang tidak mendukung pengembalian beberapa nilai. Saya tidak benar-benar melihat bagaimana menambahkan dukungan untuk beberapa nilai pengembalian akan membuatnya secara signifikan lebih ekspresif untuk mengimbangi biaya fitur bahasa baru.
Rubi
Python
Scala
Haskell
Perl6
sumber
sort
fungsi Matlab :sorted = sort(array)
hanya mengembalikan array yang diurutkan, sedangkan[sorted, indices] = sort(array)
mengembalikan keduanya. Satu - satunya cara saya bisa memikirkan dalam Python adalah dengan mengedarkan bendera kesort
sepanjang garissort(array, nout=2)
atausort(array, indices=True)
.[a, b, c] = func(some, thing)
) dan bertindak sesuai. Ini berguna, misalnya, jika menghitung argumen output pertama adalah murah tetapi menghitung yang kedua mahal. Saya tidak terbiasa dengan bahasa lain di mana setara dengan Matlabsnargout
tersedia run-time.sorted, _ = sort(array)
.sort
fungsinya dapat mengatakan bahwa itu tidak perlu menghitung indeks? Itu keren, saya tidak tahu itu.Alasan sebenarnya bahwa nilai pengembalian tunggal sangat populer adalah ungkapan yang digunakan dalam banyak bahasa. Dalam bahasa apa pun di mana Anda dapat memiliki ekspresi seperti
x + 1
Anda sudah berpikir dalam hal nilai pengembalian tunggal karena Anda mengevaluasi ekspresi di kepala Anda dengan memecahnya menjadi beberapa bagian dan memutuskan nilai masing-masing bagian. Anda melihatx
dan memutuskan bahwa nilainya adalah 3 (misalnya), dan Anda melihat 1 lalu Anda melihatnyax + 1
dan menyatukan semuanya untuk memutuskan bahwa nilai keseluruhan adalah 4. Setiap bagian sintaksis dari ekspresi memiliki satu nilai, bukan jumlah nilai lainnya; itu adalah semantik alami ekspresi yang diharapkan setiap orang. Bahkan ketika suatu fungsi mengembalikan sepasang nilai, itu tetap benar-benar mengembalikan satu nilai yang melakukan pekerjaan dua nilai, karena gagasan fungsi yang mengembalikan dua nilai yang entah bagaimana tidak terbungkus dalam satu koleksi terlalu aneh.Orang tidak ingin berurusan dengan semantik alternatif yang akan diperlukan untuk memiliki fungsi mengembalikan lebih dari satu nilai. Misalnya, dalam bahasa berbasis stack seperti Forth, Anda dapat memiliki sejumlah nilai pengembalian karena setiap fungsi cukup memodifikasi bagian atas tumpukan, membuka input dan mendorong output sesuka hati. Itu sebabnya Forth tidak memiliki jenis ekspresi yang dimiliki bahasa normal.
Perl adalah bahasa lain yang terkadang dapat bertindak seperti fungsi yang mengembalikan banyak nilai, meskipun biasanya hanya dianggap mengembalikan daftar. Cara daftar "interpolasi" di Perl memberi kita daftar seperti
(1, foo(), 3)
yang mungkin memiliki 3 elemen seperti kebanyakan orang yang tidak tahu Perl harapkan, tetapi bisa dengan mudah hanya memiliki 2 elemen, 4 elemen, atau jumlah elemen yang lebih besar tergantung padafoo()
. Daftar dalam Perl diratakan sehingga daftar sintaksis tidak selalu memiliki semantik daftar; itu bisa hanya sepotong daftar yang lebih besar.Cara lain untuk memiliki fungsi mengembalikan beberapa nilai adalah dengan memiliki semantik ekspresi alternatif di mana setiap ekspresi dapat memiliki beberapa nilai dan setiap nilai mewakili suatu kemungkinan. Ambillah
x + 1
lagi, tetapi kali ini bayangkan yangx
memiliki dua nilai {3, 4}, maka nilaix + 1
akan menjadi {4, 5}, dan nilai-nilaix + x
akan menjadi {6, 8}, atau mungkin {6, 7, 8} , tergantung pada apakah satu evaluasi diizinkan untuk menggunakan beberapa nilai untukx
. Bahasa seperti itu mungkin diimplementasikan menggunakan backtracking seperti Prolog menggunakan untuk memberikan beberapa jawaban untuk suatu query.Singkatnya, panggilan fungsi adalah unit sintaksis tunggal dan unit sintaksis tunggal memiliki nilai tunggal dalam semantik ekspresi yang kita semua tahu dan sukai. Semantik lainnya akan memaksa Anda melakukan cara aneh dalam melakukan sesuatu, seperti Perl, Prolog, atau Forth.
sumber
Seperti yang disarankan dalam jawaban ini , ini adalah masalah dukungan perangkat keras, meskipun tradisi dalam desain bahasa juga berperan.
Dari tiga bahasa pertama, Fortran, Lisp dan COBOL, yang pertama menggunakan nilai pengembalian tunggal sebagaimana dimodelkan pada matematika. Yang kedua mengembalikan sejumlah parameter sewenang-wenang dengan cara yang sama seperti menerimanya: sebagai sebuah daftar (bisa juga diperdebatkan bahwa parameter hanya lulus dan mengembalikan satu parameter: alamat daftar). Yang ketiga mengembalikan nol atau satu nilai.
Bahasa-bahasa pertama ini sangat memengaruhi desain bahasa yang mengikutinya, meskipun satu-satunya yang mengembalikan banyak nilai, Lisp, tidak pernah mengumpulkan banyak popularitas.
Ketika C datang, walaupun dipengaruhi oleh bahasa sebelumnya, C memberikan fokus yang besar pada penggunaan sumber daya perangkat keras yang efisien, menjaga hubungan erat antara apa yang dilakukan oleh bahasa C dan kode mesin yang mengimplementasikannya. Beberapa fitur tertua, seperti variabel "auto" vs "register", adalah hasil dari filosofi desain itu.
Harus juga ditunjukkan bahwa bahasa assembly secara luas populer hingga tahun 80-an, ketika akhirnya mulai dihapus dari pengembangan arus utama. Orang-orang yang menulis kompiler dan membuat bahasa terbiasa dengan perakitan, dan, sebagian besar, tetap menggunakan yang terbaik di sana.
Sebagian besar bahasa yang menyimpang dari norma ini tidak pernah menemukan banyak popularitas, dan, oleh karena itu, tidak pernah memainkan peran yang kuat mempengaruhi keputusan para perancang bahasa (yang, tentu saja, terinspirasi oleh apa yang mereka ketahui).
Jadi mari kita periksa bahasa assembly. Mari kita lihat pertama pada 6502 , mikroprosesor 1975 yang terkenal digunakan oleh mikrokomputer Apple II dan VIC-20. Itu sangat lemah dibandingkan dengan apa yang digunakan dalam mainframe dan minicomputer pada waktu itu, meskipun kuat dibandingkan dengan komputer pertama 20, 30 tahun sebelumnya, pada awal bahasa pemrograman.
Jika Anda melihat deskripsi teknis, ia memiliki 5 register plus beberapa flag satu-bit. Satu-satunya register "penuh" adalah Program Counter (PC) - yang mendaftar menunjuk ke instruksi selanjutnya yang akan dieksekusi. Register lain di mana akumulator (A), dua register "indeks" (X dan Y), dan stack pointer (SP).
Memanggil subrutin menempatkan PC dalam memori yang ditunjuk oleh SP, dan kemudian menurunkan SP. Kembali dari subrutin bekerja secara terbalik. Seseorang dapat mendorong dan menarik nilai-nilai lain pada stack, tetapi sulit untuk merujuk ke memori relatif terhadap SP, sehingga menulis kembali subrutin peserta sulit. Hal yang kita anggap remeh, menyebut subrutin kapan saja kita merasa, tidak begitu umum pada arsitektur ini. Seringkali, "tumpukan" yang terpisah akan dibuat sehingga parameter dan alamat kembali subrutin akan tetap terpisah.
Jika Anda melihat prosesor yang menginspirasi 6502, 6800 , itu memiliki register tambahan, Register Index (IX), selebar SP, yang bisa menerima nilai dari SP.
Pada mesin, memanggil subrutin masuk kembali terdiri dari mendorong parameter pada stack, mendorong PC, mengubah PC ke alamat baru, dan kemudian subrutin akan mendorong variabel lokalnya pada stack . Karena jumlah variabel dan parameter lokal diketahui, mengatasinya dapat dilakukan relatif terhadap tumpukan. Misalnya, fungsi yang menerima dua parameter dan memiliki dua variabel lokal akan terlihat seperti ini:
Itu bisa disebut berapa kali karena semua ruang sementara ada di stack.
The 8080 , digunakan pada TRS-80 dan sejumlah mikrokomputer berbasis CP / M dapat melakukan sesuatu yang mirip dengan 6800, dengan mendorong SP pada stack dan kemudian muncul pada register tidak langsungnya, HL.
Ini adalah cara yang sangat umum untuk mengimplementasikan berbagai hal, dan bahkan mendapat dukungan lebih banyak pada prosesor yang lebih modern, dengan Base Pointer yang membuat membuang semua variabel lokal sebelum kembali dengan mudah.
Masalahnya, adalah, bagaimana Anda mengembalikan sesuatu ? Register prosesor tidak terlalu banyak sejak awal, dan sering kali diperlukan beberapa dari mereka bahkan untuk mencari tahu bagian memori yang harus diatasi. Mengembalikan barang-barang di tumpukan akan menjadi rumit: Anda harus menghapus semuanya, menyimpan PC, mendorong parameter pengembalian (yang akan disimpan di mana saja?), Lalu mendorong PC lagi dan kembali.
Jadi yang biasanya dilakukan adalah memesan satu register untuk nilai pengembalian. Kode panggilan tahu nilai pengembalian akan berada di register tertentu, yang harus dipertahankan sampai dapat disimpan atau digunakan.
Mari kita lihat bahasa yang memungkinkan beberapa nilai pengembalian: Keempat. Apa yang dilakukan Forth adalah menjaga stack kembali terpisah (RP) dan tumpukan data (SP), sehingga semua fungsi harus lakukan adalah pop semua parameternya dan meninggalkan nilai kembali pada stack. Karena tumpukan kembali terpisah, itu tidak menghalangi.
Sebagai seseorang yang belajar bahasa assembly dan Forth dalam enam bulan pertama pengalaman dengan komputer, beberapa nilai pengembalian terlihat sepenuhnya normal bagi saya. Operator seperti Forth's
/mod
, yang mengembalikan divisi integer dan yang lainnya, tampak jelas. Di sisi lain, saya dapat dengan mudah melihat bagaimana seseorang yang pengalaman awalnya adalah C merasa konsep itu aneh: itu bertentangan dengan harapan mereka yang mendarah daging tentang apa "fungsi" itu.Sedangkan untuk matematika ... well, saya memprogram komputer jauh sebelum saya bisa berfungsi di kelas matematika. Ada adalah seluruh bagian dari CS dan bahasa pemrograman yang dipengaruhi oleh matematika, tapi, sekali lagi, ada seluruh bagian yang tidak.
Jadi kami memiliki pertemuan faktor-faktor di mana matematika mempengaruhi desain bahasa awal, di mana kendala perangkat keras menentukan apa yang mudah diimplementasikan, dan di mana bahasa populer mempengaruhi bagaimana perangkat keras berevolusi (mesin Lisp dan prosesor mesin Forth adalah roadkill dalam proses ini).
sumber
Bahasa fungsional yang saya tahu dapat mengembalikan banyak nilai dengan mudah melalui penggunaan tupel (dalam bahasa yang diketik secara dinamis, Anda bahkan dapat menggunakan daftar). Tuples juga didukung dalam bahasa lain:
Dalam contoh di atas,
f
adalah fungsi yang mengembalikan 2 int.Demikian pula, ML, Haskell, F #, dll., Juga dapat mengembalikan struktur data (pointer terlalu rendah untuk kebanyakan bahasa). Saya belum pernah mendengar bahasa GP modern dengan batasan seperti itu:
Akhirnya,
out
parameter dapat ditiru bahkan dalam bahasa fungsional olehIORef
. Ada beberapa alasan mengapa tidak ada dukungan asli untuk variabel keluar di sebagian besar bahasa:Semantik tidak jelas : Apakah fungsi berikut mencetak 0, atau 1? Saya tahu bahasa yang akan mencetak 0, dan yang akan mencetak 1. Ada manfaat untuk keduanya (baik dalam hal kinerja, serta mencocokkan model mental programmer):
Efek non-lokal : Seperti pada contoh di atas, Anda dapat menemukan bahwa Anda dapat memiliki rantai panjang dan fungsi terdalam memengaruhi kondisi global. Secara umum, itu membuat lebih sulit untuk berpikir tentang apa persyaratan fungsi, dan jika perubahan itu sah. Mengingat sebagian besar paradigma modern mencoba melokalisasi efek (enkapsulasi dalam OOP) atau menghilangkan efek samping (pemrograman fungsional), ia bertentangan dengan paradigma tersebut.
Menjadi berlebihan : Jika Anda memiliki tupel, Anda memiliki 99% fungsionalitas
out
parameter dan 100% penggunaan idiomatik. Jika Anda menambahkan pointer ke dalam campuran Anda menutupi sisa 1%.Saya mengalami kesulitan menyebutkan satu bahasa yang tidak dapat mengembalikan beberapa nilai dengan menggunakan tuple, kelas atau
out
parameter (dan dalam kebanyakan kasus 2 atau lebih dari metode tersebut diperbolehkan).sumber
Saya pikir itu karena ekspresi , seperti
(a + b[i]) * c
.Ekspresi terdiri dari nilai-nilai "tunggal". Fungsi yang mengembalikan nilai singular dapat langsung digunakan dalam ekspresi, menggantikan salah satu dari empat variabel yang ditunjukkan di atas. Fungsi multi-output setidaknya agak canggung dalam ekspresi.
Saya pribadi merasa bahwa ini adalah yang hal yang khusus tentang nilai kembali tunggal. Anda bisa mengatasinya dengan menambahkan sintaks untuk menentukan mana dari beberapa nilai kembali yang ingin Anda gunakan dalam ekspresi, tapi itu pasti lebih canggung daripada notasi matematika lama yang bagus, yang ringkas dan akrab bagi semua orang.
sumber
Itu sedikit menyulitkan sintaks, tetapi tidak ada alasan yang baik di tingkat implementasi untuk tidak mengizinkannya. Bertentangan dengan beberapa respons lain, mengembalikan beberapa nilai, jika tersedia, mengarah pada kode yang lebih jelas dan lebih efisien. Saya tidak dapat menghitung seberapa sering saya berharap dapat mengembalikan nilai X dan Y, atau boolean "sukses" dan nilai yang berguna.
sumber
[out]
parameter, tetapi hampir semua mengembalikanHRESULT
(kode kesalahan). Akan sangat praktis untuk mendapatkan pasangan di sana. Dalam bahasa yang memiliki dukungan yang baik untuk tupel, seperti Python, ini akan digunakan dalam banyak kode yang saya lihat.sort
berfungsi normal macam array:sorted_array = sort(array)
. Kadang-kadang saya juga perlu yang sesuai indeks:[sorted_array, indices] = sort(array)
. Kadang-kadang saya hanya menginginkan indeks:[~, indices]
= sort (array). The function
sort` sebenarnya dapat mengetahui berapa banyak argumen output yang diperlukan, jadi jika pekerjaan tambahan diperlukan untuk 2 output dibandingkan dengan 1, ia dapat menghitung output tersebut hanya jika diperlukan.Dalam sebagian besar bahasa di mana fungsi didukung, Anda dapat menggunakan panggilan fungsi di mana saja variabel yang dapat digunakan: -
Jika fungsi mengembalikan lebih dari satu nilai, ini tidak akan berfungsi. Bahasa yang diketik secara dinamis seperti python akan memungkinkan Anda untuk melakukan ini, tetapi, dalam kebanyakan kasus itu akan memunculkan kesalahan run time kecuali jika itu bisa menyelesaikan sesuatu yang masuk akal untuk dilakukan dengan tuple di tengah persamaan.
sumber
foo()[0]
Saya hanya ingin membangun berdasarkan jawaban Harvey. Saya awalnya menemukan pertanyaan ini di situs teknologi berita (arstechnica) dan menemukan penjelasan yang menakjubkan bahwa saya merasa benar-benar menjawab inti dari pertanyaan ini dan kurang dari semua jawaban lain (kecuali Harvey):
Asal tunggal kembali dari fungsi terletak pada kode mesin. Pada level kode mesin, suatu fungsi dapat mengembalikan nilai dalam register A (akumulator). Nilai pengembalian lainnya akan berada di tumpukan.
Bahasa yang mendukung dua nilai kembali akan mengkompilasinya sebagai kode mesin yang mengembalikan satu, dan menempatkan yang kedua di tumpukan. Dengan kata lain, nilai pengembalian kedua akan berakhir sebagai parameter keluar.
Itu seperti bertanya mengapa tugas adalah satu variabel pada suatu waktu. Anda dapat memiliki bahasa yang memungkinkan a, b = 1, 2 misalnya. Tapi itu akan berakhir pada level kode mesin menjadi a = 1 diikuti oleh b = 2.
Ada beberapa alasan dalam membuat konstruksi bahasa pemrograman memiliki kemiripan dengan apa yang sebenarnya akan terjadi ketika kode dikompilasi dan dijalankan.
sumber
Itu dimulai dengan matematika. FORTRAN, dinamai "Formula Terjemahan" adalah kompiler pertama. FORTRAN adalah dan berorientasi pada fisika / matematika / teknik.
COBOL, hampir setua itu, tidak memiliki nilai pengembalian eksplisit; Itu hampir tidak memiliki subrutin. Sejak itu sebagian besar inersia.
Go , misalnya, memiliki beberapa nilai pengembalian, dan hasilnya lebih bersih dan lebih tidak ambigu daripada menggunakan parameter "keluar". Setelah sedikit digunakan, sangat alami dan efisien. Saya merekomendasikan beberapa nilai pengembalian dipertimbangkan untuk semua bahasa baru. Mungkin untuk bahasa-bahasa lama juga.
sumber
Ini mungkin lebih berkaitan dengan warisan bagaimana panggilan fungsi dibuat dalam instruksi mesin prosesor dan fakta bahwa semua bahasa pemrograman berasal dari kode mesin: misalnya, C -> Assembly -> Machine.
Bagaimana Prosesor Melakukan Panggilan Fungsi
Program pertama ditulis dalam kode mesin dan kemudian perakitan. Prosesor mendukung pemanggilan fungsi dengan mendorong salinan semua register saat ini ke stack. Kembali dari fungsi akan memunculkan set register yang tersimpan dari tumpukan. Biasanya satu register dibiarkan tak tersentuh untuk memungkinkan fungsi kembali mengembalikan nilai.
Sekarang, mengapa prosesor dirancang dengan cara ini ... itu mungkin masalah keterbatasan sumber daya.
sumber