CoffeeScript und benannte Funktionen

10

An anderer Stelle ist ein Streit über die Terminologie einer benannten Funktion in CoffeeScript aufgetreten. Insbesondere hat sich jemand auf so etwas bezogen:

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

als benannte Funktion. Es wurde jedoch beanstandet, dass alles in CoffeeScript anonyme Funktionen sind und es keine benannten Funktionen gibt. Dies ist sicherlich richtig, CoffeeScript hat nur Funktionsausdrücke, die dann in einer Variablen gespeichert werden können. Aber ich denke nicht, dass es falsch ist, dies eine benannte Funktion zu nennen.

Aus meiner Sicht ist es eine benannte Funktion, weil es eine Funktion ist, der ein Name gegeben wurde. Es ist zwar keine benannte Funktion, so wie einige andere Sprachen benannte Funktionen haben, aber ich denke, es ist nah genug, dass es nicht unangemessen ist, es eine benannte Funktion zu nennen. Anders zu bestehen scheint nur ein Trottel zu sein.

Bin ich zum Mittagessen unterwegs und denke, dass das Beharren darauf, dass dies keine benannte Funktion ist, nur ein Trottel ist?

Winston Ewert
quelle
3
Ist diese ganze Frage nicht einfach nur ein Trottel? :-)
Mat
@Mat, ja, es scheint, ich kann es nicht vermeiden, über Nitpicking zu picken
Winston Ewert
Für den kleinen Pool von Programmierern, mit denen ich spreche (außerhalb von programmers.SE), sagen sie meistens, dass sie die benannten Funktionen von JavaScript zur Verwendung als "Klassen" (Konstruktoren) verwenden sollen, während anonyme Funktionen in Variablen für einfache alte Funktionen gespeichert werden.
Sal
1
"Nur Nitpicking" impliziert, dass die Antwort keine Rolle spielt und dass das Verstehen der Feinheiten einer Sprache kein würdiges Ziel ist.
user229044
Ich könnte es analog zu CoffeeScript betrachten: foo = ->ist nur eine einfache alte Funktion, während class Fooes sich um einen Konstruktor handelt. Ich sehe keinen Grund, warum foo = ->streng anonym genannt werden sollte.
Sal

Antworten:

20

CoffeeScript ist untrennbar mit JavaScript verbunden, und JavaScript unterscheidet zwischen den folgenden Ausdrücken:

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

In der Tat können Sie sogar schreiben:

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

Da dieser Unterschied in JavaScript von Bedeutung ist, ist es sinnvoll, dieselben Begriffe zu verwenden, wenn über CoffeeScript gesprochen wird. CoffeeScript unterstützt jedoch nichts wie die function foo ()Syntax, sodass wir sagen können, dass es keine "benannten" Funktionen hat.

In gewisser Weise ist der Name Teil der Funktionsdefinition in der function foo() { ... }, in dem anderen Fall erstellen Sie einfach eine Funktion und weisen sie einer Variablen zu. Dies spiegelt sich beispielsweise in der (nicht standardmäßigen) nameEigenschaft von Funktionen wider : Im ersten Fall erhalten foo.nameSie "foo"und im zweiten Fall erhalten Sie "".

Darüber hinaus unterscheiden sich diese in JavaScript auch darin, wie sie in den Bereich eingeführt werden: Die erste Version wird "gehisst" und ist in ihrem gesamten Bereich verfügbar, wobei die zweite Definition erst verfügbar ist, nachdem sie zugewiesen wurde.

Stellen Sie sich das einfach als JavaScript-spezifischen Jargon vor, der auf CoffeeScript übertragen wird, weil CoffeeScript so eng mit JS verwandt ist.

Tikhon Jelvis
quelle
1
Es ist wahr, dass es so etwas wie kein gibt function foo () {}. Sie können jedoch weiterhin eine benannte Funktion über das classKonstrukt initialisieren . Nur dass das kompilierte CoffeeScript (das resultierende JavaScript) viel ausführlicher ist, als die meisten eine benannte Funktion schreiben würden.
Sal
1
Außerdem gibt es eine technische Einschränkung: fooDer Körper Ihrer Funktion wird nicht angehoben.
Sal
1
jelivs: kein problem. Eine Korrektur aus dem letzten Kommentar, den ich zu Ihrer Antwort geschrieben habe: Ihr class fooFunktionskörper wird nicht an den Anfang der Datei gehoben.
Sal
Können wir wirklich sagen, dass die Terminologie auf CoffeeScript übertragen wird, da CoffeeScript nicht zwischen benannten und anonymen Funktionen unterscheidet? Die Unterscheidung von Javascript bedeutet in dieser Sprache einfach nichts.
Winston Ewert
@ WinstonEwert: Es ist wichtig, weil CoffeeScript so nah an JavaScript ist. Immerhin lautet die "goldene Regel": "Es ist nur JavaScript" .
Tikhon Jelvis
5

Es ist erwähnenswert, dass der Benutzer ausdrücklich angegeben hat, dass er eine "anonyme Funktion in eine benannte Funktion" umwandelt. Beide Begriffe haben eine starke, vorhandene Bedeutung und insbesondere unterschiedliche Funktionen in der JavaScript-Welt. Angesichts der vorhandenen Bedeutung taten sie so etwas nicht, und ich wies darauf hin.

CoffeeScript ist nicht so weit von JavaScript entfernt, dass Sie Begriffe, die beide gemeinsam haben, neu definieren sollten, um etwas anderes in einer Sprache zu bedeuten. CoffeeScript existiert nicht in einer Blase, die aus der JavaScript-Implementierung entfernt wurde, so wie Sie vielleicht argumentieren, dass C ++ von Assembly getrennt ist. Es ist wichtig , den Unterschied zwischen einer anonymen Funktion und einer benannten Funktion zu kennen , denn wenn Sie erwarten, dass sich Ihre "benannte" CoffeeScript-Funktion wie eine tatsächlich benannte Funktion verhält , werden Sie enttäuscht sein:

doStuff() # I cause an error

# ... later

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

Das entsprechende JavaScript würde mit einer echten benannten Funktion gut funktionieren:

doStuff(); // I work just fine!

// later....

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

Sie haben vielleicht Recht, dass ich nur "nitpicking" bin, aber was nun? Die subtilen Punkte in der Computerprogrammierung sind wichtig , und es ist wichtig, "technisch" korrekt zu sein. Es ist der Unterschied zwischen dem Schreiben von Code, der zufällig funktioniert, und dem tatsächlichen Verstehen, warum Ihr Code korrekt ist .

user229044
quelle
1
Wenn ich Ihr Beispiel zum Beispiel in Python ausprobieren würde, würde es immer noch nicht funktionieren. Ich bin mir also nicht sicher, ob das irgendetwas mit benannten oder anonymen Funktionen zu tun hat.
Winston Ewert
1
@ WinstonEwert Siehe mein Update. Python ist nicht wirklich etwas damit zu tun hat ...
user229044
@meager, mein Punkt ist, dass benannte Funktionen nicht unbedingt so funktionieren, obwohl sie in Javascript funktionieren. Daher führt das Heben selbst nicht dazu, dass die Funktionen von CoffeeScript als benannt betrachtet werden.
Winston Ewert
Ja, Sie müssen verstehen, dass alle Funktionen in CoffeeScript anonym sind (eigentlich würde ich lieber sagen, dass es sich um Funktionsausdrücke handelt). Das heißt aber nicht, dass wir manchmal nicht ein bisschen locker mit der Terminologie umgehen können. Aus diesem Grund denke ich, dass es nicht einfach ist, darauf zu bestehen, dass man sie niemals benannte Funktionen nennen kann.
Winston Ewert
3

Bin ich zum Mittagessen unterwegs und denke, dass das Beharren darauf, dass dies keine benannte Funktion ist, nur ein Trottel ist?

Nein . Denn in Bezug auf die Semantik, Ihre Funktionsreferenz wird in einer Variablen gespeichert, die Sie über eine Variable verweisen Namen .

Sal
quelle
3

Auf keinen Fall ein Trottel, imo. Ich benutze es ausgiebig für die Lesbarkeit:

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

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

Somit:

Echt benannte Funktion in "Coffeescript"

hello()

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

Sie entkommen reinem JS über den Backtick `

Beachten Sie, dass Sie Ihren Funktionskörper nicht einrücken können.

Prost

Zaid Daghestani
quelle
1

Verschwenden Sie keine Zeit damit, mit Pedanten zu streiten. Es ist niemals fruchtbar. Ja, jeder weiß, was Sie unter einer "benannten Funktion" in CoffeeScript verstehen, auch wenn diese technisch nicht korrekt ist. Nein, die Verwendung einer technisch inkorrekten, aber allgemein verständlichen Terminologie hat keinen Einfluss auf die Richtigkeit oder Unrichtigkeit der vorgeschlagenen Lösung. Ist es möglich, präziser zu sein, ohne sich umständlich zu formulieren? Wahrscheinlich nicht. Das bedeutet jedoch nicht, dass die Leute es abrutschen lassen. Stellen Sie sich diesen Kerl am anderen Ende des Gesprächs vor.

Der Grund, warum es technisch nicht korrekt ist, ist, dass Sie die Funktion nicht benannt haben, sondern einen Verweis auf die Funktion benannt haben. Erwägen:

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

Wie heißt die Funktion? foound barbeide verweisen auf dieselbe Funktion, haben jedoch unterschiedliche Namen. Entweder kann foooder barkann jederzeit neu zugewiesen werden, um auf eine andere Funktion oder sogar einen anderen Typ insgesamt zu verweisen, ohne die Funktion selbst zu ändern.

Karl Bielefeldt
quelle
0

So lese ich das:

Wenn Sie eine Funktion in einer JavaScript-Konsole mit deklarieren

var foo = function() { ... }

und dann fooohne Klammern aufrufen , wird zurückgegeben

function() { ... }

Wenn Sie es jedoch mit definieren

function foo() { ... }

und dann fooohne Klammern erneut aufrufen , wird zurückgegeben

function foo() { ... }

Im ersten Fall würde ich sagen, dass Sie eine Variable mit dem Namen "foo" deklarieren, in der eine anonyme Funktion gespeichert ist. Im zweiten Fall würde ich sagen, dass Sie tatsächlich eine benannte Funktion namens "foo" deklarieren.

Da CoffeeScript das erste Muster verwendet, stimme ich zu, dass es technisch korrekt ist, dass die Funktionen von CoffeeScript alle anonymen Funktionen sind, die in benannten Variablen gespeichert werden.

Dylan Ribb
quelle