У этого термина существуют и другие значения, см.
F (значения)
.
F#
(произносится
эф-шарп
) ?
мультипарадигмальный язык программирования
из семейства языков
.NET
, поддерживающий
функциональное программирование
в дополнение к
императивному
(
процедурному
) и
объектно-ориентированному программированию
. Структура F# во многом схожа со структурой
OCaml
с той лишь разницей, что F# реализован поверх
библиотек
и среды исполнения
.NET
. Язык был разработан
Доном Саймом
(
англ.
Don Syme
) в
Microsoft Research
в
Кембридже
, в настоящее время его разработку ведёт Microsoft Developer Division. F# достаточно тесно интегрируется со средой разработки
Visual Studio
и включён в поставку Visual Studio 2010/2012/2013/2015/2017/2019/2022; разработаны также
компиляторы
для Mac и
Linux
[1]
.
Microsoft
интегрировала среду разработки
F#
в Visual Studio 2010 и более новые версии.
4 ноября
2010 года
код компилятора F# и основных библиотек к нему опубликован под
Apache License
2.0
[2]
.
Код
на языке F# является
безопасным в отношении типов
, часто бывает более компактным, чем аналогичный код
C#
, за счёт
вывода типов
. В F# действует строгая типизация, неявные преобразования типов полностью отсутствуют, что полностью исключает ошибки, связанные с приведением типов.
Такие возможности, как
обобщённое программирование
и
функции высших порядков
позволяют писать
абстрактные обобщённые алгоритмы
, которые управляют
параметризованными структурами данных
(например,
массивами
,
списками
,
графами
,
деревьями
).
Во многих языках большинство значений являются переменными. Например, в результате исполнения следующего кода на языке C++ в переменной
x
будет храниться значение 3:
В F#, напротив, по умолчанию все значения являются константами. F# допускает переменные, для чего требуется специально помечать значения как изменяемые при помощи слова mutable:
let
x
=
2
// неизменяемое значение
let
mutable
y
=
2
// переменная
x
<-
3
// ошибка
y
<-
3
// Ok. y = 3
Также в F# есть ссылочные типы и объекты, которые также могут содержать изменяемые значения. Тем не менее, бо?льшая часть кода является
чистыми функциями
, что позволяет избежать многих ошибок и упростить отладку. Кроме того, упрощается распараллеливание программ. При всём этом код редко становится сложнее, чем аналогичный код на императивном языке.
Одна из основных идей F# заключается в том, чтобы удостовериться, что имеющийся код и типы в функциональном языке программирования могут быть легко доступны из других .NET-языков. Программы на F# компилируются в сборки CLR (файлы с расширениями .exe и .dll), однако, для их запуска необходима установка пакета среды исполнения дополнительно к .NET Framework.
Интересной особенностью (и отличием от
OCaml
) является управление логической вложенностью конструкций кода за счёт отступов в виде произвольного количества пробелов (и только лишь пробелов). Знаки табуляции для этой цели не поддерживаются. Это приводит к постоянным дискуссиям на форумах опытных разработчиков, которые привыкли пользоваться знаками табуляции в других языках программирования.
F# ? компилируемый язык программирования, при этом в качестве промежуточного языка используется язык
Common Intermediate Language
(CIL), так же как и в программах, написанных на языках
C#
или
VB.NET
.
Наряду с F#-
компилятором
(fsc) присутствует и F#-
интерпретатор
(fsi), который исполняет F#-код интерактивно.
Отличительной чертой F#-
компилятора
и F#-
интерпретатора
является возможность воспринимать код двумя разными способами ? немедленно (по умолчанию) и
отложенно
(программисту требуется явно указать это в исходном коде). В случае немедленной интерпретации, выражения вычисляются заранее в момент запуска программы на выполнение, независимо от того, вызываются ли они в процессе выполнения программы или нет. В этом случае, зачастую снижается производительность выполнения программы, а также происходит неэкономное расходование ресурсов системы (например, памяти). В случае ленивой интерпретации кода, выражения вычисляются только в тот момент, когда к ним происходит непосредственное обращение в процессе выполнения программы. Это избавляет программу от перечисленных выше недостатков, но снижает предсказуемость в плане объёма и последовательности использования ресурсов (процессорного времени, памяти, устройств ввода-вывода и т. п.) на различных этапах выполнения программы.
Синтаксис
F# построен на математической нотации, а программирование чем-то похоже на
алгебру
, что делает F# похожим на
Haskell
. Например, когда вы определяете новый тип, то можете указать, что переменными этого типа будут ≪
целые
или
строки
≫. Вот как это выглядит:
type
myType
=
IntVal
of
int
|
StringVal
of
string
Важным примером таких типов является Option, который содержит либо значение некоторого типа, либо ничего.
type
Option
<
a
>
=
None
|
Some
of
a
Он является стандартным типом F# и часто используется в ситуациях, когда результатом работы какого-то кода (например, поиска в структуре данных) является значение, которое может и не быть получено.
Код также представляет собой математическую нотацию. Следующая конструкция эквивалентна f(x) = x + 1 в алгебре:
F# работает следующим образом: тип ≪
f
≫ представляет собой ≪
int -> int
≫, то есть функция получает на вход целое и выдаёт на выход целое.
F# позволяет получить доступ абсолютно ко всему, что есть в
FCL
. Синтаксис для работы с библиотеками .NET в этом смысле максимально близок к синтаксису
C#
. Особенности языка заметны при использовании всего спектра возможностей F#. К примеру, следующий код применяет
функцию
к элементам
списка
:
let
rec
map
func
lst
=
match
lst
with
|
[]
->
[]
|
head
::
tail
->
func
head
::
map
func
tail
let
myList
=
[
1
;
3
;
5
]
let
newList
=
map
(
fun
x
->
x
+
1
)
myList
В ≪
newList
≫ теперь находится ≪
[2;4;6]
≫.
Разбор
списка
в этой функции ведётся с помощью ещё одной мощной возможности
сопоставления с образцом
. Она позволяет задавать образцы при совпадении с которыми вычисляются соответствующие вхождения оператора match. Первый образец ≪[]≫ означает пустой список. Второй ? список состоящий из первого элемента и хвоста (который может быть произвольным списком, в том числе и пустым). Во втором образце значение головы связывается с переменной head, а хвоста с tail (имена могут быть произвольные). Таким образом кроме основной задачи образец ещё позволяет производить декомпозицию сложных структур данных. Например, в случае с типом Option сопоставление с образцом выглядит так:
match
x
with
|
Some
v
->
printfn
"Найдено значение %d."
v
|
None
->
printfn
"Ничего не найдено."
|
None
->
printfn
"Привет"
Язык поддерживает генераторные выражения, определенные для множеств
{ … }
, списков
[ … ]
и массивов
[| … |]
Например:
let
test
n
=
[
for
i
in
0
..
n
do
if
i
%
2
=
0
then
yield
i
]
Функция map является одной из стандартных функций над списками, которые содержатся в модуле List. Также существуют функции для других структур данных, объявленные в модулях Array, Set, Option.
Полезным инструментом является оператор pipe-forward (|>), который позволяет писать цепочки вызовов функций в обратном порядке. В результате имеет место такой код (в комментариях указаны промежуточные значения):
[
1
;
2
;
5
]
|>
List
.
map
((+)
1
)
// [2; 3; 6]
|>
List
.
filter
(
fun
x
->
x
%
2
=
0
)
// [2; 6]
|>
List
.
sum
// 8
Использование оператора
|>
исключает необходимость использования большого числа скобок, а также изменяет визуальное восприятие кода. И теперь данный код читается так: взять такой-то список, прибавить к каждому элементу 1, затем оставить только четные элементы, вернуть их сумму. То есть, описывается последовательность действий, выполняемая над изначальным объектом, в том порядке, в котором она происходит и на компьютере.
Далее небольшая демонстрация того, насколько функции .NET расширяют возможности F#. Одним из примеров являются оконные приложения и событийная обработка. Событийная обработка означает ? какие-то действия в программе происходят только как реакция на определенные события ? действия пользователей, подключение устройств и т. д. Проект можно создать как в Visual Studio, так и в любом текстовом документе, который затем подается на вход компилятору F# (fsc).
// open - подключение модулей и пространств имен для использования содержащихся в них
// значений, классов и других модулей.
open
System.Windows.Forms
// - классы Form (окно), Button (кнопка)и т. д.
// Beep - звуковой сигнал
// В качестве аргументов beep передаются еще некоторые параметры, которые мы не используем
let
beep
_
=
System
.
Console
.
Beep
()
// создание окна с программным именем окно !необходимо вызывать слово-функцию отображения - к примеру Application.Run(окно)!
// Visible - булевское значение, является ли окно видимым
// TopMost - отображается ли окно на переднем плане (очерёдность окон с одинаковым значением в обратном порядке вызова)
// Text - текст заголовка окна
let
window
=
new
Form
(
Visible
=
true
,
TopMost
=
true
,
Text
=
""
,
Top
=
0
,
Left
=
0
,
Height
=
512
,
Width
=
768
)
window
.
WindowState
<-
FormWindowState
.
Normal
// Нормальное (, Свёрнутое, Развёрнутое) окно. Просто для примера не внесено в конструктор
window
.
ClientSizeChanged
.
Add
beep
window
.
KeyDown
.
Add
beep
window
.
KeyPress
.
Add
beep
window
.
KeyUp
.
Add
beep
Application
.
Run
window
// отображение окна
Рекурсивная функция вычисления факториала нативным способом:
let
rec
fac
n
=
if
n
<
2
then
1
else
n
*
fac
(
n
-
1
)
Рекурсивная функция вычисления факториала, оптимизированная под хвостовую рекурсию.
let
factorial
num
=
let
rec
fac
num
acc
=
match
num
with
|
x
when
x
<
2
->
acc
|_
->
fac
(
num
-
1
)
(
acc
*
num
)
fac
num
1
Функция вычисления факториала, в императивном стиле с использованием изменяемого состояния.
let
factorial
num
=
if
num
<
2
then
1
else
let
mutable
fac
=
1
for
i
in
[
2
..
num
]
do
fac
<-
fac
*
i
fac
Функция вычисления факториала с использованием свертки списка и каррированой операции умножения:
let
fac
n
=
List
.
fold
(*)
1
[
1
..
n
]
Рекурсивная функция вычисления чисел Фибоначчи с использованием метода сопоставления с образцом:
let
rec
fib
n
a
b
=
match
n
with
|
0
->
a
|
1
->
b
|
_
->
fib
(
n
-
1
)
b
(
a
+
b
)
- Крис Смит (Smith, Chris).
Программирование на F# = Programming F#. ? O'Reilly, 2011. ? 448 с. ?
ISBN 978-5-93286-199-8
.
- Дмитрий Сошников.
Функциональное программирование на F#. ? Москва: ДМК Пресс, 2011. ? 192 с. ?
ISBN 978-5-94074-689-8
.
- Syme, Don; Granicz, Adam; Cisternino, Antonio.
Expert F#. ? Apress, 2007.
(англ.)
|
---|
Основные
проекты
| |
---|
MSR Labs
| |
---|
|
|
---|
Общая информация
| |
---|
Программное
обеспечение
| Приложения
| |
---|
Игры
| |
---|
Языки
программирования
| |
---|
Фреймворки и
средства разработки
| |
---|
Операционные
системы
| |
---|
Прочее
| |
---|
|
---|
Лицензии
| |
---|
Связанные темы
| |
---|
|