Fungsi CoffeeScript dan Bernama

10

Di tempat lain , sebuah argumen telah muncul tentang terminologi fungsi bernama di CoffeeScript. Secara khusus seseorang menyebut sesuatu seperti ini:

 foo = ->
    console.log("bar")

sebagai fungsi bernama. Tapi sudah keberatan bahwa semua yang ada di CoffeeScript adalah fungsi anonim dan tidak ada fungsi bernama. Ini memang benar, CoffeeScript hanya memiliki ekspresi fungsi yang kemudian dapat disimpan dalam variabel. Tapi saya tidak berpikir itu berarti salah menyebut fungsi ini namanya.

Seperti yang saya lihat, itu adalah fungsi yang dinamai karena fungsi yang telah diberi nama. Benar, ini bukan fungsi bernama dengan cara yang sama seperti beberapa bahasa lain telah menamai fungsi, tapi saya pikir cukup dekat sehingga tidak pantas untuk menyebutnya fungsi bernama. Menegaskan sebaliknya hanya tampaknya menjadi rewel.

Apakah saya keluar untuk makan siang dengan berpikir bahwa bersikeras bahwa ini bukan fungsi yang disebut hanya pemalsuan?

Winston Ewert
sumber
3
Bukankah seluruh pertanyaan ini adil, baik, menarik? :-)
Mat
@Mat, ya sepertinya saya tidak bisa menghindari nitpicking tentang nitpicking
Winston Ewert
Untuk kumpulan kecil programmer yang saya ajak bicara (di luar programmer.SE itu), mereka kebanyakan mengatakan untuk menggunakan fungsi bernama JavaScript untuk digunakan sebagai "kelas" (konstruktor), sementara fungsi anonim disimpan dalam variabel untuk fungsi lama polos.
Sal
1
"Just nitpicking" menyiratkan jawabannya tidak masalah, dan memahami seluk-beluk suatu bahasa bukanlah tujuan yang layak.
user229044
Saya bisa melihatnya secara analog ke CoffeeScript: foo = ->hanya fungsi lama, sementara class Fookonstruktor. Saya tidak melihat alasan mengapa foo = ->harus disebut anonim.
Sal

Jawaban:

20

CoffeeScript pasti terikat dengan JavaScript, dan JavaScript membedakan antara ekspresi berikut:

function foo() { ... }
var foo = function () { ... }

Bahkan, Anda bahkan dapat menulis:

var foo = function bar () { ... }

Karena perbedaan ini penting dalam JavaScript, masuk akal untuk menggunakan istilah yang sama ketika berbicara tentang CoffeeScript. Namun, CoffeeScript tidak mendukung apa pun seperti function foo ()sintaks, jadi kita dapat mengatakan itu tidak memiliki fungsi "bernama".

Dalam arti tertentu, nama adalah bagian dari definisi fungsi di function foo() { ... }, di mana dalam kasus lain Anda hanya membuat fungsi dan menetapkannya ke variabel. Ini tercermin, misalnya, dalam nameproperti fungsi (tidak standar) : dalam kasus pertama, foo.nameakan memberi Anda "foo"dan yang kedua akan memberi Anda "".

Selain itu, dalam JavaScript, ini juga berbeda dalam hal bagaimana mereka diperkenalkan ke ruang lingkup: versi pertama "diangkat" dan tersedia di seluruh cakupannya di mana definisi kedua hanya tersedia setelah ditetapkan.

Pada dasarnya, anggap saja sebagai jargon khusus JavaScript, yang ditransfer ke CoffeeScript karena CoffeeScript sangat erat kaitannya dengan JS.

Tikhon Jelvis
sumber
1
Memang benar tidak ada yang namanya function foo () {}. Namun, Anda masih dapat menginisialisasi fungsi bernama melalui classkonstruk. Hanya saja CoffeeScript yang dikompilasi (JavaScript yang dihasilkan) jauh lebih bertele-tele daripada bagaimana kebanyakan orang akan menulis fungsi yang dinamai.
Sal
1
Dan juga, ada peringatan teknis: footubuh fungsi Anda tidak akan diangkat.
Sal
1
jelivs: tidak ada masalah. Satu koreksi dari komentar terakhir yang saya tulis pada jawaban Anda: class fooBadan fungsi Anda tidak akan diangkat ke bagian atas file.
Sal
Karena CoffeeScript tidak membuat perbedaan antara fungsi yang dinamai dan anonim, dapatkah kita benar-benar mengatakan bahwa terminologi ditransfer ke CoffeeScript? Perbedaan Javascript sama sekali tidak berarti apa-apa dalam bahasa itu.
Winston Ewert
@ WinstonEwert: Itu penting karena CoffeeScript sangat dekat dengan JavaScript. Bagaimanapun, "aturan emas" adalah: "Ini hanya JavaScript" .
Tikhon Jelvis
5

Perlu dicatat bahwa pengguna secara eksplisit menyatakan bahwa mereka mengubah "fungsi anonim menjadi fungsi bernama", kedua istilah memiliki makna yang kuat dan sudah ada, serta fungsi yang sangat berbeda di dunia JavaScript. Mengingat makna yang ada, mereka tidak melakukan hal seperti itu, dan saya menunjukkan ini.

CoffeeScript tidak sejauh ini dihapus dari JavaScript sehingga Anda harus mendefinisikan kembali istilah yang mereka berdua bagi untuk berarti sesuatu yang lain dalam satu bahasa. CoffeeScript tidak ada di beberapa gelembung, dihapus dari implementasi JavaScript-nya seperti Anda mungkin berpendapat bahwa C ++ dipisahkan dari Assembly. Mengetahui perbedaan antara fungsi anonim dan fungsi bernama penting , karena jika Anda mengharapkan fungsi CoffeeScript "bernama" Anda berperilaku seperti fungsi bernama sebenarnya , Anda akan kecewa:

doStuff() # I cause an error

# ... later

doStuff = (x,y) ->
  alert("Were I actually a named function, this would work!")

JavaScript yang setara akan bekerja dengan baik, dengan fungsi bernama sebenarnya :

doStuff(); // I work just fine!

// later....

function doStuff() {
  alert("I'm a real named function!")
}

Anda mungkin benar bahwa saya hanya "nitpicking", tetapi jadi apa? Poin halus dalam hal pemrograman komputer , dan menjadi "secara teknis" benar adalah penting. Perbedaan antara menulis kode yang bekerja, dan benar-benar memahami mengapa kode Anda benar .

pengguna229044
sumber
1
Jika saya mencoba contoh Anda dengan Python, misalnya, itu masih tidak akan berhasil. Jadi saya tidak yakin ada hubungannya dengan fungsi anonim vs bernama.
Winston Ewert
1
@ WinstonEwert. Lihat pembaruan saya. Python benar-benar tidak ada hubungannya dengan itu ...
user229044
@ Meager, maksud saya adalah bahwa fungsi bernama tidak harus bertindak seperti itu, meskipun mereka lakukan dalam Javascript. Oleh karena itu, mengangkat sendiri tidak mendiskualifikasi fungsi CoffeeScript agar tidak dianggap bernama.
Winston Ewert
Ya, Anda harus memahami bahwa semua fungsi dalam CoffeeScript adalah anonim (sebenarnya, saya lebih suka mengatakan bahwa mereka semua adalah ekspresi fungsi). Tetapi itu tidak berarti bahwa kita kadang-kadang tidak bisa lepas dengan terminologi. Itu sebabnya saya pikir ini penting untuk menegaskan bahwa Anda tidak pernah bisa memanggil mereka fungsi bernama.
Winston Ewert
3

Apakah saya keluar untuk makan siang dengan berpikir bahwa bersikeras bahwa ini bukan fungsi yang disebut hanya pemalsuan?

Tidak. Bagaimanapun, dalam hal semantik, referensi fungsi Anda disimpan dalam variabel, yang dapat Anda rujuk melalui nama variabel .

Sal
sumber
3

Jelas bukan nitpick, imo. Saya menggunakannya secara luas untuk keterbacaan:

readfile()
dothis()
dothat()
thistoo()
writefile()

function readfile() {
    ...
}
...

Jadi:

Fungsi bernama sebenarnya dalam "naskah kopi"

hello()

`function hello() {`
console.log 'hello'
dothings()
`}`

Anda lolos dari JS murni melalui backtick `

Perhatikan bahwa Anda tidak dapat membuat indent pada badan fungsi Anda.

Bersulang

Zaid Daghestani
sumber
1

Jangan buang waktu berdebat dengan pedant. Tidak pernah berhasil. Ya, semua orang tahu apa yang Anda maksud dengan "fungsi bernama" di CoffeeScript, meskipun secara teknis salah. Tidak, menggunakan terminologi yang secara teknis keliru tetapi dipahami secara luas tidak ada kaitannya dengan kebenaran atau kesalahan dari solusi yang diusulkan. Apakah mungkin untuk lebih tepat tanpa mendapatkan kecanggungan dalam pengungkapan kata? Mungkin tidak. Namun, itu tidak berarti orang akan membiarkannya. Bayangkan saja orang ini di ujung percakapan.

Alasannya secara teknis salah adalah karena Anda belum menyebutkan fungsi, Anda telah menyebutkan referensi ke fungsi tersebut. Mempertimbangkan:

foo = bar = ->
  console.log "What's my name?"

Apa nama fungsinya? foodan barkeduanya merujuk fungsi yang sama, tetapi memiliki nama yang berbeda. Selain itu, baik fooatau bardapat ditugaskan kembali kapan saja untuk referensi fungsi yang berbeda, atau bahkan tipe yang berbeda sama sekali, tanpa mengubah fungsi itu sendiri.

Karl Bielefeldt
sumber
0

Jadi, cara saya membaca ini seperti ini:

Saat Anda mendeklarasikan fungsi dalam konsol JavaScript menggunakan

var foo = function() { ... }

dan kemudian memanggil footanpa tanda kurung, ia kembali

function() { ... }

Namun, jika Anda mendefinisikannya menggunakan

function foo() { ... }

dan kemudian memohon foolagi tanpa tanda kurung, ia kembali

function foo() { ... }

Dalam kasus pertama, saya akan mengatakan Anda mendeklarasikan variabel bernama "foo" menyimpan fungsi anonim di dalamnya. Dalam kasus kedua, saya akan mengatakan Anda sebenarnya mendeklarasikan fungsi bernama bernama "foo".

Karena CoffeeScript menggunakan pola pertama, saya setuju bahwa secara teknis benar bahwa fungsi CoffeeScript adalah semua fungsi anonim yang disimpan dalam variabel bernama.

Dylan Ribb
sumber