CoffeeScript e funções nomeadas

10

Em outros lugares , surgiu um argumento sobre a terminologia de uma função nomeada no CoffeeScript. Em particular, alguém se referiu a algo assim:

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

como uma função nomeada. Mas foi contestado que tudo no CoffeeScript é funções anônimas e não há funções nomeadas. Isso certamente é verdade, o CoffeeScript possui apenas expressões de função que podem ser armazenadas em uma variável. Mas eu não acho que isso significa que é errado chamar isso de função nomeada.

A meu ver, é uma função nomeada porque é uma função que recebeu um nome. É verdade que não é uma função nomeada da mesma maneira que algumas outras linguagens nomearam funções, mas acho que é próximo o suficiente para que não seja inadequado chamá-la de função nomeada. Insistir de outra maneira apenas parece ser uma questão.

Devo almoçar ao pensar que insistir que essa não é uma função nomeada é apenas uma brincadeira?

Winston Ewert
fonte
3
Não é toda essa questão apenas, bem, nitpicking? :-)
Mat
@Mat, sim, parece que não pode evitar picuinhas sobre picuinhas
Winston Ewert
Para o pequeno grupo de programadores com quem converso (fora dos programadores.SE), eles costumam usar as funções nomeadas do JavaScript para serem usadas como "classes" (construtores), enquanto as funções anônimas são armazenadas em variáveis ​​para funções antigas simples.
Sal
11
"Apenas apontar" implica que a resposta não importa, e que entender as sutilezas de um idioma não é um objetivo digno.
user229044
Eu poderia olhar analogicamente para o CoffeeScript: foo = ->é apenas uma função antiga e simples, enquanto class Fooé um construtor. Não vejo razão para foo = ->que estritamente seja chamado de anônimo.
Sal

Respostas:

20

O CoffeeScript está inexoravelmente vinculado ao JavaScript, e o JavaScript diferencia entre as seguintes expressões:

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

De fato, você pode até escrever:

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

Como essa diferença é importante no JavaScript, faz sentido usar os mesmos termos ao falar sobre o CoffeeScript. No entanto, o CoffeeScript não suporta nada como a function foo ()sintaxe, portanto, podemos dizer que não possui funções "nomeadas".

Em certo sentido, o nome faz parte da definição da função no diretório function foo() { ... }onde, no outro caso, você apenas cria uma função e a atribui a uma variável. Isso se reflete, por exemplo, na namepropriedade (fora do padrão) das funções: no primeiro caso, foo.namefornecerá a você "foo"e no segundo, fornecerá "".

Além disso, no JavaScript, eles também diferem em termos de como eles são introduzidos no escopo: a primeira versão é "içada" e está disponível em todo o escopo, onde a segunda definição está disponível apenas após a atribuição.

Basicamente, pense nisso como um jargão específico para JavaScript, que é transferido para o CoffeeScript porque o CoffeeScript está intimamente relacionado ao JS.

Tikhon Jelvis
fonte
11
É verdade que não existe algo como a function foo () {}. No entanto, você ainda pode inicializar uma função nomeada por meio da classconstrução. Só que o CoffeeScript compilado (o JavaScript resultante) é muito mais detalhado do que o modo como a maioria escreveria uma função nomeada.
Sal
11
E também há uma advertência técnica: fooo corpo da sua função não será içado.
Sal
11
jelivs: não há problema. Uma correção do último comentário que escrevi sobre sua resposta: o class foocorpo da função do seu não será içado no topo do arquivo.
Sal
Como o CoffeeScript não faz distinção entre funções nomeadas e anônimas, podemos realmente dizer que a terminologia é transferida para o CoffeeScript? A distinção de Javascript simplesmente não significa nada nesse idioma.
Winston Ewert
@WinstonEwert: Importa porque o CoffeeScript está muito próximo do JavaScript. Afinal, a "regra de ouro" é: "É apenas JavaScript" .
Tikhon Jelvis 19/03/2013
5

Vale a pena notar que o usuário declarou explicitamente que estava transformando uma "função anônima em uma função nomeada", ambos os termos com significados fortes e existentes e funcionalidades notavelmente diferentes no mundo do JavaScript. Dado o significado existente, eles não estavam fazendo isso, e eu apontei isso.

O CoffeeScript não está tão longe do JavaScript que você deve redefinir os termos que ambos compartilham para significar outra coisa em um idioma. O CoffeeScript não existe em algumas bolhas, removido da implementação do JavaScript da maneira que você pode argumentar que o C ++ é separado do Assembly. Saber a diferença entre uma função anônima e uma função nomeada é importante , porque se você espera que a função CoffeeScript "nomeada" se comporte como uma função nomeada real , você ficará desapontado:

doStuff() # I cause an error

# ... later

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

O JavaScript equivalente funcionaria bem, com uma função nomeada real :

doStuff(); // I work just fine!

// later....

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

Você pode estar certo de que estou apenas "cutucando", mas e daí? Os pontos sutis da programação de computadores são importantes , e ser "tecnicamente" correto é importante. É a diferença entre escrever código que funciona e entender realmente por que seu código está correto .

user229044
fonte
11
Se eu tentasse seu exemplo em Python, por exemplo, ele ainda não funcionaria. Portanto, não tenho certeza de que tenha algo a ver com funções nomeadas vs anônimas.
Winston Ewert
11
@WinstonEwert Veja minha atualização. Python realmente não tem nada a ver com isso ...
user229044
@meager, meu argumento é que as funções nomeadas não necessariamente agem dessa maneira, embora o façam em Javascript. Portanto, o içamento em si não desqualifica as funções do CoffeeScript de serem consideradas nomeadas.
Winston Ewert
Sim, você precisa entender que todas as funções no CoffeeScript são anônimas (na verdade, prefiro dizer que são todas expressões de função). Mas isso não significa que às vezes não possamos ficar um pouco frouxos com a terminologia. É por isso que acho que é insistente insistir que você nunca pode chamá-los de funções nomeadas.
Winston Ewert
3

Devo almoçar ao pensar que insistir que essa não é uma função nomeada é apenas uma brincadeira?

Não. Afinal, em termos de semântica, sua referência de função é armazenada em uma variável, à qual você pode consultar por meio de um nome de variável .

Sal
fonte
3

Definitivamente não é um nitpick, imo. Eu o uso extensivamente para facilitar a leitura:

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

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

Portanto:

Função nomeada real em "coffeescript"

hello()

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

Você escapa JS puro através do backtick `

Observe que você não pode recuar no seu corpo funcional.

Felicidades

Zaid Daghestani
fonte
1

Não perca tempo discutindo com pedantes. Nunca é frutífero. Sim, todo mundo sabe o que você quer dizer com "função nomeada" no CoffeeScript, mesmo que seja tecnicamente incorreto. Não, o uso de terminologia tecnicamente incorreta, mas amplamente compreendida, não tem influência na correção ou incorreta da solução proposta. É possível ser mais preciso sem obter algum constrangimento de fraseado? Provavelmente não. No entanto, isso não significa que as pessoas vão deixar passar. Imagine esse cara do outro lado da conversa.

O motivo tecnicamente incorreto é que você não nomeou a função, nomeou uma referência à função. Considerar:

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

Qual o nome da função? fooe barestão fazendo referência à mesma função, mas têm nomes diferentes. Além disso, um fooou barpode ser reatribuído a qualquer momento para referenciar uma função diferente, ou mesmo um tipo diferente, sem alterar a própria função.

Karl Bielefeldt
fonte
0

Então, a maneira como eu li isso é assim:

Quando você declara uma função em um console JavaScript usando

var foo = function() { ... }

e depois invocar foosem parênteses, ele retorna

function() { ... }

No entanto, se você o definir usando

function foo() { ... }

e depois invocar foonovamente sem parênteses, ele retorna

function foo() { ... }

No primeiro caso, eu diria que você está declarando uma variável chamada "foo" armazenando uma função anônima nela. No segundo caso, eu diria que você está realmente declarando uma função nomeada chamada "foo".

Como o CoffeeScript usa o primeiro padrão, eu concordo que é tecnicamente correto que as funções do CoffeeScript sejam todas funções anônimas sendo armazenadas em variáveis ​​nomeadas.

Dylan Ribb
fonte