Вступление
А зачем оно мне?
А почему бы и нет? К примеру, для общего развития, или просто для интереса, а впоследствии, может быть, для того, чтобы убедиться, что F# — не просто язык для ознакомления.
И что дальше?
А дальше я, пожалуй, начну. F# — мультипарадигменный язык, корни которого растут от OCaml, который смешивает в себе функциональную, императивную и объектно-ориентированную парадигмы, что, собственно, и является одним из его самых больших плюсов. Еще один плюс — это интеграция с .NET Framework. Еще один — то, что я постараюсь долго не расписывать как все это круто и удобно и перейду ближе к делу: мы получаем возможность использовать аж три парадигмы, да еще и с огромным количеством вкусностей, запакованных в коробку под названием .NET Framework. Многие задачи решаются намного проще и короче на F#, чем на том же C#, однако, справедливо и обратное.
Замечательно, ты, кажется, обещал перейти ближе к делу
Ну что ж, закончив классическое вступление, перейдем к классическому HelloWorld!
printfn "Hello, world!"
Да, это все. Впечатляет? И меня нет, поэтому пойдем дальше.
Ближе к делу
Начнем мы с функциональной части F# и, пожалуй, самого главного ключевого слова: let. Служит оно, как ни странно, для определения идентификатора и его значения.
let someId = 5
// F# также поддерживает unicode имена:
let число = 1
Есть пара оговорок:
- Идентификатор — это имя, к которому привязано какое-либо значение, причем изменить его нельзя, идентификатор можно только переопределить. С этим, кстати, можно столкнуться не только в F#, но и во всех других функциональных языках программирования.
- Значение — это все что угодно. Функция, константное значение, другой идентификатор и все, что душе угодно, только бы возвращало значение или являлось им
Немного примеров:
// в данном случае F# автоматически определит тип идентификатора
let someFloat = 0.5
// тут мы явно указываем тип идентификатора - int
let someCalculation : int = 2 + 2
// здесь идентификатору helloWorld присвоится объединение двух строк
let someString = "Hello"
let anotherString = ", World"
let helloWorld = someString + anotherString
Теперь пойдем еще дальше, и пощупаем функции.
let add x y = x + y
let someFunc x y =
let val = x + y
val / y
Cначала обсудим более абстрактное понятие функции в F#.
fun x y -> x + y
Это — анонимная функция, или лямбда-функция. Ее аргументы — x и y, оператор -> указывает на то, что дальше будет находится тело функции. В этом примере телом является выражение x + y, оно же будет и возвращаемым значением. Для тех, кто никогда не встречался с «лямбдами» на этот момент достаточно понимать, что у них просто-напросто нет имени. Все функции в F# так или иначе представляются в похожем виде, к примеру
let add = fun x y -> x + y
Тут можно увидеть как в F# на самом деле представляются функции: к идентификатору привязывается анонимная функция. То, что приводилось в качестве примера выше — упрощенный синтаксис.
Рассмотрим наш пример:
let add x y = x + y
Тут хотелось-бы порассуждать о типе аргументов. Дело в том, что F# автоматически определяет тип аргументов и возвращаемого значения, в данном случае аргументы могут быть любого типа, если они поддерживает операцию сложения.
let someFunc x y =
let val = x + y
val / y
Тут функция имеет более сложное тело, в котором используется промежуточный идентификатор. Область видимости кода определяется его отступом, то есть идентификатор val будет виден только внутри тела функции someFunc. Возвращаемое значение — val / y
Напоследок приведу небольшой пример, который покажет как функции можно вызывать в коде:
let add x y = x + y
// 2. - то же самое, что и 2.0
let avg x y = add x y / 2.
printfn "%A" add 5. 2.
// тут будет ошибка
//printfn "%A" add "Hello" ", World!"
printfn "%A" avg 2. 10.
— Почему во втором вызове printfn будет ошибка?
— Потому что функция avg возвращает тип float.
— Почему она возвращает float?
— Потому что мы делим результат add x y на float.
— Причем здесь ошибка при попытке сложения строк?
— При том, что оба аргумента функции add имеют тип float, соответственно она возвращает float
— Как так?!
— Просто для того, чтобы avg возвращала float, надо чтобы левый и правый операнды оператора деления были типа float, вот об этом F# и позаботился, так как типы аргументов в add явно не указаны.
Надеюсь, мы не прощаемся
На этом заканчивается краткое выступление в F#, тут написано далеко не все, и далеко не полностью, и не без изъянов. Но, если всем понравится, то постараюсь писать дальше, больше и подробнее, ведь целью данного поста была совсем не в том, чтобы дать всеобъемлющее представление о F#, а только чуток приоткрыть дверь в мир FP, а вот зайдем мы в нее в последующих статьях.
Что почитать/посмотреть?
Для тех, у кого с английским все хорошо, можно почитать Beginning F#. Не смотря на название, книга дает достаточно глубокое представление о F# и его применениях.
Еще можно посмотреть An Introduction to Microsoft F#
А вот ссылка на RIA (спасибо ApeCoder'у), позволяющее использовать F# Interactive прямо в окне браузера.
[Следующий пост]