CoffeeScript и именованные функции

10

В другом месте возник спор по терминологии именованной функции в CoffeeScript. В частности, кто-то упоминал что-то вроде этого:

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

как именованная функция. Но было высказано возражение, что все в CoffeeScript является анонимными функциями и не имеет именованных функций. Это, безусловно, верно, у CoffeeScript есть только функциональные выражения, которые затем можно сохранить в переменной. Но я не думаю, что это означает, что неправильно называть это именованной функцией.

На мой взгляд, это именованная функция, потому что ей присвоено имя. Правда, это не именованная функция так же, как некоторые другие языки имеют именованные функции, но я думаю, что она достаточно близка, чтобы не называть ее именованной функцией. Настаивать на другом просто кажется придиркой.

Могу ли я пойти на ланч, думая, что настаивать на том, что это не именованная функция, просто придираться?

Уинстон Эверт
источник
3
Разве весь этот вопрос не просто придирки? :-)
Mat
@ Мат, да, кажется, я не могу избежать придирки к придиркам
Уинстон Эверт
Для небольшого пула программистов, с которыми я общаюсь (за исключением программистов. То есть), они в основном говорят, что используют именованные функции JavaScript для использования в качестве «классов» (конструкторов), в то время как анонимные функции хранятся в переменных для простых старых функций.
Sal
1
«Просто придирки» подразумевают, что ответ не имеет значения, и что понимание тонкостей языка не является достойной целью.
user229044
Я мог бы взглянуть на это аналогично CoffeeScript: foo = ->это просто старая функция, а class Fooконструктор. Я не вижу причин, почему foo = ->следует строго называть их анонимными.
Sal

Ответы:

20

CoffeeScript неумолимо связан с JavaScript, и JavaScript различает следующие выражения:

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

На самом деле, вы даже можете написать:

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

Поскольку это различие имеет значение в JavaScript, имеет смысл использовать те же термины, когда речь идет о CoffeeScript. Однако CoffeeScript не поддерживает ничего подобного function foo ()синтаксису, поэтому мы можем сказать, что он не имеет «именованных» функций.

В некотором смысле имя является частью определения функции в function foo() { ... }, где в другом случае вы просто создаете функцию и присваиваете ее переменной. Это отражено, например, в (нестандартном) nameсвойстве функций: в первом случае foo.nameэто даст вам, "foo"а во втором это даст вам "".

Кроме того, в JavaScript они также различаются с точки зрения того, как они вводятся в область действия: первая версия «поднята» и доступна во всей области ее действия, где второе определение доступно только после ее назначения.

По сути, просто думайте об этом как о специфичном для JavaScript жаргоне, который переносится в CoffeeScript, потому что CoffeeScript так тесно связан с JS.

Тихон Джелвис
источник
1
Это правда, что не существует такой вещи, как function foo () {}. Тем не менее, вы все равно можете инициализировать именованную функцию через classконструкцию. Просто скомпилированный CoffeeScript (получившийся в результате JavaScript) гораздо более многословен, чем большинство написало бы именованную функцию.
Sal
1
А также, есть техническая оговорка: fooтело вашей функции не будет поднято.
Sal
1
Джеливс: нет проблем. Одно исправление из последнего комментария, который я написал к вашему ответу: class fooтело вашей функции не будет перемещено в верхнюю часть файла.
Sal
Поскольку CoffeeScript не делает различий между именованными и анонимными функциями, можем ли мы действительно сказать, что терминология перенесена в CoffeeScript? Различие Javascript просто ничего не значит на этом языке.
Уинстон Эверт
@WinstonEwert: Это важно, потому что CoffeeScript очень близок к JavaScript. В конце концов, «золотое правило» таково: «Это просто JavaScript» .
Тихон Джелвис
5

Стоит отметить, что пользователь явно заявил, что превращает «анонимную функцию в именованную функцию», причем оба термина имеют сильное существующее значение и заметно отличающиеся функции в мире JavaScript. Учитывая существующее значение, они не делали такой вещи, и я указал на это.

CoffeeScript не так далек от JavaScript, что вам следует переопределить термины, которые они оба разделяют, чтобы означать что-то еще на одном языке. CoffeeScript не существует в каком-то пузыре, удаленном из его реализации JavaScript, как вы могли бы утверждать, что C ++ отделен от Assembly. Знание разницы между анонимной функцией и именованной функцией имеет значение , потому что, если вы ожидаете, что ваша «именованная» функция CoffeeScript будет вести себя как фактическая именованная функция, вы будете разочарованы:

doStuff() # I cause an error

# ... later

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

Эквивалентный JavaScript будет хорошо работать с реальной именованной функцией:

doStuff(); // I work just fine!

// later....

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

Вы можете быть правы, что я просто придираюсь, ну и что? Тонкие моменты в компьютерном программировании имеют значение , и важно быть «технически» правильным. Это разница между написанием кода, который работает, и фактическим пониманием того, почему ваш код корректен .

user229044
источник
1
Например, если я попробую ваш пример на Python, он все равно не будет работать. Так что я не уверен, что это как-то связано с именованными и анонимными функциями.
Уинстон Эверт
1
@WinstonEwert Смотрите мое обновление. Python действительно не имеет к этому никакого отношения ...
user229044
@meager, я хочу сказать, что именованные функции не обязательно действуют таким образом, хотя в Javascript они действуют. Следовательно, подъем сам по себе не лишает функции CoffeeScript возможности считаться именованными.
Уинстон Эверт
Да, вы должны понимать, что все функции в CoffeeScript являются анонимными (на самом деле, я бы предпочел сказать, что все они являются выражениями функций). Но это не значит, что иногда мы не можем быть немного свободными с терминологией. Вот почему я считаю неприличным настаивать на том, что вы никогда не сможете называть их именованными функциями.
Уинстон Эверт
3

Могу ли я пойти на ланч, думая, что настаивать на том, что это не именованная функция, просто придираться?

Нет. В конце концов, с точки зрения семантики, ваша ссылка на функцию хранится в переменной, к которой вы можете обращаться через имя переменной .

Сэл
источник
3

Определенно не придурок, имо. Я использую это широко для удобства чтения:

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

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

Таким образом:

Реальная именованная функция в "coffeescript"

hello()

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

Вы избегаете чистого JS через обратную черту

Обратите внимание, что вы не можете сделать отступ в своем теле функции.

ура

Зайд Дагестан
источник
1

Не тратьте время на споры с педантами. Это никогда не плодотворно. Да, все знают, что вы подразумеваете под «именованной функцией» в CoffeeScript, даже если она технически неверна. Нет, использование технически неверной, но широко понятой терминологии не имеет отношения к правильности или неправильности предложенного решения. Можно ли быть более точным, не получая некоторую неловкость формулировки? Возможно нет. Однако это не означает, что люди позволят этому скользить. Просто представьте этого парня на другом конце разговора.

Технически неверная причина в том, что вы не назвали функцию, вы назвали ссылку на функцию. Рассматривать:

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

Как называется функция? fooи barоба ссылаются на одну и ту же функцию, но имеют разные имена. Кроме того , либо , fooили barможет быть переведен в любое время , чтобы ссылаться на другую функцию, или даже другой тип в целом, не меняя саму функцию.

Карл Билефельдт
источник
0

Итак, как я читаю это так:

Когда вы объявляете функцию в консоли JavaScript, используя

var foo = function() { ... }

а затем вызвать fooбез скобок, он возвращает

function() { ... }

Однако, если вы определите это с помощью

function foo() { ... }

и затем вызвать fooснова без скобок, он возвращает

function foo() { ... }

В первом случае я бы сказал, что вы объявляете переменную с именем "foo", в которой хранится анонимная функция. Во втором случае я бы сказал, что вы на самом деле объявляете именованную функцию с именем "foo".

Поскольку CoffeeScript использует первый шаблон, я согласен, что технически правильно, что функции CoffeeScript - это все анонимные функции, хранящиеся в именованных переменных.

Дилан Рибб
источник