Tw-city.info

IT Новости
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Функциональное программирование f

Что выбрать новичку: C# или F#

Чем различаются C# и F#, для чего они используются и что проще и перспективнее учить новичку.

Эта статья для тех, кто только выбирает свой первый язык программирования. Во время поисков вы могли встретить упоминания о C# и F#. У них много общего (в том числе и названия похожи), но и различий тоже достаточно. Рассказываем, как понять, какой из них лучше подходит именно вам.

C# и F# — это языки программирования из семейства .NET. Оба языка разрабатываются компанией Microsoft, одинаково компилируются и поддерживаются одними и теми же платформами. Даже производительность у них практически на одном уровне. Однако они всё равно достаточно сильно различаются.

Евгений Кучерявый

Пишет о разработке сайтов, в свободное время создает игры. Мечтает открыть свою студию и выпускать ламповые RPG.

Отличия F# и C#

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

В C# используется императивная (англ. imperative — приказ, повелительное наклонение) парадигма. В ней программист пишет инструкции для компьютера, то есть отдает ему приказы. Чтобы делать это было удобнее, используются объекты — это называется объектно-ориентированным программированием:

  • Консоль (объект), выведи надпись (инструкция)!
  • Калькулятор, умножь числа!
  • Клиент, отправь запрос серверу!
  • Сервер, подключись к базе данных!

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

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

В F# разработчик использует декларативную парадигму и функциональное программирование. В F# вместо инструкций — выражения, которые всегда возвращают какое-то значение. Разработчик не отдает приказы, а описывает проблему, способ ее решения (функцию) и ожидаемый результат. То есть нужно сказать программе, что делать, а решит задачу она сама.

C#

F#

В примере выше показано получение факториала в C# и F#. В обоих фрагментах кода есть конструкция if-else, которая позволяет изменять ход выполнения программы в зависимости от того, было ли соблюдено условие. В C# с помощью этой конструкции указываются какие-то действия (в данном случае используется оператор return, который возвращает значение), а в F# — значения, которые будут возвращены.

Для чего они используются

Оба языка можно использовать для разработки:

  • сайтов;
  • программ для компьютеров;
  • мобильных приложений;
  • игр;
  • скриптов и так далее.

В целом языки универсальны. Например, несмотря на то что работать с пользовательским интерфейсом лучше с помощью объектов, для этой задачи вполне подойдет и F#, потому что в нем тоже есть поддержка ООП.

Однако всё же есть задачи, когда стоит предпочесть тот или иной язык:

  • F# лучше использовать для написания бизнес-логики, которая требует серьезных вычислений (в том числе и для работы с Big Data и машинным обучением).
  • C# больше подходит для разработки интерфейсов, работы с графикой или же написания логики, в которой нужно работать с объектами. Например, функциональное программирование вряд ли подойдет для создания игры, потому что в ней много сущностей (персонажи, предметы, декорации). Именно поэтому среди разработчиков игр более популярен C#.

Кроме того, достаточно распространена практика, когда UI (пользовательский интерфейс) написан на C#, а бизнес-логика — на F#.

Важно понимать, что нельзя слепо любить только один язык и использовать его для всего, — для решения каждой задачи есть свой инструмент.

Что учить новичку

Несмотря на то что парадигмы различаются, новичкам одинаково легко учить и C#, и F#. Если человек никогда не программировал и еще не успел привыкнуть к объектно- или функционально-ориентированной разработке, то никаких проблем не будет. Наоборот, сложности могут возникнуть у тех, кто уже освоился с одной из парадигм и теперь видит написание приложений через определенную призму.

В целом же оба языка довольно востребованы, для обоих написано много обучающих материалов, а также имеется дружелюбное и большое сообщество, которое может помочь исправить баги и найти подходящее решение любой задачи. Однако C# более распространен как среди программистов, так и среди компаний, поэтому с ним проще найти работу.

Если вы хотите решать задачи, для которых больше подходит F#, то можете посмотреть информацию на официальном сайте языка (на английском). Там можно узнать, как начать использовать язык, выучить его синтаксис, а также почитать гайды по использованию F# в той или иной сфере.

Если же вам больше по душе C#, то записывайтесь на курс «Профессия C#-разработчик» — там вы не только узнаете азы языка, но и поработаете над проектами, которые сможете добавить в портфолио.

Обязательно изучите функциональное программирование в 2017 году

Функциональное программирование существует уже очень давно, начиная с появления языка программирования Lisp в 50-х годах прошлого века. И, если вы заметили, на протяжении последних двух лет такие языки, как Clojure, Scala, Erlang, Haskell и Elixir, создают много шума и привлекают к себе внимание.

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

Краткая история функционального программирования

Как мы уже говорили, функциональное программирование берет свое начало еще в 50-х годах с момента создания Lisp для работы в серии научных компьютеров IBM700/7000. Lisp представил множество парадигм и особенностей, которые теперь мы связываем с функциональным программированием, и хотя мы можем назвать Lisp дедушкой функционального программирования мы можем копнуть глубже и взглянуть на еще большую общность между всеми функциональными языками программирования — лямбда-исчисление.

Это, безусловно, самый интересный аспект функционального программирования. Все языки функционального программирования основаны на одной и той же простой математической основе — лямбда-исчислении.

Лямбда-исчисление обладает свойством полноты по Тьюрингу, то есть является универсальной моделью вычислений, которая может быть использована для моделирования любой одноленточной машины Тьюринга. Ее тезка, греческая буква лямбда (λ), используется в лямбда-выражениях и лямбда-условиях для обозначения связывания переменной с функцией. — Википедия

Лямбда-исчисление — удивительно простая, но мощная концепция. В основе лямбда-исчисления лежат два понятия:

  • Функциональная абстракция, использующаяся для обобщения выражений посредством введения имен (переменных)
  • Функциональное применение, которое используется для вычисления обобщенных выражений путем присвоения переданных имен к определенным значениям

В качестве примера давайте рассмотрим функцию f с одним аргументом, увеличивающую аргумент на единицу:

Допустим, мы хотим применить функцию к числу 5 . Тогда функцию можно читать следующим образом:

Основы функционального программирования

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

Функции первого класса

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

Затем мы легко можем вызвать эту функцию:

Функции высшего порядка

Функции высшего порядка — функции, принимающие одну или несколько функций в качестве аргументов и/или возвращающие новую функцию. Для демонстрации концепции давайте снова воспользуемся нашей функцией double :

В этом примере Enum.map в качестве первого аргумента принимает перечисляемый — список, а в качестве второго — функцию, которую мы только что определили. Затем Enum.map применяет функцию к каждому элементу списка. В результате мы получаем:

Неизменяемое состояние

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

Как и прежде, давайте воспользуемся Elixir для иллюстрации:

В примере выше наша переменная tuple никогда не изменит своего значения. В третьей строке put_elem возвращает совершенно новый tuple без изменения значения оригинала.

Я не буду продолжать вдаваться в подробности, потому что эта статья не является введением в лямбда-исчисление, теорию вычислений или даже функциональное программирование. Если вы хотите, чтобы я копал глубже по любой из этих тем, напишите об этом в разделе комментариев. На данный момент мы можем закрепить следующее:

  • Функциональное программирование существует уже давно (с начала 50-х годов)
  • Функциональное программирование основано на математических концепциях, в частности на лямбда-исчислениях
  • Функциональное программирование считалось слишком медленным по сравнению с императивными языками
  • Функциональное программирование возвращается

Применение функционального программирования

Как разработчики программного обеспечения мы живем в захватывающие времена, когда обещанные облачные вычисления наконец-то здесь и каждому из нас доступен беспрецедентный объем компьютерной мощности. К сожалению, с этим также пришли и требования масштабируемости, производительности и параллелизма.

Объектно-ориентированное программирование уже не справляется, особенно когда речь идет о конкурентности и параллелизме. Попытки добавить их к этим языкам, добавляют много сложностей и чаще всего приводят к чрезмерному усложнению и низкой производительности.

С другой стороны, функциональное программирование уже хорошо подходит для таких задач как: неизменяемое состояние, замыкания и функции высокого порядка — концепции, очень хорошо подходящие для написания высоконагруженных и распределенных приложений.

Читать еще:  Приложение без программирования

Но не надо верить мне на слово, вы можете найти достаточно доказательств, посмотрев на технологические новости стартапов, таких как WhatsApp и Discord:

  • 900 миллионов пользователей WhatsApp поддерживают всего лишь 50 инженеров, используя Erlang
  • Discord подобным образом обрабатывают более миллиона запросов в минуту с использованием Elixir

Эти компании и команды справляются с взрывным ростом благодаря преимуществам функционального программирования. А поскольку функциональное программирование приобретает все большую популярность, я твердо верю, что подобные истории будут встречаться чаще.

По этой причине функциональное программирование обязательно должно быть в арсенале знаний каждого разработчика. Вам необходимо быть готовым к созданию приложений следующего поколения, которые будут обслуживать следующий миллиард пользователей. И, черт возьми, если этого было недостаточно, поверьте мне, функциональное программирование — это действительно весело, просто взгляните на Elixir:

Языки функционального программирования: прошлое, настоящее и будущее

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

Clojure, Elixir, Elm, F#, Haskell, Idris и Scala — это те языки, которые чаще всего можно увидеть среди рекомендованных к изучению для функционального программирования (ФП). Им учатся сегодня и они еще долгие годы не растеряют своей популярности. Haskell — это наиболее ранний язык, но со временем более поздние, такие как Clojure, переплелись с ним, образуя общую картину эволюции ФП. Так какие же задачи решает этот отдельный класс языков программирования?

Что такое ФП

Согласно Википедии, функциональное программирование — раздел дискретной математики и парадигма программирования, в которой процесс вычисления трактуется как вычисление значений функций в математическом понимании последних (в отличие от функций как подпрограмм в процедурном программировании). Противопоставляется парадигме императивного программирования, которая описывает процесс вычислений как последовательное изменение состояний.

Термин «функциональное программирование» уходит корнями к способу программирования, который базируется на создании чистых функций. Основой всех языков ФП является лямбда-исчисление (Lambda Calculus, также обозначается как λ-исчисление), которое описывается как «самый маленький универсальный язык программирования в мире». Соответственно, ФП состоит из математических функций, которым для проведения вычислений требуются условные выражения и рекурсия.

ФП характеризуют следующие особенности:

  • неизменяемость данных;
  • применение чистых функций в качестве неделимых единиц композиции, с избеганием общего изменяемого состояния и побочных эффектов вне вызываемой функции;
  • ФП проще в том смысле, что разработчику не нужно беспокоится о случайном изменении переменной вне данной функции;
  • ссылочная прозрачность. Эта особенность позволяет заменить выражение соответствующим значением без изменения поведения программы;
  • модульная конструкция позволяет создавать небольшие модули и новые надстройки на их основе, что способствует более быстрой разработке программ. Отладка модулей может производиться отдельно, что сокращает время, затрачиваемое на тестирование и отладку.

ФП состоит из математических функций

ФП основано на Lambda Calculus. Разработка концепции принадлежит авторству Алонза Черча, она появилась на свет в 1936 г., но поскольку в те далекие времена компьютеров не существовало, она носила чисто теоретический характер. Так было до 1960 г., когда американский ученый-компьютерщик Джон Маккарти опубликовал работу «Рекурсивные функции символьных выражений и их вычисление на машине». В результате его исследования появился первый язык ФП: LISP. У LISP имеются ответвления, в том числе Common Lisp, Scheme и elisp, а также Clojure, последний пользуется большой популярностью и в наше время.

Как уже говорилось, базовые принципы программирования LISP заложили основу современного ФП. Вот некоторые из них:

  • применение замыканий для реализации статической области видимости. Например, функция f в выражении let x = 3 in f = λ y. x + y не является закрытой, поскольку имеет свободную переменную x. Для того, чтобы задействовать ее, она должна быть связана со средой, которая сообщает значение x. Функция, в теле которой присутствуют ссылки на переменные, объявленные вне тела этой функции в окружающем коде и не являющиеся ее параметрами, называется замыканием;
  • условное выражение и его использование для написания рекурсивных функций. Этот принцип связан с «ленивым» порядком вычисления выражений;
  • применение высокоуровневых операций в списке, такие как функция mapcar.

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

Спустя почти два десятилетия, в 1978-м, в развитии ФП состоялся новый прорыв. Исследователи из Эдинбургского университета изобрели метаязык (Metalanguage), который предназначался для работы с их автоматической системой доказательства теорем (LCF). Как позже выяснилось, его можно применять в качестве языка программирования общего назначения. Метаязык имеет две версии: Standard ML of New Jersey (бесплатный компилятор с открытым кодом и среда программирования для языка программирования Standard ML) и CAML. Эдинбург преподнес ФП еще один подарок — язык Hope. Источником названия послужил Hope Park Square, где находился Эдинбургский отдел компьютерных наук. Hope — первый язык, использующий вызов по шаблону.

Язык Haskell был назван в честь логика Хаскелла Карри. Формулирование стандартов и задач языка состоялось в 1987 г. в ходе конференции по функциональным языкам программирования и компьютерной архитектуре в Орегоне. Первая версия Haskell 1.0 появилась в 1990 г. Версия языка Haskell 2010 была объявлена в конце 2009 г., в 2020 г. ожидается выход новой версии. Haskell стал парадигмой современных функциональных языков, отличающихся от других видов языков функциями высшего порядка, выводом типов, «ленивым» порядком вычислений и пользовательскими типами данных.

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

В 2009 г. сформировалась концепция Haskell Platform — стандартного дистрибутива языка, включающего кроме компилятора (GHC), также дополнительный инструментарий (систему сборки и развертывания пакетов Cabal) и набор популярных библиотек. Сейчас Haskell Platform — это рекомендованный базовый дистрибутив для разработчиков. Готовые сборки Haskell Platform доступны для Windows, MacOS X и ряда дистрибутивов Linux.

Основные современные языки ФП

Haskell — наиболее известный среди языков ФП. Вероятно, это связано с его богатой историей. Он также повлиял на развитие других языков. «Такие вещи, как Linq, язык запросов в C#, на самом деле произошли от Haskell. Рабочие процессы F# и изменяемые состояния взяты непосредственно из его монадической структуры», — сказал главный исследователь Microsoft и ключевой контрибутор Haskell Саймон Пейтон Джонс.

Clojure — новый диалект LISP, созданный Ричем Хикки. Clojure отличается от других диалектов LISP тем, что он работает на платформе Java и компилируется в байт-код JVM, за счет чего программы на Clojure легко переносятся в любую среду с JVM. Язык также поддерживает ряд макросов, которые упрощают использование в нем существующих Java API. Структуры данных Clojure реализуют все стандартные интерфейсы Java, что делает легким запуск из Java программного кода, написанного на Clojure.

«Clojure обеспечивает легкий доступ к фреймворкам Java, с дополнительными подсказками и логикой типа, чтобы гарантировать, что вызовы Java могут избежать отражения», — объясняет Хикки. Он также говорит, что «подход Lisp к коду как данным и его макросистеме по-прежнему отличает его» от других диалектов Lisp и добавляет, что как и списки в Lisp, его карты, множества и векторы являются в Clojure первым классом. «Я думаю, что Clojure занимает уникальную нишу в качестве функционального Lisp для JVM с сильной поддержкой параллелизма», — добавил Хикки.

Elm — чисто функциональный язык, разработанный в 2012 г. Эваном Чаплицким. Он популярен среди веб-разработчиков, которым нравятся его возможности для создания пользовательских интерфейсов. Компилятор Elm предназначен для HTML, CSS и JavaScript. Он работает с библиотеками JavaScript почти так же, как Clojure — с библиотеками Java. Отличительной особенностью Elm является то, что он использует статическую проверку типов, которая помогает в устранении исключений во время выполнения, поскольку ошибки будут обнаружены на стадии компиляции. Отсутствие видимых ошибок на стороне пользователя — очевидное преимуществом этого языка.

Elixir — динамический функциональный язык, предназначенный для построения масштабируемых и обслуживаемых приложений. Он служит для создания систем с высокой доступностью и низкой задержкой. Elixir работает на базе экосистемы Erlang VM. Она востребована Heroku, WhatsApp, Klarna и другими проектами для распределенных, отказоустойчивых приложений. Каждый элемент приложений является выражением, функции языка Erlang могут быть вызваны без влияния на время исполнения из-за компиляции байт-кода в Erlang и наоборот.

F# — кроссплатформенный функциональный язык программирования с открытым кодом. Его разработку курирует F# Software Foundation. F# работает на Linux, Mac OS X, Android, iOS, Windows, графических процессорах и браузерах. Его можно применять свободно, он является языком с открытым исходным кодом и распространяется на условиях лицензии, одобренной OSI. F# затребован в широком спектре областей применения и активно поддерживается как со стороны сообщества Open Source, так и ведущими отраслевыми компаниями, предоставляющими профессиональные инструменты.

Читать еще:  Среда программирования визуал бейсик

Idris — чисто функциональный язык программирования общего назначения, который включает особенности Haskell и метаязыка. Он характеризуется зависимыми типами, основанными на значениях, поэтому некоторые аспекты поведения программы могут быть точно определены в типе. Также реализована возможность компиляции в код на JavaScript (в том числе для Node.js) и компилирование по принципу «энергичных» вычислений (вычислять, не откладывая, все что возможно). Idris поддерживает два способа работы с системой автоматического доказательства: путем написания последовательных вызовов тактик (стиль Coq, при этом набор доступных тактик не столь богат, как в Coq, но может быть расширен штатными средствами метапрограммирования) или посредством пошаговой разработки доказательства (стиль Epigram и Agda).

JavaScript не является строго функциональным языком программирования, поскольку допускает объектно-ориентированный подход, однако у него есть компонент, который связывает его с ФП. Он включает в себя функции высшего порядка. Кроме того, новые версии стандарта ECMAScript предоставляют исправления для проблемы изменчивости.

Kotlin относится к числу новейших языков программирования. Он вышел в феврале 2016 г., но до этого в течении пяти лет проходил тестирование и активно дорабатывался. Его используют такие компании, как Amex, NBC Digital, Expedia и Gradle, но это не чисто функциональный язык. В этом отношении Kotlin можно сравнить с JavaScript, то есть с его помощью можно создавать как объектно-ориентированные, так и функциональные конструкции. Он обладает полной совместимостью с Java. К числу преимуществ Kotlin нужно отнести его лаконичность, в этом плане он более гибкий, чем Java.

Некоторые программисты считают, что он передает те же выражения, что и Java, но при этом ему требуется на треть меньше кода. Kotlin также предлагает все преимущества, связанные с функциональными языками программирования, включая функции высшего порядка, функции расширения и лямбда-выражения. Универсальность делает его подходящим для любого вида разработки, будь то серверные, клиентские веб-приложения или Android, и сейчас его создатели работают над совместимостью языка с iOS.

Scala — еще один гибридный язык, который можно применять как для объектно-ориентированного программирования, так и ФП. Статические типы Scala помогают избежать ошибок в сложных приложениях, а его среды выполнения JVM и JavaScript позволяют создавать высокопроизводительные системы с легким доступом к огромным экосистемам библиотек.

Главный специалист Telstra по аналитике больших данных Марк Молони считает, что программистам нужно обратить более пристальное внимание на функциональные языки программирования и заняться их изучением: «ФП окружает миф о его сложности или академичности, но я рассматриваю его как еще один источник информации для изучения. Чтобы освоить ФП, нужно время и практика, но этот путь ничем не отличается от того, который в конце 1980-х — начале 1990-х прошли разработчики для изучения объектно-ориентированного программирования. Технология продолжает развиваться. Это одна из причин, почему я люблю ПО. Важно уметь учиться, это равноценно тем знаниям, что у вас уже есть».

Функциональное программирование с примерами на JavaScript. Часть первая. Основные техники функционального программирования

    Переводы, 2 декабря 2016 в 22:24

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

В первой части вы изучите основы ФП, такие как каррирование, чистые функции, fantasy-land, функторы, монады, Maybe-монады и Either-монады на нескольких примерах.

Функциональное программирование — это стиль написания программ через составление набора функций.

Основной принцип ФП — оборачивать практически все в функции, писать множество маленьких многоразовых функций, а затем просто вызывать их одну за другой, чтобы получить результат вроде (func1.func2.func3) или в композиционном стиле func1(func2(func3())) .

Кроме этого, структура функций должна следовать некоторым правилам, описанным ниже.

Ивент перенесён, есть новые даты ( 16 – 17 июня ) , Санкт-Петербург, 10 750–138 000 ₽

Итак, у вас могло возникнуть несколько вопросов. Если любую задачу можно решить, объединяя вызовы нескольких функций, то:

  1. Как реализовать условия (if-else)? (Совет: используйте монаду Either);
  2. Как перехватить исключения типа Null Exception? (В этом может помочь монада Maybe);
  3. Как убедиться в том, что функция действительно “многоразовая” и может использоваться в любом месте? (Чистые функции);
  4. Как убедиться, что данные, которые мы передаем, не изменяются, чтобы мы могли бы использовать их где-то еще? (Чистые функции, иммутабельность);
  5. Если функция принимает несколько значений, но цепочка может передавать только одно значение, как мы можем сделать эту функцию частью цепочки? (Каррирование и функциивысшегопорядка).

Чтобы решить все эти проблемы, функциональные языки, вроде Haskell, предоставляют инструменты и решения из математики, такие как монады, функторы и т.д., из коробки.

Хотя в JavaScript эти инструменты не встроены, к счастью, у него достаточно преимуществ, позволяющих людям реализовывать недостающие функции в собственных библиотеках.

Спецификация Fantasy-Land и библиотеки ФП

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

Fantasy-Land — одна из таких спецификаций, в которой описано, как должна действовать та или иная функция или класс в JS.

На рисунке выше показаны все спецификации и их зависимости. Спецификации — это, по существу, описания функционала, подобные интерфейсам в Java. С точки зрения JS вы можете думать о спецификациях, как о классах или функциях-конструкторах, которые реализовывают некоторые методы ( map , of , chain ), следуя спецификации.

Например, класс в JavaScript является функтором, если он реализует метод map . Метод map должен работать, следуя спецификации.

По аналогии, класс в JS является аппликативным функтором, если он реализует функции map и ap .

JS-класс — монада, если он реализует функции, требуемые функтором, аппликативным функтором, цепочкой и самой монадой.

Библиотеки, следующие спецификациям Fantasy-Land

Какие же из них мне использовать?

Такие библиотеки, как lodash-fp и ramdajs, позволяют вам начать программировать в функциональном стиле. Но они не реализуют функции, позволяющие использовать ключевые математические концепты (монады, функторы, свертки), а без них невозможно решать некоторые из реальных задач в функциональном стиле.

Так что в дополнение к ним вы должны использовать одну из библиотек, следующих спецификациям FL.

Теперь, когда мы знаем основы, давайте посмотрим на несколько практических примеров и изучим на них некоторые из возможностей и техник функционального программирования.

Пример 1: справляемся с проверкой на NULL

Тема покрывает: функторы, монады, Maybe-монады и каррирование.

Сценарий использования: Мы хотим показать различные стартовые страницы в зависимости от языка, выбранного пользователем в настройках. В данном примере мы реализовываем функцию getUrlForUser, которая возвращает правильный URL из списка indexURLs для испанского языка, выбранного пользователем joeUser.

Проблема: язык может быть не выбран, то есть равняться null. Также сам пользователь может быть не залогинен и равняться null. Выбранный язык может быть не доступен в нашем списке indexURLs. Так что мы должны позаботиться о нескольких случаях, при которых значение null или undefined может вызвать ошибку.

Решение (Императивное против Функционального):

Не беспокойтесь, если функциональное решение пока вам не понятно, я объясню его шаг за шагом немного позже.

Давайте для начала попробуем понять некоторые из концептов ФП, которые были использованы в этом решении.

Функторы

Любой класс или тип данных, который хранит значение и реализует метод map , называется функтором.

Например, Array — это функтор, потому что массив хранит значения и реализует метод map , позволяющий нам применять функцию к значениям, которые он хранит.

Давайте напишем свой собственный функтор “MyFunctor”. Это просто JS-класс (функция-конструктор). Метод map применяет функцию к хранимым значениям и возвращает новый экземпляр MyFunctor.

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

Монады

Монады — это подтип функторов, так как у них есть метод map , но они также реализуют другие методы, например, ap , of , chain .

Ниже представлена простая реализация монады.

Обычные монады используются нечасто, в отличие от более специфичных монад, таких как “монада Maybe” и “монада Either“.

“Maybe”-монада

Монада “Maybe” — это класс, который имплементирует спецификацию монады. Её особенность заключается в том, что с помощью нее можно решать проблемы с null и undefined.

В частности, в случае, если данные равны null или undefined, функция map пропускает их.

Код, представленный ниже, показывает имплементацию Maybe-монады в библиотеке ramda-fantasy. Она возвращает экземпляр одного из двух подклассов: Just или Nothing, в зависимости от значения.

Классы Just и Nothing содержат одинаковые методы ( map , orElse и т.д.). Отличие между ними в реализации этих самых методов.

Обратите особое внимание на функции “map” и “orElse”.

Давайте поймем, как Maybe-монада осуществляет проверку на null.

  1. Если есть объект, который может равняться null или иметь нулевые свойства, создаем экземпляр монады из него.
  2. Используем библиотеки, вроде ramdajs, чтобы получить значение из монады и работать с ним.
  3. Возвращаем значение по умолчанию, если данные равняются null.
Читать еще:  Что такое язык программирования c

Каррирование

Освещенные темы: чистые функции и композиция.

Если мы хотим создавать серии вызовов функций, как то func1.func2.func3 или (func1(func2(func3())) , все эти функции должны принимать только один параметр. Например, если func2 принимает два параметра (func2(param1, param2)) , мы не сможем включить её в серию.

Но с практической точки зрения многие функции могут принимать несколько параметров. Так как же нам создавать из них цепочки? Ответ: С помощью каррирования.

Каррирование превращает функцию, которая принимает несколько параметров в функцию, которая принимает только один параметр за один раз. Функция не запустится, пока все параметры не будут переданы.

В дополнение, каррирование может быть также использовано в ситуациях, когда мы обращаемся к глобальным значениям.

Давайте снова взглянем на наше решение:

Пример 2: обработка функций, бросающих исключения и выход сразу после ошибки

Освещенные темы: Монада “Either”

Монада Maybe подходит нам, чтобы обработать ошибки, связанные с null и undefined. Но что делать с функциями, которым требуется выбрасывать исключения? И как определить, какая из функций в цепочке вызвала ошибку, когда в серии несколько функций, бросающих исключения?

Например, если func2 из цепочки func1.func2.func3. выбросила исключение, мы должны пропустить вызов func3 и последующие функции и корректно обработать ошибку.

Монада Either

Монада Either превосходно подойдет для подобной ситуации.

Пример использования: В примере ниже мы рассчитываем “tax” и “discont” для “items” и в конечном счете вызываем showTotalPrice.

Заметьте, что функции “tax” и “discount” выбросят исключение, если в качестве цены передано не числовое значение. Функция “discount”, помимо этого, вернет ошибку в случае, если цена меньше 10.

Давайте посмотрим, как можно реализовать этот пример в функциональном стиле, используя монаду Either.

Either-монада предоставляет два конструктора: “Either.Left” и “Either.Right“. Думайте о них, как о подклассах Either. И “Left“, и “Right” тоже являются монадами. Идея в том, чтобы хранить ошибки или исключения в Left и полезные значения в Right.

Экземпляры Either.Left или Either.Right создаются в зависимости от значения функции.

Так давайте же посмотрим, как изменить наш императивный пример на функциональный.

Шаг 1: Оберните возвращаемые значения в Left и Right. “Оборачивание” означает создание экземпляра класса с помощью оператора new.

Шаг 2: Оберните исходное значение в Right, так как оно валидно.

Шаг 3: Создайте две функции: одну для обработки ошибок, а другую для отображения результата. Оберните их в Either.either (из библиотеки ramda-fantasy.js).

Either.either принимает 3 параметра: обработчик успешного завершения, обработчик ошибок и монаду Either. Сейчас мы можем передать только обработчики, а третий параметр, Either, передать позже.

Как только Either.either получит все три параметра, она передаст третий параметр в обработчик успешного завершения или обработчик ошибок, в зависимости от типа монады: Left или Right.

Шаг 4: Используйте метод chain, чтобы создать цепочку из нескольких функций, выбрасывающих исключения. Передайте результат их выполнения в Either.either (eitherLogOrShow).

Все вместе выглядит следующим образом:

В следующей части мы рассмотрим аппликативные функторы, curryN и Validation Applicative.

Функциональное программирование Язык программирования F#.NET. — презентация

Презентация была опубликована 6 лет назад пользователемГерасим Русанов

Похожие презентации

Презентация на тему: » Функциональное программирование Язык программирования F#.NET.» — Транскрипт:

1 Функциональное программирование Язык программирования F#.NET

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

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

4 Основные свойства функциональных языков Краткость и простота Функции — это значения Чистота (отсутствие побочных эффектов)

5 Краткость и простота Программы на функциональных языках обычно намного короче и проще, чем те же самые программы на императивных языках

6 Функции — это значения В функциональных языках функции могут быть переданы другим функциям в качестве аргумента или возвращены в качестве результата. Функции, принимающие функциональные аргументы, называются функциями высших порядков или функционалами. Самый, пожалуй, известный функционал, это map. map применяет некоторую функцию ко всем элементам списка, формируя из результатов другой список. Например определив функцию возведения целого числа в квадрат как: square :: Int -> Int square n = n * n Mожем воспользоваться этой функцией для возведения в квадрат всех элементов списка l2 = map square [1, 2, 3, 4] — результат — список [1, 4, 9, 16] Int square n = n * n Mожем воспользоваться этой функцией для возведения в квадрат всех элементов списка l2 = map square [1, 2, 3, 4] — результат — список [1, 4, 9, 16]»>

7 Чистота (отсутствие побочных эффектов) В императивных языках функция в процессе своего выполнения может читать и модифицировать значения глобальных переменных и осуществлять ввод/вывод. Поэтому, если мы вызовем одну и ту же функцию дважды с одним и тем же аргументом, может случиться так, что мы получим два различных результата. Такая функция называется функцией с побочными эффектами. В чистом функциональном программировании оператор присваивания отсутствует, объекты нельзя изменять и уничтожать, можно только создавать новые путем декомпозиции и синтеза существующих. О ненужных объектах позаботится встроенный в язык сборщик мусора. Благодаря этому в чистых функциональных языках все функции свободны от побочных эффектов. Однако это не мешает этим языкам имитировать некоторые полезные императивные свойства, такие как исключения и изменяемые массивы. Для этого существуют специальные методы.

8 Язык программирования F#.NET F# это язык программирования, обеспечивающий поддержку функционального программирования, а также объектно- ориентированного и императивного (процедурного) программирования. Распространяется вместе с.NET Framework и Visual Studio как часть Visual Studio 2010.

9 Основные свойства F# мультипарадигменный язык программирования. В нем можно писать функциональный, императивный и объектно-ориентированный код. F# использует вывод типов, что приводит к более лаконичным программам. Лаконичность- самая сильная сторона этого языка. F# это.NET-язык программирования. Он компилируется в IL в том же рабочем цикле что и C# с VB и будет запросто работать с уже существующим.NET-кодом. F# хорош в многопоточном программировании, если быть точнее: в параллельном, асинхронном, конкурентном и реагирующем доменах программирования.

10 Одна и та же задача выполнена в C# и в F#

[] | h::t -> quicksort ([ for x in t when x x]) @ [h] @ quicksort ([ for x in t when x>h -> x]);;» title=»Метод сортировки Хоара на F# let rec quicksort = function [] -> [] | h::t -> quicksort ([ for x in t when x x]) @ [h] @ quicksort ([ for x in t when x>h -> x]);;» class=»link_thumb»> 12 Метод сортировки Хоара на F# let rec quicksort = function [] -> [] | h::t -> quicksort ([ for x in t when x quicksort ([ for x in t when x>h -> x]);; [] | h::t -> quicksort ([ for x in t when x x]) @ [h] @ quicksort ([ for x in t when x>h -> x]);;»> [] | h::t -> quicksort ([ for x in t when x x]) @ [h] @ quicksort ([ for x in t when x>h -> x]);;»> [] | h::t -> quicksort ([ for x in t when x x]) @ [h] @ quicksort ([ for x in t when x>h -> x]);;» title=»Метод сортировки Хоара на F# let rec quicksort = function [] -> [] | h::t -> quicksort ([ for x in t when x x]) @ [h] @ quicksort ([ for x in t when x>h -> x]);;»>

13 Области применения Первая область, в которой F# в самом деле непревзойден это техническое и количественное программирование, т.е. в сложных математических расчетах. Симуляция одна из областей, которой F# хорошо подходит. Представьте, что вы пишете какого-то рода физический симулятор, или пытаетесь смоделировать некоторую реалистичную ситуацию. В F# вы можете аккуратно написать функции, которые вам требуются, без необходимости притягивать абстракции кода к процессам реального мира. Вычислительные финансы. Позволяет создавать финансовые модели в более простом и декларативном виде, но также интегрироваться с остальным набором приложений предприятия, через.NET взаимодействие. Обработка крупномасштабных данных

14 Заключение Если вам кажется, что ваш язык не позволяет в полной мере выразить вам свои идеи, засоряет ваш код ненужным синтаксическим мусором, в котором теряется смысл, попробуйте F#. В областях, связанных с большим количеством вычислений или преобразований данных – техническом программировании, ЯОП, параллельном/асинхронном – вы можете получить существенную пользу. Написание кода на F# не сделает ваши программы, словно по мановению волшебной палочки, быстрее или менее ресурсоёмкими. Все, что он делает – предоставляет вам возможность посмотреть на задачу с другой стороны, с которой её решение может получиться более эффективным, и просто увеличивает количество путей для выражения ваших идей.

Ссылка на основную публикацию
Adblock
detector