F Sharp
| F# | |
|---|---|
| Класс языка | мультипарадигменный:функциональное,объектно-ориентированное,обобщённое, императивное программирование |
| Появился в | 2005 |
| Автор | Microsoft Research |
| Разработчик | Microsoft и F Sharp Software Foundation[вд] |
| Расширение файлов | .fs, .fsi, .fsx или.fsscript |
| Выпуск | 10.0 (11 ноября2025) |
| Система типов | строгая, статическая / динамическая |
| Испытал влияние | Objective Caml,C#,Haskell |
| Лицензия | Apache Software License |
| Сайт | fsharp.org |
| ОС | Кроссплатформенное программное обеспечение (.NET Framework,Mono) |
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/2026; разработаны такжекомпиляторы для Mac иLinux[1].
Microsoft интегрировала среду разработкиF# в Visual Studio 2010 и более новые версии.
4 ноября2010 года код компилятора F# и основных библиотек к нему опубликован подApache License 2.0[2].
Особенности
[править |править код]Код на языке F# являетсябезопасным в отношении типов, часто бывает более компактным, чем аналогичный кодC#, за счётвывода типов. В F# действует строгая типизация, неявные преобразования типов полностью отсутствуют, что полностью исключает ошибки, связанные с приведением типов.
Такие возможности, какобобщённое программирование ифункции высших порядков позволяют писатьабстрактные обобщённые алгоритмы, которые управляютпараметризованными структурами данных (например,массивами,списками,графами,деревьями).
Во многих языках большинство значений являются переменными. Например, в результате исполнения следующего кода на языке C в переменнойx будет храниться значение 3:
intx=2;x++;
В F#, напротив, по умолчанию все значения являются константами. F# допускает переменные, для чего требуется специально помечать значения как изменяемые при помощи слова mutable:
letx=2// неизменяемое значениеletmutabley=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. Например, когда вы определяете новый тип, то можете указать, что переменными этого типа будут «целые илистроки». Вот как это выглядит:
typemyType=IntValofint|StringValofstring
Важным примером таких типов является Option, который содержит либо значение некоторого типа, либо ничего.
typeOption<a>=None|Someofa
Он является стандартным типом F# и часто используется в ситуациях, когда результатом работы какого-то кода (например, поиска в структуре данных) является значение, которое может и не быть получено.
Код также представляет собой математическую нотацию. Следующая конструкция эквивалентна f(x) = x + 1 в алгебре:
letfx=x+1
F# работает следующим образом: тип «f» представляет собой «int -> int», то есть функция получает на вход целое и выдаёт на выход целое.
F# позволяет получить доступ абсолютно ко всему, что есть вFCL. Синтаксис для работы с библиотеками .NET в этом смысле максимально близок к синтаксисуC#. Особенности языка заметны при использовании всего спектра возможностей F#. К примеру, следующий код применяетфункцию к элементамсписка:
letrecmapfunclst=matchlstwith|[]->[]|head::tail->funchead::mapfunctailletmyList=[1;3;5]letnewList=map(funx->x+1)myList
В «newList» теперь находится «[2;4;6]».
Разборсписка в этой функции ведётся с помощью ещё одной мощной возможностисопоставления с образцом. Она позволяет задавать образцы при совпадении с которыми вычисляются соответствующие вхождения оператора match. Первый образец «[]» означает пустой список. Второй — список состоящий из первого элемента и хвоста (который может быть произвольным списком, в том числе и пустым). Во втором образце значение головы связывается с переменной head, а хвоста с tail (имена могут быть произвольные). Таким образом кроме основной задачи образец ещё позволяет производить декомпозицию сложных структур данных. Например, в случае с типом Option сопоставление с образцом выглядит так:
matchxwith|Somev->printfn"Найдено значение %d."v|None->printfn"Ничего не найдено."|_->printfn"Привет"
Язык поддерживает генераторные выражения, определенные для множеств{ … }, списков[ … ] и массивов[| … |]Например:
lettestn=[foriin0..ndoifi%2=0thenyieldi]
Функция map является одной из стандартных функций над списками, которые содержатся в модуле List. Также существуют функции для других структур данных, объявленные в модулях Array, Set, Option.
Полезным инструментом является оператор pipe-forward (|>), который позволяет писать цепочки вызовов функций в обратном порядке. В результате имеет место такой код (в комментариях указаны промежуточные значения):
[1;2;5]|>List.map((+)1)// [2; 3; 6]|>List.filter(funx->x%2=0)// [2; 6]|>List.sum// 8
Использование оператора|> исключает необходимость использования большого числа скобок, а также изменяет визуальное восприятие кода. И теперь данный код читается так: взять такой-то список, прибавить к каждому элементу 1, затем оставить только четные элементы, вернуть их сумму. То есть, описывается последовательность действий, выполняемая над изначальным объектом, в том порядке, в котором она происходит и на компьютере.
Далее небольшая демонстрация того, насколько функции .NET расширяют возможности F#. Одним из примеров являются оконные приложения и событийная обработка. Событийная обработка означает — какие-то действия в программе происходят только как реакция на определенные события — действия пользователей, подключение устройств и т. д. Проект можно создать как в Visual Studio, так и в любом текстовом документе, который затем подается на вход компилятору F# (fsc).
// open - подключение модулей и пространств имен для использования содержащихся в них// значений, классов и других модулей.openSystem.Windows.Forms// - классы Form (окно), Button (кнопка)и т. д.// Beep - звуковой сигнал// В качестве аргументов beep передаются еще некоторые параметры, которые мы не используемletbeep_=System.Console.Beep()// создание окна с программным именем окно !необходимо вызывать слово-функцию отображения - к примеру Application.Run(окно)!// Visible - булевское значение, является ли окно видимым// TopMost - отображается ли окно на переднем плане (очерёдность окон с одинаковым значением в обратном порядке вызова)// Text - текст заголовка окнаletwindow=newForm(Visible=true,TopMost=true,Text="",Top=0,Left=0,Height=512,Width=768)window.WindowState<-FormWindowState.Normal// Нормальное (, Свёрнутое, Развёрнутое) окно. Просто для примера не внесено в конструкторwindow.ClientSizeChanged.Addbeepwindow.KeyDown.Addbeepwindow.KeyPress.Addbeepwindow.KeyUp.AddbeepApplication.Runwindow// отображение окна
Факториал
[править |править код]Рекурсивная функция вычисления факториала нативным способом:
letrecfacn=ifn<2then1elsen*fac(n-1)
Рекурсивная функция вычисления факториала, оптимизированная под хвостовую рекурсию.
letfactorialnum=letrecfacnumacc=matchnumwith|xwhenx<2->acc|_->fac(num-1)(acc*num)facnum1
Функция вычисления факториала, в императивном стиле с использованием изменяемого состояния.
letfactorialnum=ifnum<2then1elseletmutablefac=1foriin[2..num]dofac<-fac*ifac
Функция вычисления факториала с использованием свертки списка и каррированой операции умножения:
letfacn=List.fold(*)1[1..n]
Рекурсивная функция вычисления чисел Фибоначчи с использованием метода сопоставления с образцом:
letrecfibnab=matchnwith|0->a|1->b|_->fib(n-1)b(a+b)
Примечания
[править |править код]- ↑Ссылки для загрузки F# на сайте Microsoft Research . Дата обращения: 24 июня 2011. Архивировано 24 июня 2011 года.
- ↑Announcing the F# Compiler + Library Source Code Drop . Дата обращения: 5 ноября 2010. Архивировано 17 января 2013 года.
См. также
[править |править код]Ссылки
[править |править код]- F# (англ.) — Microsoft F# Developer Center.
- Введение в F#. Евгений Лазин, Максим Моисеев, Давид Сорокин, «Практика функционального программирования», 2010, № 5
- Введение в F# — интервью с Доном Саймом.
- Обсуждение книги по F# на русском языке Дона Сайма «The Definitive Guide to F#»
- Три парадигмы F# — Хабрахабр.
- Try F# Tutorials — Ознакомление с языком F#. программирования
Литература
[править |править код]- Крис Смит (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.
- Страницы, использующие устаревший тег source
- Википедия:Cite web (не указан язык)
- Википедия:Статьи со ссылками на элементы Викиданных без русской подписи
- ПРО:ИТ:Статьи по алфавиту
- ПРО:ИТ:Последняя правка: в текущем году
- Википедия:Статьи к переработке с июня 2008 года
- Википедия:Статьи к переработке
- Википедия:Статьи с шаблонами недостатков по алфавиту
- Википедия:Статьи без сносок с декабря 2014 года
- Википедия:Статьи без сносок
- Страницы, использующие волшебные ссылки ISBN