CoffeeScript i nazwane funkcje

10

W innym miejscu pojawił się spór o terminologię nazwanej funkcji w CoffeeScript. W szczególności ktoś odniósł się do czegoś takiego:

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

jako nazwana funkcja. Jednak sprzeciwiano się temu, że wszystko w CoffeeScript jest funkcjami anonimowymi i nie ma żadnych nazwanych funkcji. Jest to z pewnością prawda, CoffeeScript ma tylko wyrażenia funkcyjne, które można następnie przechowywać w zmiennej. Ale nie sądzę, aby to oznaczało, że błędem jest nazywanie tej funkcji nazwanej.

Według mnie jest to funkcja nazwana, ponieważ jest to funkcja, której nadano nazwę. To prawda, że ​​nie jest to funkcja nazwana w taki sam sposób, jak niektóre inne języki nazwały funkcje, ale myślę, że jest wystarczająco blisko, aby nazwać ją funkcją nazwaną. Domaganie się czegoś innego wydaje się po prostu podstępne.

Czy jestem na lunchu, myśląc, że upieranie się, że nie jest to nazwana funkcja, to tylko nitpicking?

Winston Ewert
źródło
3
Czy to całe pytanie nie jest po prostu, podstępne? :-)
Mat
@ Mat, tak, wygląda na to, że nie mogę uniknąć nitpickowania w sprawie nitpickingu
Winston Ewert,
W przypadku małej puli programistów, z którymi rozmawiam (poza programmers.SE), najczęściej mówią, że używają nazwanych funkcji JavaScript jako „klas” (konstruktorów), podczas gdy anonimowe funkcje są przechowywane w zmiennych dla zwykłych starych funkcji.
Sal
1
„Po prostu nitpicking” oznacza, że ​​odpowiedź nie ma znaczenia, a zrozumienie subtelności języka nie jest godnym celem.
user229044
Mógłbym spojrzeć na to analogicznie jak na CoffeeScript: foo = ->jest to po prostu stara funkcja, podczas gdy class Foojest konstruktorem. Nie widzę powodu, dla którego foo = ->miałby być nazywany anonimowym.
Sal

Odpowiedzi:

20

CoffeeScript jest nieuchronnie powiązany z JavaScript, a JavaScript rozróżnia następujące wyrażenia:

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

W rzeczywistości możesz nawet napisać:

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

Ponieważ ta różnica ma znaczenie w JavaScript, sensowne jest używanie tych samych terminów przy mówieniu o CoffeeScript. Jednak CoffeeScript nie obsługuje niczego takiego jak function foo ()składnia, więc możemy powiedzieć, że nie ma funkcji „nazwanych”.

W pewnym sensie nazwa jest częścią definicji funkcji w function foo() { ... }, gdzie w innym przypadku po prostu tworzysz funkcję i przypisujesz ją do zmiennej. Odzwierciedla to na przykład (niestandardowa) namewłaściwość funkcji: w pierwszym przypadku foo.nameda ci, "foo"aw drugim da ci "".

Dodatkowo, w JavaScript, różnią się one również sposobem wprowadzenia do zakresu: pierwsza wersja jest „podnoszona” i dostępna w całym jej zakresie, gdzie druga definicja jest dostępna dopiero po przypisaniu.

Zasadniczo pomyśl o tym jak o żargonie specyficznym dla JavaScript, który jest przenoszony do CoffeeScript, ponieważ CoffeeScript jest tak blisko związany z JS.

Tikhon Jelvis
źródło
1
To prawda, że ​​nie ma czegoś takiego jak function foo () {}. Nadal jednak można zainicjować nazwaną funkcję za pomocą classkonstrukcji. Tyle tylko, że skompilowany CoffeeScript (wynikowy JavaScript) jest o wiele bardziej szczegółowy niż większość osób, które napisałyby nazwaną funkcję.
Sal
1
Jest też techniczne zastrzeżenie: foociało twojej funkcji nie zostanie podniesione.
Sal
1
jelivs: nie ma problemu. Jedna poprawka z ostatniego komentarza, który napisałem do twojej odpowiedzi: class foociało funkcji nie zostanie przeniesione na początek pliku.
Sal
Ponieważ CoffeeScript nie rozróżnia funkcji nazwanych od anonimowych, czy naprawdę możemy powiedzieć, że terminologia została przeniesiona do CoffeeScript? Rozróżnienie JavaScript po prostu nic nie znaczy w tym języku.
Winston Ewert
@WinstonEwert: To ważne, ponieważ CoffeeScript jest tak blisko JavaScript. W końcu „złotą zasadą” jest: „To tylko JavaScript” .
Tikhon Jelvis
5

Warto zauważyć, że użytkownik wyraźnie stwierdził, że przekształca „funkcję anonimową w funkcję nazwaną”, przy czym oba terminy mają silne, istniejące znaczenie i szczególnie różne funkcje w świecie JavaScript. Biorąc pod uwagę istniejące znaczenie, nie robili nic takiego i wskazałem na to.

CoffeeScript nie jest tak daleko od JavaScriptu, że powinieneś na nowo zdefiniować terminy, które oba udostępniają, aby oznaczać coś innego w jednym języku. CoffeeScript nie istnieje w jakiejś bańce, usunięty z implementacji JavaScript w sposób, w jaki można argumentować, że C ++ jest oddzielony od asemblera. Znajomość różnicy między funkcją anonimową a funkcją nazwaną jest ważna , ponieważ jeśli oczekujesz, że funkcja „nazwana” CoffeeScript będzie zachowywać się jak funkcja o nazwie rzeczywistej , będziesz rozczarowany:

doStuff() # I cause an error

# ... later

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

Odpowiednik JavaScript działałby dobrze, z prawdziwie nazwaną funkcją:

doStuff(); // I work just fine!

// later....

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

Może masz rację, że po prostu „robię dupki”, ale co z tego? Subtelne punkty w komputerze programowania sprawa , i jest „technicznie” poprawne jest ważne. Różnica między pisaniem kodu, który akurat działa, a faktycznym zrozumieniem, dlaczego kod jest poprawny .

użytkownik229044
źródło
1
Na przykład, jeśli wypróbowałem twój przykład w Pythonie, nadal nie działałby. Nie jestem więc pewien, czy ma to coś wspólnego z nazwanymi a anonimowymi funkcjami.
Winston Ewert
1
@WinstonEwert Zobacz moją aktualizację. Python naprawdę nie ma z tym nic wspólnego ...
user229044
@meager, chodzi mi o to, że nazwane funkcje niekoniecznie działają w ten sposób, chociaż działają w JavaScript. Dlatego samo podnoszenie nie dyskwalifikuje funkcji CoffeeScript do uznania za nazwane.
Winston Ewert
Tak, musisz zrozumieć, że wszystkie funkcje w CoffeeScript są anonimowe (w rzeczywistości wolałbym powiedzieć, że wszystkie są wyrażeniami funkcji). Ale to nie znaczy, że czasami nie możemy być trochę rozluźnieni z terminologią. Właśnie dlatego uważam, że jego podstępem jest naleganie, abyś nigdy nie mógł nazwać ich nazwanymi funkcjami.
Winston Ewert
3

Czy jestem na lunchu, myśląc, że upieranie się, że nie jest to nazwana funkcja, to tylko nitpicking?

Nie. W końcu, jeśli chodzi o semantykę, odwołanie do funkcji jest przechowywane w zmiennej, do której można się odwoływać poprzez nazwę zmiennej .

Sal
źródło
3

Zdecydowanie nie jest głupkiem, imo. Używam go szeroko dla czytelności:

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

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

A zatem:

Prawdziwie nazwana funkcja w „coffeescript”

hello()

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

Uciekasz przed czystym JS poprzez backstick `

Zauważ, że nie możesz wciskać się w ciało funkcji.

Twoje zdrowie

Zaid Daghestani
źródło
1

Nie trać czasu na kłótnie z pedantami. To nigdy nie jest owocne. Tak, wszyscy wiedzą, co rozumiesz przez „nazwaną funkcję” w CoffeeScript, nawet jeśli jest to technicznie niepoprawne. Nie, stosowanie technicznie niepoprawnej, ale szeroko rozumianej terminologii nie ma wpływu na poprawność lub nieprawidłowość proponowanego rozwiązania. Czy można być bardziej precyzyjnym bez niewygodnego frazowania? Prawdopodobnie nie. Nie oznacza to jednak, że ludzie pozwolą się zsuwać. Wyobraź sobie tego faceta po drugiej stronie rozmowy.

Jest to technicznie niepoprawne, ponieważ nie nazwałeś funkcji, nazwałeś jej odwołanie . Rozważać:

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

Jak nazywa się ta funkcja? fooi baroba odnoszą się do tej samej funkcji, ale mają różne nazwy. Ponadto albo można fooalbo barw dowolnym momencie zmienić przypisanie, aby odwoływać się do innej funkcji, a nawet zupełnie innego typu, bez zmiany samej funkcji.

Karl Bielefeldt
źródło
0

Sposób, w jaki to czytam, jest następujący:

Gdy deklarujesz funkcję w konsoli JavaScript za pomocą

var foo = function() { ... }

a następnie wywołuje foobez nawiasów, zwraca

function() { ... }

Jeśli jednak zdefiniujesz to za pomocą

function foo() { ... }

a następnie wywołuje fooponownie bez nawiasów, zwraca

function foo() { ... }

W pierwszym przypadku powiedziałbym, że deklarujesz zmienną o nazwie „foo” przechowującą w niej anonimową funkcję. W drugim przypadku powiedziałbym, że faktycznie deklarujesz nazwaną funkcję o nazwie „foo”.

Ponieważ CoffeeScript używa pierwszego wzorca, zgodzę się, że technicznie poprawne jest, że wszystkie funkcje CoffeeScript są anonimowymi funkcjami przechowywanymi w nazwanych zmiennych.

Dylan Ribb
źródło