Dalam bahasa apa nilai yang dikembalikan ditetapkan dengan menetapkan ke nama fungsi?

Jan 18 2021

Dalam pertanyaan Stack Overflow ini , kode asli membuat kesalahan dengan menggunakan nama fungsi sebagai variabel, dan menetapkan nilai kembalian ke dalamnya. Seorang pemberi komentar menyebutkan bahwa dia pernah menggunakan bahasa di mana ini adalah cara Anda mengembalikan nilai dari fungsi. Komentar itu berbunyi "Saya tahu saya pernah menggunakan bahasa di mana nilai kembalian dari suatu fungsi perlu ditetapkan ke nama fungsi. Itu sangat kuno dan usang sehingga saya bahkan tidak dapat mengingat bahasa itu."

Kedengarannya tidak asing bagi saya juga, tetapi saya juga tidak dapat mengingat bahasa apa itu.

Adakah yang memiliki ingatan yang lebih baik daripada kami dan dapat memberi tahu kami bahasa apa itu?

Jawaban

50 WillHartung Jan 18 2021 at 22:45

Pascal melakukan ini, saya tidak tahu orang lain. Tidak tahu apakah praktiknya berlanjut dengan bahasa Wirth lainnya.

50 OmarL Jan 18 2021 at 23:14

Bahasa dalam keluarga Visual Basic melakukan hal ini. Ini termasuk VBScript, VBA, Visual Basic, dan yang lebih lama. Saya yakin ini mewarisi "fitur" dari QBASIC. Sebagai contoh

Public Function AddTwo(something as Integer)
    AddTwo = something + 2
End Function
29 scruss Jan 18 2021 at 23:03

Fortran, pasti:

      PROGRAM TRIANG 
      WRITE(UNIT=*,FMT=*)'Enter lengths of three sides:' 
      READ(UNIT=*,FMT=*) SIDEA, SIDEB, SIDEC 
      WRITE(UNIT=*,FMT=*)'Area is ', AREA3(SIDEA,SIDEB,SIDEC) 
      END 

      FUNCTION AREA3(A, B, C) 
*Computes the area of a triangle from lengths of sides 
      S = (A + B + C)/2.0 
      AREA3 = SQRT(S * (S-A) * (S-B) * (S-C)) 
      END

(dari Panduan Programmer Profesional Clive G. Page untuk Fortran77 ).

Itu juga didefinisikan seperti itu dalam standar Fortran ANSI X 3.9 1966 Fortran 66 .

22 user3840170 Jan 18 2021 at 23:54

Bahasa paling awal yang dapat saya temukan adalah FORTRAN II dan ALGOL 58, keduanya diterbitkan pada tahun yang sama 1958; meskipun FORTRAN asli (1956) bisa dibilang juga bisa dimasukkan.

Untuk FORTRAN, halaman pertama dari bab manual yang mencakup fungsi-fungsi berisi contoh ini (hlm.27):

FUNCTION AVRG (ALIST, N)
DIMENSION ALIST (500)
SUM = ALIST (1)
DO 10 I=2, N
SUM = SUM + ALIST (I)
AVRG = SUM / FLOATF (N)
RETURN
END (2, 2, 2, 2, 2)

FORTRAN II juga menyertakan sintaks fungsi lain (p. 10), definisi fungsi baris tunggal, yang diwarisi dari pendahulunya:

FIRSTF(X) = A*X + B

Tidak sulit untuk melihat bagaimana sintaksis sebelumnya merupakan perpanjangan alami dari sintaksis yang terakhir, yang pada gilirannya berasal dari penggunaan matematis.

ALGOL 58 , mirip dengan FORTRAN, mendefinisikan kedua 'fungsi' baris tunggal:

Sebuah fungsi deklarasi menyatakan ekspresi yang diberikan untuk menjadi fungsi tertentu variabel nya. Dengan demikian, deklarasi memberikan (untuk fungsi sederhana tertentu) aturan komputasi untuk menetapkan nilai ke fungsi (lih. Fungsi ) setiap kali fungsi ini muncul dalam ekspresi.

Bentuk: Δ ~ I n (I, I, ~, I): = E di mana I adalah pengidentifikasi dan E adalah ekspresi yang, di antara konstituennya, mungkin berisi variabel sederhana yang dinamai oleh pengidentifikasi yang muncul di tanda kurung.

dan 'prosedur', setara dengan definisi fungsi saat ini (setidaknya dalam bahasa pemrograman imperatif / prosedural). Nilai kembali ditunjukkan sebagai berikut (hlm. 19):

Untuk setiap prosedur keluaran tunggal I (P i ) yang terdaftar dalam tajuk, nilai harus ditetapkan dalam prosedur dengan pernyataan penugasan "I: = E" di mana I adalah pengenal yang menamai prosedur itu.

Sintaks ini kemudian digunakan oleh beberapa dialek BASIC (dalam bentuk DEF FNdan yang lebih baru FUNCTION) dan turunan ALGOL Pascal: dalam kompiler Pascal Borland, menetapkan ke nama fungsi adalah satu-satunya sintaks yang didukung sebelum pengenalan Resultvariabel di Delphi 1.0.

Mungkin Pascal yang diingat oleh pemberi komentar tersebut; beberapa universitas masih mengajarkan pemrograman di dalamnya, dan biasanya tetap menggunakan variasi standar yang asli, daripada dialek modern yang diperluas seperti Object Pascal. (Ini sebenarnya bukan bagian dari pertanyaan, tetapi saya akan berasumsi kesalahpahaman penanya StackOverflow berasal dari itu juga.)

17 Raffzahn Jan 19 2021 at 00:28

TL; DR:

Saya akan mengatakan, kemungkinan besar itu adalah PASCAL yang Anda ingat, karena itu agak populer di awal 80-an, digunakan dalam kursus Universitas hingga tahun 80-an hingga 90-an dan masih memiliki beberapa persekutuan di sana setelahnya, terutama Delphi.


Beberapa Sejarah

Ide dasarnya adalah bahwa nama fungsi tidak hanya sudah dipesan, jadi tidak perlu muncul dengan sesuatu yang berbeda, dan menggunakannya adalah pernyataan yang jelas bahwa inilah hasilnya. Ini juga menyederhanakan desain kompilator, karena item data khusus dapat dialokasikan dalam konvensi pemanggilan.

Pada dasarnya ada dua garis warisan, FORTRAN dan ALGOL.

Untuk kedua keturunan mereka menyimpannya, seperti

  • beberapa varian BASIC dari FORTRAN dan
  • Pascal dan Modula dari ALGOL.

Yang lain membatalkannya, seperti tindak lanjut ALGOL

  • BCPL, yang memperkenalkan return()sintaks,

yang cukup umum saat ini karena C mengambilnya dari BCPL.

Ide bahasa seperti gen yang melompat di antara host. Misalnya ADA, dalam banyak hal seorang cucu ALGOL / PASCAL, juga beralih menggunakan returnelemen.

Granddaddy FORTRAN, selama bertahun-tahun, telah memvariasikan cara mengembalikan hasil fungsi.

  • Awalnya, hasil dari suatu fungsi ditetapkan ke pengenal fungsi tersebut
  • dengan FORTRAN 90 definisi eksplisit dari nama kembali di kepala fungsi diperkenalkan.

Meskipun ini pada dasarnya hanyalah gula sintaksis, ini menampilkan perubahan gaya. Alasan yang diterapkan adalah bahwa dengan konstruksi rekursi seperti Foo = Foo(x-1)akan terlihat aneh. Tapi saya rasa itu tergantung interpretasi.

Menariknya di sini juga adalah bahwa FORTRAN II tahun 1958 memang memperkenalkan RETURNpernyataan dalam upayanya untuk menambahkan pemrograman prosedural, tetapi penggunaannya hanya untuk mengembalikan eksekusi ke pemanggil, nilai yang dikembalikan harus ditetapkan terpisah.

12 alephzero Jan 18 2021 at 23:02

Fortran telah menggunakan sintaks ini, dari versi paling awal yang memiliki fungsi sama sekali hingga Fortran 2008 dan seterusnya.

Namun Fortran 2008 memiliki opsi (bahkan lebih membingungkan?) Di mana Anda dapat mendeklarasikan nama variabel berbeda yang digunakan untuk mengembalikan nilai fungsi! Sebagai contoh

function xyz(argument) result(answer)
...
answer = 42
...
end function xyz

bukan gaya lama

...
xyz = 42
...
9 another-dave Jan 19 2021 at 01:02

Algol 60 untuk satu.

Berikut kata-kata yang relevan dari Laporan Revisi pada Bahasa Algoritma Algol 60 .

5.4.4. Nilai penunjuk fungsi.

Untuk deklarasi prosedur untuk mendefinisikan nilai dari sebuah fungsi penunjuk harus, di dalam badan deklarasi prosedur, terjadi satu atau lebih pernyataan penugasan eksplisit dengan pengenal prosedur di bagian kiri; setidaknya satu dari ini harus dijalankan, dan tipe yang terkait dengan pengenal prosedur harus dideklarasikan melalui tampilan deklarator tipe sebagai simbol pertama dari deklarasi prosedur. Nilai terakhir yang ditetapkan digunakan untuk melanjutkan evaluasi ekspresi tempat penunjuk fungsi terjadi.

Setiap kejadian pengidentifikasi prosedur dalam tubuh prosedur selain di bagian kiri dalam pernyataan penugasan menunjukkan aktivasi prosedur.

Kalimat terakhir adalah signifikan - ini menunjukkan bahwa nama tipe procedure (function) tidak diperlakukan 'seperti' variabel di dalam procedure (function) body; sebaliknya, hanya tugas yang memiliki kasus khusus.

Di Algol 60, panggilan ke fungsi yang tidak membutuhkan argumen tidak diikuti dengan tanda kurung kosong: jadi, n := readbukan n := read().

Kalimat terakhir juga terkenal sebagai kalimat yang mendapat prosedur rekursif ke dalam bahasa. Tapi itu tidak terkait dengan jawaban ini.

6 StephenKitt Jan 18 2021 at 23:03

BASIC adalah bahasa lain dengan fungsi di mana beberapa dialek menggunakan penetapan ke nama fungsi untuk memberikan nilai yang dikembalikan. Dialek paling awal mirip dengan fungsi garis tunggal Fortran:

DEF FND(x) = x*x

Tetapi dialek yang lebih baru memungkinkan varian yang lebih kompleks, mirip dengan fungsi multi-garis Fortran :

DEF FNPeekWord& (A&)
  FNPeekWord& = PEEK(A&) + 256& * PEEK(A& + 1)
END DEF
5 LyndonWhite Jan 19 2021 at 20:38

MATLAB / Oktaf juga melakukan ini.

Itu dari 1984; jadi tidak setua yang lainnya.

Itu mungkin meniru Fortran, karena pada awalnya dianggap sebagai alat tingkat tinggi. Di atas perpustakaan Fortran seperti Linpack dan Eispack.

5 chasly-supportsMonica Jan 19 2021 at 21:29

Saya yakin SNOBOL4 melakukan ini. http://berstis.com/greenbook.pdf

Berikut ini adalah contoh definisi dan penggunaan fungsi untuk menghitung faktorial angka:

   DEFINE('FACT(N)') :(SKIPFCN)
 * Set value to 1
 FACT      FACT = 1
 * Return 1 if N<2
 * Return N*((N-1)!) with recursive call
   FACT = GT(N,1) FACT(N - 1) * N :(RETURN)
 SKIPFCN
   OUTPUT = '5 factorial is ' FACT(5)

http://berstis.com/s4ref/prim3e.htm

4 d3jones Jan 19 2021 at 07:12

Verilog (1995/2001) juga kembali dengan penugasan ke variabel implisit. SystemVerilog menambahkan pernyataan "return" tetapi tugas klasik masih tersedia.

1 arne Jan 21 2021 at 03:02

Haskell (dari 1990) melakukan ini juga:

doubleMe x = x + x  

mendefinisikan fungsi doubleMedari satu parameter xdan menetapkan badan fungsi x+xuntuk itu, lihat tutorial hebat Learn You A Haskell For Great Good

mathrick Jan 19 2021 at 13:08

Pascal adalah salah satu yang saya gunakan secara pribadi untuk melakukannya. Common Lisp kinda-sorta-but-not-really melakukannya, dalam nilai yang dikembalikan hampir selalu implisit (mis. Setiap pernyataan memiliki nilai, dan nilai terakhir dalam sebuah blok adalah nilai kembalian blok tersebut), jadi Anda sangat jarang melihat sebuah pernyataan kembali eksplisit, tetapi ketika Anda perlu mengembalikan nilai dan tidak dapat menggunakan cara implisit, cara untuk melakukannya adalah dengan menggunakan RETURN-FROM[*] pernyataan, seperti: (return-from function-name value).

[*] Ada juga RETURNpernyataan, tapi itu singkatan dari (return-from nil value), dan tidak akan berpengaruh membuat VALUEnilai fungsi yang dieksekusi. Ini adalah jebakan besar bagi pemula yang datang dari C dan keturunannya.