F#: нужно ли ключевое слово fun?

Я набирал ключевое слово «весело», а потом вспомнил, что в C# этого делать не нужно.

Не будет ли это:

List.map (x -> x + 1) [1..10]

Быть таким же выразительным?:

List.map (fun x -> x + 1) [1..10]

Это заставляет меня задуматься, зачем вообще нужно ключевое слово «fun». Может ли кто-нибудь пояснить, почему синтаксически требуется ключевое слово «весело»?


person rysama    schedule 18.12.2009    source источник
comment
Я ничего не знаю о F#, но мне кажется, что в нем есть ключевое слово fun.. забавно.   -  person Thomas Bonini    schedule 18.12.2009
comment
потому что программировать на F# весело! Это дружеское напоминание во время кодирования :)   -  person Russell    schedule 18.12.2009
comment
Если бы они его убрали, в f# не было бы веселья! А если серьезно, это любопытно, поскольку лямбда-выражения в C# не нуждаются в ключевом слове. Это может быть просто для упрощения синтаксического анализа. По мере развития языков такие вещи, как правило, сокращаются или становятся необязательными.   -  person Jim L    schedule 18.12.2009
comment
Хорошая мысль о эволюции @Jim. Это может помочь уменьшить кривую обучения F #, и как только он станет/может стать более широко используемым, ключевые слова, которые подразумеваются, могут быть удалены.   -  person Russell    schedule 18.12.2009
comment
это необходимо, если вы хотите, чтобы он скомпилировался :)   -  person dan    schedule 18.12.2009
comment
Разве ключевое слово fun не осталось от семейства языков ML? Haskell, кажется, справляется с использованием обратной косой черты.   -  person yatima2975    schedule 18.12.2009
comment
@ yatima2975: Я не совсем уверен, что обратная косая черта намного меньше. Это на пару символов короче — в остальном они идентичны. Оба являются токенами, указывающими на лямбду.   -  person Chuck    schedule 18.12.2009
comment
Хорошая обратная косая черта на Haskellian была бы приятной, а не забавной. Ну, по крайней мере, это больше напоминает мне символ лямбда   -  person Bernadette    schedule 18.12.2009
comment
@ yatima2975: Да, в SML тоже есть «веселье».   -  person Stringer    schedule 18.12.2009
comment
Как ни странно, SML использует fun вместо let rec. Эквивалентом OCaml и fun в F# является fn.   -  person Chuck    schedule 18.12.2009
comment
Кроме того, по этому поводу есть проблема на GitHub.   -  person aloisdg    schedule 10.04.2019


Ответы (3)


Язык двусмыслен без него.

let x y = y z -> y z

Вызывает ли x y функцию z -> y z или игнорирует аргумент и возвращает функцию y z -> y z?

person Chuck    schedule 18.12.2009
comment
хм, хорошее замечание, но, конечно, вы могли бы добавить круглые скобки, чтобы решить двусмысленность: y (z -> y z)? хм... не приведет ли это к тому, что все станет более подробным? - person rysama; 18.12.2009
comment
Но тогда вы только что преобразовали fun в (). C# может обойтись без специального синтаксиса для лямбда-выражений, потому что он изначально имеет более сложный синтаксис. В таком языке, как F#, я не понимаю, как можно обойти использование какого-либо разделителя, чтобы сказать OK, лямбда подходит! - person Chuck; 18.12.2009
comment
Я не думаю, что это должно быть двусмысленным, в большинстве языков много двусмысленности, и существуют правила приоритета, которые используются, чтобы «сломать» двусмысленность. Возможно, это еще один такой случай. - person Brian; 18.12.2009
comment
@Brian: я пытаюсь придумать, как такое правило будет выражено, не делая другие части языка более запутанными. Кажется, что единственным простым выбором является каждый идентификатор до того, как -> является аргументом (опция превращения fun в ()), или лямбда-выражения принимают только один аргумент (что, я думаю, приблизит нас к лямбда-исчислению). Вероятно, есть еще один вариант, о котором я не подумал, но я думаю, что fun здесь довольно простое решение. - person Chuck; 18.12.2009

Уже много приличных спекулятивных ответов... Я добавлю к смеси:

F# имеет базовый язык, совместимый с OCaml, а OCaml использует «веселье».

person Brian    schedule 18.12.2009

Я знаю, что как часть каррирования (см. этот post) вы можете заменить:

let countOneToTen = fun y List.map(fun x -> x + 1) y
countOneToTen = [1..10]

с участием

let countOneToTen y = List.map(fun x -> x + 1) y
countOneToTen = [1..10]

без веселого ключевого слова.

person Russell    schedule 18.12.2009
comment
ОП говорит не об этом. Вместо этого они спрашивают, почему fun x -> x + 1 не может быть просто x -> x + 1. - person bcat; 18.12.2009
comment
Вопрос заключается в том, нужно ли ключевое слово «весело» вообще, я привел еще один пример того, где его можно использовать и опускать в зависимости от предпочтений разработчика. - person Russell; 18.12.2009
comment
Я знаю (и я не тот, кто проголосовал за вас, чтобы было ясно). Хотя я, честно говоря, не знаю, почему кто-то предпочитает версию, в которой не используется частичное применение. :) - person bcat; 18.12.2009
comment
Я вижу, к чему вы пришли из @bcat. Это сценарий, в котором я бы также использовал его частичное применение, однако я говорил в более общем плане. Я считаю (при условии, что функции названы правильно), каррирование функций (помимо уменьшения значений параметров) обеспечивает более четкий поток кода. (*Примечание: я все еще изучаю F#! :) ) - person Russell; 18.12.2009