CoffeeScript e funzioni nominate


10

Altrove , è sorto un argomento sulla terminologia di una funzione denominata in CoffeeScript. In particolare qualcuno si riferiva a qualcosa del genere:

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

come una funzione con nome. Ma è stato obiettato che tutto in CoffeeScript sono funzioni anonime e non ci sono funzioni nominate. Questo è certamente vero, CoffeeScript ha solo espressioni di funzioni che possono essere archiviate in una variabile. Ma non penso che ciò significhi che è sbagliato chiamarla funzione nominata.

A mio avviso, è una funzione denominata perché è una funzione a cui è stato assegnato un nome. È vero, non è una funzione con nome nello stesso modo in cui altre lingue hanno funzioni con nome, ma penso che sia abbastanza vicino da non essere inappropriato chiamarla funzione con nome. Insistere altrimenti sembra proprio essere un pignolo.

Sono fuori a pranzo pensando che insistere sul fatto che questa non è una funzione nominata sia solo un pignolo?


3
Tutta questa domanda non è solo, beh, nitpicking? :-)
Mat

@Mat, sì, sembra che non riesca a evitare di parlare di nitpicking
Winston Ewert,

Per il piccolo gruppo di programmatori con cui parlo (al di fuori di programmers.SE, cioè), per lo più dicono di usare le funzioni nominate di JavaScript per usarle come "classi" (costruttori), mentre le funzioni anonime vengono archiviate in variabili per semplici funzioni precedenti.
Sal

1
"Il solo pignolo" implica che la risposta non ha importanza e che comprendere le sottigliezze di una lingua non è un obiettivo meritevole.
user229044

Potrei guardarlo in modo analogo a CoffeeScript: foo = ->è solo una vecchia funzione, mentre class Fooè un costruttore. Non vedo alcun motivo per cui foo = ->dovrebbe essere rigorosamente chiamato anonimo.
Sal

Risposte:


20

CoffeeScript è legato inesorabilmente a JavaScript e JavaScript differenzia tra le seguenti espressioni:

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

In effetti, puoi persino scrivere:

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

Poiché questa differenza è importante in JavaScript, ha senso usare gli stessi termini quando si parla di CoffeeScript. Tuttavia, CoffeeScript non supporta nulla di simile alla function foo ()sintassi, quindi possiamo dire che non ha funzioni "nominate".

In un certo senso, il nome fa parte della definizione della funzione in function foo() { ... }, dove nell'altro caso basta creare una funzione e assegnarla a una variabile. Ciò si riflette, ad esempio, nella nameproprietà (non standard) delle funzioni: nel primo caso, foo.nameti darà "foo"e nel secondo ti darà "".

Inoltre, in JavaScript, questi differiscono anche per quanto riguarda il modo in cui vengono introdotti nell'ambito: la prima versione è "issata" e disponibile in tutto il suo ambito in cui la seconda definizione è disponibile solo dopo che è stata assegnata.

Fondamentalmente, pensalo come un gergo specifico di JavaScript, che viene trasferito su CoffeeScript perché CoffeeScript è così strettamente correlato a JS.


1
È vero che non esiste una cosa come a function foo () {}. Tuttavia, è ancora possibile inizializzare una funzione denominata tramite il classcostrutto. Solo che il CoffeeScript compilato (il JavaScript risultante) è molto più dettagliato di come la maggior parte scriverebbe una funzione con nome.
Sal

1
Inoltre, c'è un avvertimento tecnico: il foocorpo della tua funzione non verrà sollevato.
Sal

1
jelivs: nessun problema. Una correzione dall'ultimo commento che ho scritto sulla tua risposta: il class foocorpo della funzione del tuo non verrà sollevato all'inizio del file.
Sal

Poiché CoffeeScript non distingue tra funzioni nominate e anonime, possiamo davvero dire che la terminologia viene trasferita su CoffeeScript? La distinzione di Javascript semplicemente non significa nulla in quella lingua.
Winston Ewert,

@WinstonEwert: è importante perché CoffeeScript è così vicino a JavaScript. Dopo tutto, la "regola d'oro" è: "È solo JavaScript" .
Tikhon Jelvis,

5

Vale la pena notare che l'utente ha dichiarato esplicitamente che stava trasformando una "funzione anonima in una funzione denominata", entrambi i termini con significati forti, esistenti e in particolare funzionalità diverse nel mondo JavaScript. Dato il significato esistente, i non stavano facendo nulla del genere e l'ho sottolineato.

CoffeeScript non è così lontano da JavaScript che dovresti ridefinire i termini che entrambi condividono per significare qualcos'altro in una lingua. CoffeeScript non esiste in qualche bolla, rimosso dalla sua implementazione JavaScript nel modo in cui si potrebbe sostenere che C ++ è separato da Assembly. Conoscere la differenza tra una funzione anonima e una funzione con nome è importante , perché se ti aspetti che la funzione "con nome" CoffeeScript si comporti come una funzione con nome reale , rimarrai deluso:

doStuff() # I cause an error

# ... later

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

Il JavaScript equivalente funzionerebbe bene, con una vera funzione denominata:

doStuff(); // I work just fine!

// later....

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

Potresti avere ragione sul fatto che sto solo "scherzando", ma che importa? I punti sottili nella programmazione del computer sono importanti ed essere "tecnicamente" corretti è importante. È la differenza tra la scrittura del codice che funziona e la comprensione del perché il codice è corretto .


1
Se avessi provato il tuo esempio in Python, ad esempio, non avrebbe funzionato. Quindi non sono sicuro che abbia qualcosa a che fare con le funzioni nominate vs anonime.
Winston Ewert,

1
@WinstonEwert Vedi il mio aggiornamento. Python non ha davvero nulla a che fare con esso ...
user229044

@meager, il mio punto è che le funzioni denominate non agiscono necessariamente in quel modo, sebbene lo facciano in Javascript. Pertanto, il sollevamento stesso non esclude che le funzioni di CoffeeScript vengano considerate nominate.
Winston Ewert,

Sì, devi capire che tutte le funzioni di CoffeeScript sono anonime (in realtà, preferirei dire che sono tutte espressioni di funzioni). Ma ciò non significa che a volte non possiamo essere un po 'liberi dalla terminologia. Ecco perché penso che sia pignolo insistere sul fatto che non puoi mai chiamarle funzioni nominate.
Winston Ewert,

3

Sono fuori a pranzo pensando che insistere sul fatto che questa non è una funzione nominata sia solo un pignolo?

No. Dopotutto, in termini di semantica, il riferimento della funzione è memorizzato in una variabile, a cui è possibile fare riferimento tramite un nome di variabile .


3

Sicuramente non un pazzo, imo. Lo uso ampiamente per leggibilità:

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

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

Così:

Funzione reale denominata in "coffeescript"

hello()

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

Sfuggi al JS puro tramite il backtick "

Nota che non puoi rientrare nel tuo corpo di funzione.

Saluti


1

Non perdere tempo a discutere con i pedanti. Non è mai fruttuoso. Sì, tutti sanno cosa intendi per "funzione denominata" in CoffeeScript, anche se tecnicamente non è corretto. No, l'utilizzo di una terminologia tecnicamente scorretta ma ampiamente compresa non ha alcuna attinenza con la correttezza o l'inesattezza della soluzione proposta. È possibile essere più precisi senza acquisire imbarazzo nel fraseggio? Probabilmente no. Tuttavia, ciò non significa che le persone lo lasceranno scivolare. Immagina questo ragazzo all'altro capo della conversazione.

Il motivo per cui è tecnicamente errato è perché non hai nominato la funzione, hai nominato un riferimento alla funzione. Prendere in considerazione:

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

Qual è il nome della funzione? fooe barfanno entrambi riferimento alla stessa funzione, ma hanno nomi diversi. Inoltre, o fooo barpotrebbe essere riassegnato in qualsiasi momento per fare riferimento a una funzione diversa, o addirittura a un tipo diverso, senza modificare la funzione stessa.


0

Quindi, il modo in cui leggo questo è così:

Quando si dichiara una funzione in una console JavaScript utilizzando

var foo = function() { ... }

e poi invoca foosenza parentesi, ritorna

function() { ... }

Tuttavia, se lo definisci usando

function foo() { ... }

e poi invocare di foonuovo senza parentesi, ritorna

function foo() { ... }

Nel primo caso, direi che stai dichiarando una variabile chiamata "pippo" che contiene una funzione anonima. Nel secondo caso, direi che stai effettivamente dichiarando una funzione denominata chiamata "pippo".

Poiché CoffeeScript utilizza il primo modello, concordo sul fatto che è tecnicamente corretto che le funzioni di CoffeeScript siano tutte funzioni anonime archiviate in variabili con nome.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.