Зачем изучать непопулярные языки. Пример сообщества F#



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

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

    Я попытался узнать, в чем причина. И вообще — кто те люди, которые на нем пишут, и зачем они это делают, если язык не нужен бизнесу? Для этого я постучался поговорить в русскоязычное сообщество F# в «Телеграме». Здесь — наш круглый стол.

    С чего начали изучать F#


    Айрат Худайгулов (Szer): Я сам выходец из C#. Была у нас работа связанная с Akka.NET, которая портирована с Akka на Scala. Порт отличный, но к редким кейсам документации не было примеров, они всегда были в Scala-доке. Когда я читал эту доку, в голову лезли одни вопросы — почему в Scala всё записывается в пару строчек, а я страдаю на C#?

    Выход был найден — F#. С тех пор и не слез.

    Роман Лиман (kagetoki): Оказалось — это мощный инструмент для решения вполне реальных будничных проблем любого программиста. Те трудности, что считалось нормой и неизбежностью в ООП мире C# и Java, неизбежными вовсе не являются, и их можно легко предотвратить вместо того, чтобы превозмогать.

    Фил Ранжин (fillpackart): Как-то на Хабре я прочитал большое интервью с Вагифом Абиловым. На тот момент я совсем не понимал функциональной парадигмы программирования, и любая информация о ней меня серьёзно раздражала. Так и то интервью.

    Вагиф Абилов (VagifAbilov): Тот материал можно почитать здесь. Это было вскоре после моего выступления на московской конференции DotNext. Если в двух словах, то я начал изучать F# из желания писать более компактный код (меньше кода — меньше зла) и работать с неизменяемыми структурами данных. Конечно, никто не мешает программисту на C# или Java определять свои структуры данных как неизменяемые, но в основе языков, реализующих ООП, лежит возможность мутаций структур данных, и эта возможность никуда из этих языков не уйдет. Функциональное программирование позволяет не тратить усилия на защиту данных от некорректного изменения в многопоточной среде — данные сами о себе позаботятся, они неизменяемы.

    Фил Ранжин: Вагиф всё говорил, что после церемониальных C# и Java, F# казался чем-то намного более подходящим для разработки. Я тогда не знал, кто такой Вагиф, но, естественно, сразу решил для себя, что ничего он не понимает. C# не церемониальный, C# именно такой, какой и должен быть. Мощный и красивый. Решил написать статью про то, какое всё-таки функциональное программирование нелепое. Взял простую задачу, и стал имплементить её на C# и F#, чтобы проиллюстрировать свою правоту. F# в процессе мне зашёл настолько, что статью я дописывать не стал. Я стал изучать эту технологию.

    Роман Лиман: Многие вещи, которые в C# проверяются в рантайме, теперь перекочевали в компайл-тайм, так что ощущения словно впервые попробовал статическую типизацию — прям откровение снизошло.

    Там, где на F# вам понадобится семь строк кода, на C# эквивалентный код развернется на 200–300, без преувеличения (и это считая только полезный код). Компилятор сам генерирует кучу бойлерплейта за вас, например, structural equality.

    Фил Ранжин: Я ещё ни разу не дебажил F# код, потому что в моём F# коде все баги ловятся на этапе компиляции. Я не шучу.

    Тяжело ли изучать F#


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

    Синтаксис поначалу не очевиден, так что браваду лучше оставить в стороне и почитать про язык, а не надеяться, что знаний C# хватит с головой.

    Айрат Худайгулов: F# поддерживает всё, что есть в C# кроме goto (язык полностью expression-based, сделать императивный переход в вычисляемом выражении было бы странно) и ключевого слова protected (это by design, т.к. сделать его очевидно несложно). Всё остальное, любимое нами ООП — абстрактные классы, интерфейсы, авто проперти, юзинги, трай-кетчи — конечно есть. Для любителей посчитать байты тоже всё есть: ref/out параметры, мутабельность, спаны, unmanaged, pointers, stackalloc.

    Все фичи в C# приходят с лагом в пару лет по сравнению с F# (дженерики, async/await + task, LINQ, паттерн матчинг и многое другое). А многие фичи вообще сомневаюсь, что когда-либо заедут (sum types в лице discriminated unions, нативный function currying). В свежий C# 8.0 обещают завезти рекорды и рекурсивный паттерн матчинг. Внимание вопрос — зачем ждать?

    И другой вопрос: а зачем учить новый язык чтобы писать на нём точно так же? Чтобы получать преимущества которые даёт F#, но не даёт C#, придётся понять и другую сторону Силы. И это непросто.

    Джон Доу: Как C# девелопер благодарен создателям F# за дженерики и асинхронность с человеческим лицом в C#. Если кто не знает, эти мегафичи появились в C# благодаря F#.

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

    Многие вообще слишком носятся с языками программирования, как жизненным кредо. Если перешел с Java на Clojure, порой отнесутся, как если бы христианин принял ислам. Почему, собственно, такое внимание? Изучение новых языков программирования зачастую позволяет переосмыслить наши привычки работы со старыми языками. Познакомившиеся с F# пишут на C# по-другому.

    Роман Мельников (neftedollar): В F# ООП правильнее (хотя полностью совместимо с ООП в C#) т.к. подталкивает программировать на абстракциях-интерфейсах, вместо явных классов.

    Что думают про создателей языка


    Николай Матюшин: Однажды я поспособствовал поддержке тайп провайдеров на .NET Core. Довольно долгое время они не работали, и мы с одним человеком из русскоязычного сообщества решили разобраться, в чём беда. Поковырялись, увидели, что в .NET Core нет функции, которая сохраняет assembly (объект) в файл — эта функция использовалась провайдерами.

    Мы потратили одну или две недели на прототип, который это делал. Получился жуткий костыль, но частично работающий. Всё это время общались в issue на гитхабе, а потом пришёл Дон Сайм, написал «Few hours of work», и починил тайп провайдеры.

    Вагиф Абилов: Создатель языка Дон Сайм доступен и демократичен. Надеюсь, он доедет до какой-нибудь российской конференции, чтобы российские разработчики смогли с ним познакомиться лично.

    Роман Лиман: Сайм — гений. Поразительно, но он создал всю эту красоту чуть ли не в одиночку.

    Павел Смирнов: Он мой программистский кумир.

    Айрат Худайгулов: Дон Сайм между прочим впилил дженерики в .NET, иначе сидели бы мы на C# и хардкастили всё из object и обратно, как это было (и частично есть) в Java. Сайм развивает язык с оглядкой на C#, на совместимость с его новыми фичами, что наверное стратегически правильно. Но это означает что отголосок плохих решений в С# может попасть и в F#. Также он против введения «заумных» ФП-фич (привет Scala), и переусложения языка, т.к. они могут отпугнуть других людей и раздуть стандартную либу (привет C++).

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

    Почему язык не популярен


    Роман Лиман: Язык не популярен, на мой взгляд, потому что в целом ФП менее популярно, чем ООП. Плюс, есть порог вхождения. А дальше — уловка 22. Проекты на F# не пишут, потому что программистов на рынке мало, а программисты не учат этот язык, потому что проектов на рынке нет.

    Фил Ранжин: Я не знаю людей, которые практиковали бы функциональное программирование, но предпочитали бы объектно-ориентированное. Тут F# особенно не повезло — он подходит только тем, кто верит в симбиоз этих парадигм.

    Павел Смирнов: Многие считали его мертворождённым из-за политики Microsoft — F# был всего лишь площадкой для обыгрывания фичей для C#. Но язык изначально позиционировался скорее для data science, чем для промышленной разработки.

    Роман Мельников: Решарпер. Для C# это важная тема, и многие уже на него потратились. Без решарпера на C# писать больновато, нужно много ручками прописывать, типа подсветки аллокаций. И решарпер убирает кучу боли сишарперов. В F# этой боли нет, но те, у кого есть решарпер, не могут оценить все прелести языка, не полагающегося на тулинг.

    Вагиф Абилов: На мой взгляд, причина отставания от успехов Scala лежит в доминировании Майкрософт, которая по-прежнему определяет, что является приоритетным на платформе Windows. При том, что F# разработан в Microsoft Research, он всегда позиционировался компанией как язык для энтузиастов. У Майкрософт есть метрики, показывающие экономическую обоснованность развития той или иной технологии в зависимости от текущих продаж, и разумеется, какой-нибудь SharePoint согласно этим метрикам выглядит более привлекательным, чем F#. Но капля камень точит.

    Фил Ранжин: Я верю, что он выстрелит. Вся мощь .NET в паре с самым современным синтаксисом и самым идиоматичным подходом в истории не могут не выстрелить.

    Роман Мельников: Перспективы потрясающие. F# постепенно заходит в анализ данных, благодаря провайдерам типов, например. Есть компиляторы в js и волшебная библиотека elmish (по сути Elm для .NET).

    Мигель Де Иказа активно поддерживает F#, и в Xamarin его поддержка всегда была как у C#. Есть компилятор в ErlangCore, что тоже дико круто. На F# можно писать полностью бэкенд и фронтенд. SAFE-Stack чумовая вещь, с типизированными вызовами api, крутыми обертками поверх вебсокетов (Elmish.Bridge) и кучей еще всего.

    Вагиф Абилов: Очень радует, что удается применять F#. Я работаю в проекте норвежского телерадиовещания, наша система закачивает в “облако” медиафайлы телевизионных и радиопрограмм, чтобы сделать их доступными для просмотра и прослушивания с компьютеров и мобильных устройств. Система написана на F# и использует Akka.NET. Это не единственный проект в нашей организации, где используется F#, и что особенно радует, это что число таких проектов растет, как и число разработчиков, готовых перейти на этот язык.

    Для чего подходит F#


    Фил Ранжин: F# идеально ложится на разработку ИИ. Этот язык буквально сделан, чтобы абстрагировать меня от сложностей и сосредоточиться на главном. Когда делаешь ИИ, твоя задача отмапить свой образ мышления на поведение машины. В таких кейсах код — ваш промежуточный язык, который не способен выразить слишком сложные вещи. Вот F# способен быть настолько абстрактным, что бы не мешать тебе и твоей машине творить историю.

    Вагиф Абилов: Он применим к любым задачам, а ложится особенно хорошо на задачи доменного моделирования. В прошлогоднем интервью на Хабре я неосмотрительно сказал, что функциональные языки в большей степени применимы к алгоритмам и бэкенду, и в меньшей — к программированию интерфейса пользователя и веб-страниц.

    Мне тогда в комментариях кто-то заметил, что есть такой функциональный язык Elm, который специально написан для программирования веб-страниц. Комментатор был совершенно прав. Я с тех пор начался пользоваться Fable, который позволяет писать веб-аппликации на F#, компилируя их в JavaScript. Потрясающие впечатления, комбинация F# + Fable (и еще библиотека Fable-Elmish) открывают доступ к веб-программированию для таких ничего не понимающих в CSS разработчиков, как я.

    Павел Сирнов: Data driven development — лаконичный ФП язык, поддерживающий Type Providers. Actor model — MailboxProcessor в стандартной библиотеке это сказка.

    Роман Мельников: Отлично решает задачи веба, интегрируется с react-компонентами. Решаются задачи анализа данных и машинного обучения (fslab.org), задачи ETL, задачи по проектированию бизнес логики — система типов позволяет писать так, чтоб неправильных состояний не было.
    Потрясающе решаются задачи парсинга (Fparsec). Отлично подходит для написания своих языков. Тот же TypeScript изначально был написан на F#. Пишется код для GPU.
    Сам я пишу на нем скрипты fsx вместо баш и пайтона для свой машины.

    Да, под микроконтроллеры на нем не попишешь. Но думаю достаточно многие люди могут и без этого обойтись.

    Где брать информацию


    Книги



    Интернет



    Телеграм


    • fsharp_news
    • fsharp_chat

    Пара слов о сообществе


    Роман Лиман: Сообщество классное, всех объединяет желание писать на F# за деньги, поэтому всем новичкам сильно помогают, чтобы увеличить коммьюнити, повысив шансы найти работу.

    Фил Ранжин: Опасные сектанты. Но они правы.

    Павел Смирнов: Русскоязычное сообщество F# весьма уютное место. Больше всего нравится, что они неравнодушны к своему языку, также как это бывает в других более известных экосистемах.

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

    Роман Мельников: Бывают свои драмы не влияющие на язык. Но жизнь делают интереснее.
    Поделиться публикацией

    Похожие публикации

    Комментарии 163
      0
      Простите, а где ответ на вопрос «зачем?» из заголовка статьи? Почему стоит тратить время и силы именно на F#?
        0
        Представьте что вам один год, ваша бабушка подводит вас к входной двери, открывает её и говорит — иди чувачок, куда глаза глядят и делай что хочешь. Странно и главное дико! Но представьте, что ещё более дико, когда вам за 40, а бабушка вам вытирает носик, и говорит что вы не спешили, а то через порог бубухнетесь и будет бобо.

        Вот тоже самое и с F#. Он дает полную свободу, которой не хватает взрослым-сформировавшимся и которая может навредить молодым-неокрепшим разработчикам. Единственное нужно понимать, что синтаксис современных ооп языков в большей степени впитал функциональные возможности. Но их недостаток заключается в слишком слабом определении типов. Объявил класс-интерфейс, вот и тип. В фп языках, существует возможность конструировать типы. Это полностью закрывает все проблемы, которые возникают из-за совместимости типов в других языках. Вы можете строить типы так, что уйдет потребность в приведении вообще, программа сама будет все типы выводить.
          0
          Я правильно вас понимаю, что конструирование типов — это основной (главный) плюс F# и это то, ради чего его стоит изучать?
            +5
            Уже отвечал в других местах, но повторюсь, что являлось главным для меня:
            — immutability by default, т.е. по умолчанию никакие структуры данных нельзя мутировать.
            — type inference, автоматический вывод типов. Вообще сильная типизация позволила мне вытаскивать ошибки кода в основном при компиляции, в C# я на все тесты писал.
            — discriminated union для доменного моделирования. Компактно и читабельно.
            0
            Представьте самый вкусный в мире торт, рецепт которого, лучшие мастера, выводили на протяжении десятков лет. Нет, F# это не торт, F# это всего-лишь ингредиенты-парадигмы, которые приготовлены по рецепту новейшей системы типов. То есть, возможности системы типов и есть торт. Это будущие уже сегодня. Это как c#после assembly. А о остальном и говорить не стоит. Сама фппарадигма присутствует и в ооп, который от части структурная парадигма. Все эти парадигмы в свое время были революционными и каждая новая поглощала лучшее из предыдущих. И о них не стоит говорить. Говорить стоит о мощнейших возможностях конструирования типов. Они изменяют подход к разработке по всем направлениям. Перечислять отличия просто бессмысленно, все не вспомнишь.

            Но я бы не рекомендовал учить F# как первый язык до тех пор, пока общество не удалится от обычных языков также далеко, как от assembly.
              +3
              Ну, при прочих равных, у F# система типов таки не новейшая и не продвинутейшая.
            –2
            Вот тоже самое и с F#. Он дает полную свободу, которой не хватает взрослым-сформировавшимся и которая может навредить молодым-неокрепшим разработчикам


            Для этого есть динамические языки со слабой неявной типизацией.
              +8
              Нет, они есть не для этого. Вернее они увеличивают свободу, но оплачиваешь ты её багами, которые мог бы поймать компайл-тайм. Вот F# — увеличивает свободу, а платишь ты за это — ничем. Вот серьёзно, просто ничем. Это бесплатная свобода!
              +6

              Вопрос тут — почему не хаскель?

                0

                Мне тоже очень интересно, в Haskell есть всё упомянутое и даже больше, но почему-то вопрос повис в воздухе.

                  +2
                  Вопрос тут — почему не хаскель?

                  Очень простой ответ — тулинг, инфраструктура, поддержка крупных/крупнейших компаний.


                  F# — это экосистема .NET (все нугеты в вашем распоряжении, интеграции со всем на свете).
                  Нативная поддержка облаков (Azure/AWS). Хаскель туда только через докер пихать или бинарники в виртуалке, а вот F# можно прям в Azure Function или AWS Lambda без прокладок или через WebApp в Azure


                  Комплиятор и SDK встроены в .NET Core SDK, так что уже даже ничего устнавливать не надо, всё в коробке.


                  Одна из лучших (на мой взгляд вообще и лучшая) IDE — Visual Studio без вопросов работает с F#, миксовать проекты в одном солюшне и делать референсы между проектами на C#/F# очевидно можно.


                  F# язык для работы. Haskell для души. Это не значит что на F# нельзя для души, а на Haskell работать, просто разные цели ставят перед собой авторы языков.

                    +1
                    Получается, если нет необходимости в интеропе с C# и .NET вообще, то половина преимуществ как-то отпадает.

                    Тулинг — ну, ghc — вполне себе production-ready-компилятор, что по качеству рантайма, что по производительности, что по профилированию, что по поддержке всяких вкусностей.

                    Инфра — commercialhaskell с их stack'ом тут заруливает. Я бы, кстати, сравнил ещё число хаскелевских библиотек и чисто F#'ых.

                    Поддержка крупных компаний — да фиг знает, вроде и с текущим состоянием норм, я бы не сказал, что как-то по совокупности поддержка отличается от таковой для F#. Кстати, где работает Simon Peyton Jones? ;)
                0
                Видимо, для отвечающих это самоочевидно)
                  +4
                  Думаю, что тут нет однозначного ответа.

                  Например, я до F# изучал много разных языков. Среди них — Haskell, Scala и Clojure.
                  И я не могу сказать, что F# однозначно лучше или хуже любого из них.
                  У всех них есть как плюсы так и минусы.

                  Я попробую сравнить по четырём параметрам — сам язык(синтаксис, система типов, набор фич и т.д.), бэкенд, фронтенд и мобильная разработка.
                  На самом деле, параметров сильно больше, но это то, что интересовало больше всего лично меня.

                  Haskell vs F#

                  Сам язык.
                  Тут, на мой взгляд, по фичам выигрывает Haskell, но по удобству, как ни странно, F#.
                  У Haskell более мощная система типов, отсутвие побочных эффектов, зависимые типы с пмошью Liquid Haskell и некоторые другие фичи.
                  С другой стороны, F# показался более прагматичным.
                  Иногда мутабильность и побочные эффекты упрощают жизнь, особенно во время взаимодействия с кодом, написанным на других языках(C#, JavaScript).

                  Бэкенд.
                  Тут сложно выбрать.
                  Для меня важна поддержка облаков и тут, мне кажется, лучше дела обстоят у F#(особенно, что касается поддержки Azure, по понятным причинам).
                  Например, F# у меня отлично работаетв AWS Lambdas и Azure Functions, а Haskell я так и не смог запустить в Azure Functions(в AWS Lambdas получилось, но не без проблем).
                  Есть Cloud Haskell и Frege(Haskell для JVM).
                  В общем, ничья.

                  Фронтенд.
                  Тут тоже паритет, т.к. у F# есть прекрасный Elmish, а у Haskell есть не менее прекрасный Miso.

                  Мобильная разработка.
                  Тут однозначно F#. У F# нативаня поддержка в Xamarin, Xamarin.Forms плюс изумительный Fabulous.
                  У Haskell с этим не очень.
                  Есть возможность разрабатывать под Android через NDK. Не пробовал, но, думаю, что занятие не для слабых духом.
                  Под iOS тоже можно как-то скомпилить код, но, как я понял, никакого тулинга и поддержки библотек.

                  Scala vs F#

                  Сам язык.
                  Scala богаче, с точки зрения набора фич, но сильно сложнее для изучения.
                  Лично мне, из Scala в F# не хватает только зависимых типов, но синтаксис нравится больше.

                  Бэкенд.
                  Тут лучше Scala благодаря JVM. У Java экосистема всё-таки побогаче чем у .NET.

                  Фронтенд.
                  Наверное F#, т.к. Elmish мне понравился больше чем Scala+React и Udash.

                  Мобильная разработка.
                  F#. Scala можно писать под Android, но как писать под iOS я вообще не нашёл.

                  Кроме того, попробовал на F# решать задачи машинного обучения и это мне прям очень понравилось.
                  У F# есть Type Providers и он поддерживается в Jupiter Notebooks.
                  Это сочетание просто убийственное.
                  Я люблю Python, но если бы у F# была настолько развитая экосистема для ML, то выбор бы для меня не стоял.

                  Короче нет однозначного ответа, но, в целом, F# очень понравился.
                  Язык прагматичный с крайне приятной экосистемой и именно его я сейчас использую для своих pet projects. На нём я могу решить абсолютно все свои задачи.

                  Конечно сравнение очень субъективное и содержит много неточностей, т.к. я многого не знаю.
                  Скорее всего упускаю много плюсов и минусов у всех языков и их экосистем.
                  Но смысл моего комментария не в этом.
                  Смысл в том, что объективно сравнить два языка практически нереально.
                  Надо брать и пробовать.
                    0
                    Спасибо за развернутый ответ!
                  0
                  Потому что он лучше, например, C#, и ребята рассказали чем. Потому что там раньше появляются новые фичи. Потому что изучение меняет твой подход в целом и развивает, как программиста. Потому что перспективный.

                  Я конечно понимаю, что я не вынес это все отдельным пунктом с выводами. Но вроде и между строк не зашифровывал.
                    +2
                    хотелось бы немного конкретных примеров, как он сокращает 200 строк в 7 :)
                      +1

                      В интервью Вагифа есть ещё упоминание об этом.
                      https://m.habr.com/post/424461/
                      Может быть вам просто попробовать написать и будет понятно где код короче?)

                        0
                        Как малый пример «Компилятор сам генерирует кучу бойлерплейта за вас, например, structural equality». Но да, будет круто, если ребята расскажут здесь еще.
                          +2
                          Пожалуйста
                          using System;
                          using System.Collections;
                          using Microsoft.FSharp.Core;
                          
                          namespace CsEquivalents.RecordTypeExamples
                          {
                          
                              /// <summary>
                              ///  Example of a simple immutable record 
                              /// </summary>
                              [Serializable]
                              public sealed class FinalGameScore :
                                  IEquatable<FinalGameScore>,
                                  IStructuralEquatable,
                                  IComparable<FinalGameScore>,
                                  IComparable,
                                  IStructuralComparable
                              {
                                  /// <summary>
                                  /// Game property
                                  /// </summary>
                                  public string Game { get; internal set; }
                          
                                  /// <summary>
                                  /// FinalScore property
                                  /// </summary>
                                  public int FinalScore { get; internal set; }
                          
                                  /// <summary>
                                  /// Constructor 
                                  /// </summary>
                                  public FinalGameScore(string game, int finalScore)
                                  {
                                      this.Game = game;
                                      this.FinalScore = finalScore;
                                  }
                          
                          
                                  /// <summary>
                                  ///  Needed for custom equality
                                  /// </summary>
                                  public int GetHashCode(IEqualityComparer comp)
                                  {
                                      var num = 0;
                                      const int offset = -1640531527;
                                      num = offset + (this.FinalScore + ((num << 6) + (num >> 2)));
                                      var game = this.Game;
                                      return offset + (((game == null) ? 0 : game.GetHashCode()) + ((num << 6) + (num >> 2)));
                                  }
                          
                                  /// <summary>
                                  ///  Needed for custom equality
                                  /// </summary>
                                  public override int GetHashCode()
                                  {
                                      return this.GetHashCode(LanguagePrimitives.GenericEqualityComparer);
                                  }
                          
                                  /// <summary>
                                  ///  Implement custom equality
                                  /// </summary>
                                  public bool Equals(FinalGameScore obj)
                                  {
                                      return obj != null
                                             && string.Equals(this.Game, obj.Game)
                                             && this.FinalScore == obj.FinalScore;
                                  }
                          
                                  /// <summary>
                                  ///  Implement custom equality
                                  /// </summary>
                                  public override bool Equals(object obj)
                                  {
                                      var finalGameScore = obj as FinalGameScore;
                                      return finalGameScore != null && this.Equals(finalGameScore);
                                  }
                          
                                  /// <summary>
                                  ///  Implement custom equality
                                  /// </summary>
                                  public bool Equals(object obj, IEqualityComparer comp)
                                  {
                                      // ignore the IEqualityComparer as a simplification -- the generated F# code is more complex
                                      return Equals(obj);
                                  }
                          
                                  /// <summary>
                                  ///  Implement custom comparison
                                  /// </summary>
                                  public int CompareTo(FinalGameScore obj)
                                  {
                                      if (obj == null)
                                      {
                                          return 1;
                                      }
                          
                                      int num = string.CompareOrdinal(this.Game, obj.Game);
                                      if (num != 0)
                                      {
                                          return num;
                                      }
                          
                                      return this.FinalScore.CompareTo(obj.FinalScore);
                                  }
                          
                                  /// <summary>
                                  ///  Implement custom comparison
                                  /// </summary>
                                  public int CompareTo(object obj)
                                  {
                                      return this.CompareTo((FinalGameScore)obj);
                                  }
                          
                                  /// <summary>
                                  ///  Implement custom comparison
                                  /// </summary>
                                  public int CompareTo(object obj, IComparer comp)
                                  {
                                      // ignore the IComparer as a simplification -- the generated F# code is more complex
                                      return this.CompareTo((FinalGameScore)obj);
                                  }
                          
                              }
                          }
                          


                          /// Example of a simple immutable record 
                          type FinalGameScore = { 
                              /// Game property
                              Game: string
                              /// FinalScore property
                              FinalScore : int
                              }
                          



                          F# decompiled into C#
                            0
                            Это получается, что фшарп все сам генерирует за кулисами? А если мне надо сравнить объекты только по Id?
                              0
                              Тогда руками.
                                0
                                override есть
                                    +1

                                    Тут ниже привели хорошую ссылку на A class with custom equality — вроде получается читаемее и короче, чем если то же самое реализовывать на C#.


                                    Но дело в том, что если нужно сравнивать по ID, то, возможно, лучше зайдествовать для этого кастомные компараторы — сегодня нужно по ID, завтра по имени-фамилии (да еще с учетом/без учета культуры/регистра) и т.д.


                                    А "структуры" (не struct, а именно структуры/рекорды в широком смысле) пусть по умолчанию сравниваются по полям "как есть".

                                  0
                                  Главным образом это применимо к Discriminated Unions. Вот тут можно глянуть пример goo.gl/V8pozz
                                  Даже после чистки всех автосгенеренных аттрибутов и форматирования все равно счет строк идет на сотни
                                    0

                                    Там все-таки большая часть — это compare и equals (которые практически никогда не нужны). Вместо тагов можно использовать рефлексию (вообще использования тагов — очень странное решение). На шарпе в любом случае код будет больше, конечно же, но все же разница скорее где-то возле 10 -> 20 строк, а не 10 -> 100.

                                      0
                                      compare и equals (которые практически никогда не нужны)

                                      В мире неизменяемых сущностей верно прямо противоположное. F# для вывода типов использует Алгоритм Хиндли — Милнера, что позволяет в 90% случаев обойтись без явного указания типа, и, в отличие от динамичиских языков сохранить типобезопасность. Одно только это уменьшает код вдвое. Особенно это заметно на четырехэтажных дженериках, когда определение метода длиннее его реализации.
                                        0
                                        Для Х-М всё же лучше топ-левел-аннотации типов писать, чтобы немножко помочь тайпчекеру помочь вам, когда вы сделали ошибку.
                                          +1
                                          F# для вывода типов использует Алгоритм Хиндли — Милнера, что позволяет в 90% случаев обойтись без явного указания типа, и, в отличие от динамичиских языков сохранить типобезопасность.

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

                                            0
                                            Как выше сказано — топ-левел аннотации порядочные люди все равно пишут, а локальный вывод есть уже ну везде, в том числе и в шарпе.

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

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

                                              Написать монаду для LINQ не проблема, при ее использовании типы прекрасно выводятся.
                                              А другие кейзы мне неинтересны, потому что с реальной практикой не связаны.


                                              и читабельности не добавляют все эти описания дженериков.

                                              На мой взгляд как раз соглашения шарпа по именованию генерик-аргументов — очень полезная штука, по сравнению классическим data K a b c d e f = yoba из хаскеля.

                                                +1
                                                по сравнению классическим data K a b c d e f = yoba из хаскеля

                                                I took a s t a b at lenses.

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

                                              То есть, я могу написать


                                              var foo;
                                              foo = 10;

                                              и оно мне выведет int?

                                                0

                                                Нет, конечно, корректный тип в данном случае алгоритмически невыводим (точнее, можно вывести только object или dynamic, что бесполезно).

                                                  0
                                                  Нет, конечно, корректный тип в данном случае алгоритмически невыводим (точнее, можно вывести только object или dynamic, что бесполезно).

                                                  Бред. Алгоритмически он как раз выводим. Хиндли-Мильнер такое пережовывает на раз. Литерал инта есть? Есть. Значит это Int32.


                                                  Даже F# справляется.


                                                  Если написать так (аналог default из C#), но не указать тип, то заинферится object (справа, едва заметным серым цветом) и вывалится value restriction:
                                                  image


                                                  Если добавить присваивание от инта, то естественно алгоритм выведет тип за нас:
                                                  image

                                                    0
                                                    Хиндли-Мильнер такое пережовывает на раз.

                                                    Хиндли-Милнер такое не пережевывает, потому что Хиндли-Милнер работает для вполне конкретных систем типов. Для каких-либо других систем (например, для системы типа шарпа) Хиндли-Милнер уже неприменим.


                                                    Литерал инта есть? Есть. Значит это Int32.

                                                    С чего бы вдруг? Там точно так же мог бы быть string иди HurrDurr. То, что должен быть Int32 — вообще ниоткуда не следует. Что будет, если ниже я напишу foo = "fdfdsfd"?

                                                      0
                                                      Для каких-либо других систем (например, для системы типа шарпа) Хиндли-Милнер уже неприменим.

                                                      Я не уверен что до конца понимаю почему нормальный вывод типов нельзя подключить к C#


                                                      С чего бы вдруг? Там точно так же мог бы быть string иди HurrDurr. То, что должен быть Int32 — вообще ниоткуда не следует. Что будет, если ниже я напишу foo = "fdfdsfd"?

                                                      Ну если мы о C#, то да, никак.


                                                      А вот тот же H-M алгоритм же с бектреком. Все ограничения от литералов и функций он применяет взад) В этом например отличие алгоритма вывода в Scala от HM, она не умеет пропагировать типы по коду выше.

                                                        0
                                                        Я не уверен что до конца понимаю почему нормальный вывод типов нельзя подключить к C#

                                                        Потому что он уже подключен.


                                                        А вот тот же H-M алгоритм же с бектреком. Все ограничения от литералов и функций он применяет взад)

                                                        Он не взад применяет, он строит цельную систему уравнений на типы, а потом ее решает. То есть ему просто без разницы, взад или вперед.


                                                        В этом например отличие алгоритма вывода в Scala от HM, она не умеет пропагировать типы по коду выше.

                                                        Допустим. А чем это плохо?

                                                        0
                                                        С чего бы вдруг? Там точно так же мог бы быть string иди HurrDurr. То, что должен быть Int32 — вообще ниоткуда не следует. Что будет, если ниже я напишу foo = "fdfdsfd"?

                                                        Что-то такое — вполне вариант.


                                                        Prelude> foo = \x -> (x <> "foo", x + (10 :: Int))
                                                        
                                                        <interactive>:7:31: error:
                                                            • Couldn't match expected type ‘[Char]’ with actual type ‘Int’
                                                      +1

                                                      Называть локальным выводом типов умение посчитать тип справа от = (что и так должен уметь делать тайпчекер) и распознать ключевое слово var/auto/etc слева — это ну так себе.

                                                        0

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

                                                          0
                                                          Эм, алгоритм в точности тот же, как что?

                                                          А вообще непонятное мне удобство какое-то, когда некоторые кейсы специально блокируются.
                                                            0
                                                            Эм, алгоритм в точности тот же, как что?

                                                            Тот же как и тот, что выводит не только по принципу "посчитать тип справа от = (что и так должен уметь делать тайпчекер) и распознать ключевое слово var/auto/etc слева".


                                                            А вообще непонятное мне удобство какое-то, когда некоторые кейсы специально блокируются.

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


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

                                                              0

                                                              Ну можно локальную аннотацию написать, внезапно.


                                                              Я и в хаскеле иногда пишу что-то вроде


                                                                where
                                                                  foo :: T
                                                                  foo = ...

                                                              или даже


                                                              {-# LANGUAGE PartialTypeSignatures #-}
                                                              ...
                                                                where
                                                                  foo :: T -> _ -> _
                                                                  foo = ...

                                                              если там особо наркоманская ерунда.

                                                                0
                                                                Ну можно локальную аннотацию написать, внезапно.

                                                                Можно, конечно, но хороший язык — это тот, что не позволяет писать плохо, а не тот, что позволяет писать хорошо. Ну это как со статической типизацией — ее смысл не в том, что вы можете написать программу, которая чекается, а в том, что не можете написать программу, которая не чекается.

                                                +1
                                                Ну, по опыту переписывания, пусть и с х-ля на плюсы, а не с F# на C#, там таки билже к 10 -> 100. Сравнения, Show, Hashable из автогенерённых, (atto)parsec для парсинга вместо спирита, адекватная беготня по деревьям вместо визиторов, uniplate/geniplate вместо, гм, вместо ничего, пиши сам.

                                                Хотя, наверное, это от предметной области зависит. Какие-нибудь гуи бы так не выиграли.
                                                  0
                                                  Ну, по опыту переписывания, пусть и с х-ля на плюсы, а не с F# на C#, там таки билже к 10 -> 100.

                                                  Зависит от того, как писать. Переписанный "в лоб" код будет действительно сильно длинней в силу своей неидеоматичности. Но это тогда сравнение яблок с бегемотами. Порядочный type soundness господин ведь не станет сравнивать яблоки с бегемотами?

                                                    +1
                                                    Переписанный «в лоб» код будет действительно сильно длинней в силу своей неидеоматичности.

                                                    Я не знаю, как идиоматично писать околокомпиляторные вещи на плюсах (и склоняюсь к варианту, что правильно — никак не писать, плюсы не для этого). Как писать хардкорные числодробилки, не вписывающиеся в repa, на хаскеле, впрочем, тоже не знаю.

                                                    Порядочный type soundness господин ведь не станет сравнивать яблоки с бегемотами?

                                                    Порядочные господа определяют отношение порядка отдельно. Можно сравнить их по пищевой ценности, например.
                                            0
                                            Мир не ограничивается шарпом. Если, скажем, я пишу на Go или Rust?
                                            Почему перспективный? Можно подробнее? Вы в статье пытаетесь «продать» F# другим программистам, хотелось бы больше selling point увидеть. Например, на вопрос «тяжело ли изучать язык» только один человек на него ответил. Остальное пишут «спасибо за дженерики», «умеет все что c#».
                                              +2
                                              Изучив F# Вы лучше поймете Go или Rust, как ни странно. По крайней мере, будет с чем сравнивать. Ну, если, захотите, конечно. Изучать F# тяжело для ООП-программеров. Впрочем, изучать вообще тяжело.
                                                +1
                                                Если вас абсолютно все устраивает в том языке, на котором вы пишете (C#?), то нет ничего зазорного на нем же и продолжать. Большинство переходящих на F# делают это после многих лет работы на C#, будучи неудовлетворены эффективностью написания на нем кода. Надо просто как-то созреть если не для перехода, то по крайней мере, чтобы попробовать писать код по-другому. К этом прийти никогда не поздно, если у вас для этого сейчас нет причин, то в этом нет ничего страшного.
                                                  0
                                                  Не очень понимаю, зачем вы меня успокаиваете, будто я что-то стыдное мог сказать. :)
                                                  Основная претензия к статье — в ней нет ответов на вопрос «зачем». Похвалить, как и поругать, можно любой язык, но это делает его обязательно желанным для изучения. Приведу к примеру Go. Очень простой синтаксис (люди начинают что-то ковырять после Go Tour), очень быстрая компиляция, статическая типизация, горутины, каналы, пакеты на все случаи жизни на гитхабе, кроссплатформенность.
                                                  Что может предложить F#, кроме иммутабельных типов? Ниже уже тоже писали про сравнение Хаскеля и F#.
                                                    0
                                                    Ну я выше привел некоторые мои аргументы «зачем», в частности о том, что еще F# может предложить кроме иммутабельных типов. Плюс в статье есть ссылка на хабровское интервью, где более подробно говорю о причинах. А «успокаиваю» я вас потому, что аргументы у каждого могут быть свои и для других они могут быть неубедительны. Первичным должно быть осознание неффективнсти текущего метода написания кода, желание что-то с этим сделать.
                                                      0
                                                      Если вам не понравились или показались неубедительными ответы, которые там дали, это не значит, что их нет.
                                                        –3
                                                        Очевивидно, есть проблемы с ответами. Если F# так хорош, как вы его описываете, почему его никто не хочет знать? Почему за время его существования другие языки появились из ниоткуда и стали мейнстримом?
                                                          +2
                                                          Классика — то, что каждый считает нужным прочесть и никто не читает.
                                                          Марк Твен
                                                            +1
                                                            Хм, в той таблице C# хотят изучать 8%, а F# — 4%. Ruby где-то посередине. По этим цифрам невозможно сделать какой-то фатальный вывод. Да и вообще, если обращаться к цифрам, имеет смысл обращать внимание не на то, что привлекает массовый интерес, а на то, как обстоит с работой и проектами в том, чем хотелось бы заниматься. Если нет вокруг проектов на языке, на котором хотелось бы писать, то это разумный аргумент, чтобы все не бросать и ждать, пока появится. Но и здесь преимущество нашей профессии — что можно что-то изучать в свободное время, дожидаясь возможности это применить. У меня лично года четыре прошло с момента, когда я понял, что мне хочется программировать на F# и стал его потихоньку осваивать, до того, как я смог на нем программировать за деньги. Сейчас, думаю, ситуация значительно улучшилась.
                                                    +1
                                                    Как-то раз я попросил гуру Джавы и гуру .NET сравнить, на чем кодить лучше. Большая часть сравнения пришлась на инфраструктуру: библиотеки, тулзы, средства разработки, платформы, фреймворки и т.д. То есть, возможность написать запрос к google API в 7 строк — это хорошо, но наличие библиотеки googleAPI — лучше. У F# есть какие-то «инфраструктурные» преимущества?

                                                    Теперь по вашим пунктам «Почему стоит тратить время и силы именно на F#?».
                                                    Потому что там раньше появляются новые фичи.
                                                    В Java фичи появляются реже. Язык и окружение живут и здравствуют. .NET куда симпатичней «чистой» Джавы, но джавистов надо больше (в моей локальной области пространства, да).

                                                    Потому что изучение меняет твой подход в целом и развивает, как программиста.
                                                    Ок. Но такой аргумент применим и для PowerShell\SharePoint\Axapta\JS\React\Redux\SQL — изучение всех этих языков\фреймворков развивает тебя и меняет твой подход к программированию. Почему надо изучать именно F#, а не один из пунктов выше?

                                                    Потому что перспективный.
                                                    F# уже несколько лет как перспективный. И перспективность его сильно зависит от воли MS (если я правильно прочел статью).

                                                    Вы понимаете, не так важно, сколько в языке фич, или «насколько правильно» он дружит с ООП. У языка ЦА — разработчики. А про этих ребят ходят анекдоты вроде «работает — не трогай». Ну вот работает C# для человека — зачем его трогать, да? Лучше посмотреть в сторону ML\DS. Или предметную область покопать. Или про Mongo\Elastic\Azure Storage почитать.

                                                    Чувствуете грань? Для тех задач, которые может закрыть F# — у разработчика уже есть C#. И у разработчика есть выбор: сконцентрироваться на тех задачах, что он уже умеет решать (и изучить F#), или сконцентрироваться на задачах, которые он решать не умеет (и изучить Python\JS\NoSql\Sql\Domain).

                                                    Вот и получается: язык интересный, относительно простой (при знании .NET учится за неделю — пример перед глазами), но все еще перспективный, а не популярный.
                                                      +4
                                                      Я знаю F# и НЕ программирую на нем. Но я ни разу не пожалел, что изучил его. Как бы это сказать… У F# есть не «инфраструктурные» преимущества, а интеллектуальные. Это просто другой взгляд на программирование.

                                                      Но такой аргумент применим и для Java\PowerShell\SharePoint\Axapta\JS\React\Redux\SQL


                                                      Не применим: Java это близнец C#, а функциональные языки просто из Зазеркалья
                                                        +1
                                                        Вы в целом правы, вычеркнул «java» из списка.

                                                        По поводу же «другого взгладя»: F# — функциональный язык, PowerShell — интерпретируемый, SharePoint — инфраструктурный с типовыми задачами, Axapta — погружение в Domain, JS — упор на фронт, React — компонентность, Redux — ФП, SQL — тоже своеобразен.

                                                        Любой из вариантов выше даст другой взгляд на программирование. Почему же именно F#?
                                                          0
                                                          Не обязательно F#, любой функциональный язык подойдет. Теория групп — это то что кардинально отличет ФП от ООП (хотя она применима и там). Именно для того, чтобы понять чем Вы занимаетесь сейчас с точки зрения этой теории.
                                                            +1
                                                            Давайте немного проясним. Почему именно функциональный язык? Почему не низкоуровневый, например? И что такого сакрального в теории групп, что нужно выяснять её точку зрения?
                                                              +1
                                                              Группы — первый шаг к алгебре, а алгебра — это про структуры, а структуры — это про всё.

                                                              Правда, непосредственно теория групп к ФП отношение имеет весьма малое.
                                                                0
                                                                Теория категорий, а не групп, спутал с полугруппами, извините. Развернутый ответ на этот вопрос есть тут: From design patterns to category theory

                                                                Вкратце: шаблоны программирования от GOF или Фаулера представляют некоторые абстракции, выведенные эмпирическим путем, в то время как в теории категорий всё основано на четкой и однозначной математике. Проблема со стандартными шаблонами в том, что каждый программист воспринимает их по-своему. Типичный пример это MVC — никто не знает, что такое каноничный MVC; или Репозиторий — существуют сотни различных реализаций этого шаблона. Если же говорить на языке математики, то все становится однозначно.

                                                                Кроме того, ФП основано на трансформации данных, в то время как ООП на действиях. Это кардинально меняет стиль программирования.

                                                                Короче, Нео, у тебя есть две таблетки: возьмешь красную — узнаешь, что полиморфизм, инкапсуляция, наследование и шаблоны проектирования не нужны, возьмешь синюю — все останется по-прежнему.
                                                                  +1
                                                                  Полиморфизм нужен, но не тот.
                                                                    +1
                                                                    По поводу «никто не знает, что такое каноничный MVC» вспомнился мне коллега, который пытался объяснить что его понимание паттерна — самое верное и view с контроллером обязан взаимодействовать вот так, и никак иначе!
                                                                      0
                                                                      Типичный пример это MVC — никто не знает, что такое каноничный MVC

                                                                      Для вас может быть новостью, но что такое "каноничный функтор" тоже никто не знает, потому что кодировка может быть любая, никаких стандартных реализаций не существует. На самом деле-то самих функторов в программировании нет, есть некоторые штуки, которые можно считать функторами, причем обычно даже можно считать в определенном приближении. Так что разница с MVC на деле-то и невелика :)
                                                                      Все это просто определенный вокабуляр, некие идиомы, при помощи которых можно мыслить и получать какой-то полезный результат. И MVC или репозитории ничуть не менее полезный термины, чем монады. Вообще, чем лучше человек знает язык, чем с большим количеством понятий он способен комфортно работать — тем лучше.

                                                                        0
                                                                        что такое «каноничный функтор» тоже никто не знает

                                                                        Ну, если искать определение функтора не в математической энциклопедии, а в книжках Александреску, тогда — да. Идея в том, что современные шаблоны проектирования никак научно не обоснованы — это как алхимия против таблицы Менделеева.
                                                                          0
                                                                          Ну, если искать определение функтора не в математической энциклопедии, а в книжках Александреску, тогда — да.

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


                                                                          Идея в том, что современные шаблоны проектирования никак научно не обоснованы — это как алхимия против таблицы Менделеева.

                                                                          А в каком смысле они должны быть обоснованы? Это просто некоторые решения некоторых проблем, которые часто применяются, и потому "достойны" отдельного названия.
                                                                          Функторы или монады из теорката обоснованы не в большей мере (и если функторы еще достаточно базовая вещь то монада — это просто интересный объект, то есть мотивация выделения такого объекта в точности соответствует мотивации введения паттернов вроде mvc).
                                                                          Реализация их нигде и никак не регламентируется (и регламентироваться не может), то есть функтор в хаскеле (или в каком-то другом языке) и функтор в теоркате — это совершенно разные объекты, функторы в хаскеле являются лишь одним из вариантов кодировки теоркатовых да и то условно. И если в том же хаскеле эта условность совсем где-то глубоко зарыта, то в какой-нибудь скале монада Try нарушает монадические законы вполне конкретно. Но все равно монада.

                                                                            0
                                                                            Насколько понимаю, реализация действительно не регламентируется, зато чётко заданы свойства, из которых следуют различные следствия.
                                                                            То есть, если объект имеет определённые чётко заданные свойства — мы можем назвать его функтором, из чего следуют всякие полезности, свойственные этим самым функторам.
                                                                            У того же паттерна MVC нет чётко заданных свойств и нельзя тупо взять, проделать с двумя разными реализациями паттернов одинаковые действия и получить одинаковый результат.
                                                                            Но я в этих вещах нуб, могу ошибаться.
                                                                              0
                                                                              Насколько понимаю, реализация действительно не регламентируется, зато чётко заданы свойства, из которых следуют различные следствия.

                                                                              Так я же вам говорю, что:


                                                                              1. эти свойства на практике выполняются весьма условно (с разной степенью условности)
                                                                              2. с-но это объясняет первый пункт — эти свойства в программировании не важны, они там попросту бесполезны. Так уж вышло, что те причины, по которым те же монады интересны в математике — они не интересны в программировании, а те причины, по которым они интересны в программировании — они не интересны в математике.

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

                                                                              Смотрите, с точки зрения программирования монада (я говорю о монадах, а не о функторах, потмоу что функторы — слишком бессодержательная вещь) — это интерфейс построенный в вокабуляре из пары понятий bind/return, причем семантика bind/return неформализуема.
                                                                              Если ваши bind/return или какое-то изоморфное представление соответствует такому внутреннему неформалзованному понимаю, то перед вами, с точки зрения программирования, монада, пусть она и не является монадой с точки зрения формально-математической, как Try в скале.
                                                                              Потому что программисту от монады не нужны монадические свойства, программисту от монады нужен специфический способ композиции, некие принципы, по которым он может построить интерфейс к НЕХ и потом с этой НЕХ работать.
                                                                              И в этом плане это ничем не отличается от MVC.


                                                                              Все паттерны (и ФП паттерны и ООП) — это просто некие общие принципы построения интерфейсов, не более и не менее. Просто абстракции, за которые удобно скрывать НЕХ того или иного вида для того, чтобы работать с этой НЕХ тем или иным способом.

                                                                                0
                                                                                Ок. Как я уже говорил, я не волшебник а только учусь. Про функторы, аппликативные функторы и монады я более менее нормально прочитал в «Learn you a haskell for a great god» вот в этой главе.
                                                                                Рассмотрим для простоты функтор.
                                                                                Функтор имеет всего один метод:
                                                                                fmap :: (a -> b) -> f a -> f b
                                                                                — то есть, берёт функцию и параметр, обёрнутый во что либо, достаёт параметр, применяет к нему функцию и оборачивает обратно.
                                                                                Также, функтор имеет два свойства:

                                                                                1. если применить fmap к функции id и функтору, то получим тоже самое значение, что получили бы просто применив id к функтору
                                                                                2. если к результату композиции двух функций применить fmap с функтором, результат будет тот же, если мы сначала применим fmap с фуктором к одной функции, затем к другой


                                                                                Скажите, пожалуйста, где здесь условность?
                                                                                Оба свойства чётко определены, мы можем спокойно написать функцию, которая может проверить любой объект, реализующий fmap на предмет — «а не функтор ли ты часом ?» и дать точный ответ на этот вопрос.
                                                                                С MVC так не выйдет )).
                                                                                  0
                                                                                  Скажите, пожалуйста, где здесь условность?

                                                                                  Как водится, в жопе:


                                                                                  Prelude> seq undefined ()
                                                                                  *** Exception: Prelude.undefined
                                                                                  CallStack (from HasCallStack):
                                                                                    error, called at libraries\base\GHC\Err.hs:79:14 in base:GHC.Err
                                                                                    undefined, called at <interactive>:50:5 in interactive:Ghci19
                                                                                  Prelude> seq (id . undefined) ()
                                                                                  ()
                                                                                  Prelude> 

                                                                                  => id. undefined != undefined, с-но ваша категория — не категория, а функтор — не функтор, т.к. id в хаскеле нет.

                                                                                    0
                                                                                    Сейчас, о достопочтенные граждане, я восстановлю баланс во вселенной:
                                                                                    Prelude> ff = id . undefined
                                                                                    Prelude> :t ff
                                                                                    ff :: a -> c

                                                                                    В общем, выражение (id. undefined) имеет тип «ff :: a -> c» а не «undefined» как может показаться на первый взгляд.
                                                                                    Так что id возвращает то что должно.
                                                                                      0
                                                                                      Так что id возвращает то что должно.

                                                                                      нет, не возвращает. id. a = a, по определению id, это равенство в хаскеле не выполняется.


                                                                                      имеет тип «ff :: a -> c» а не «undefined»

                                                                                      undefined это не тип, а значение, и тип у него:


                                                                                      Prelude> :t undefined
                                                                                      undefined :: a
                                                                                      Prelude> 

                                                                                      то есть в данном случае id. undefined должно вернуть значение undefined типа a -> c. А оно не возвращает.

                                                                                        0
                                                                                        id. a = a, по определению id, это равенство в хаскеле не выполняется.

                                                                                        Оно нигде не выполняется, потому что вы нигде это не можете записать как теорему этого языка (на самом деле логическая цепочка тут чуть сложнее, но не суть).


                                                                                        В хаскеле оно не выполняется только в присутствии seq, кстати.

                                                                                        0

                                                                                        Нет. Дело в том, что у seq кривая неконсистентная семантика.


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


                                                                                        seq принимает два аргумента и возвращает жопу ⊥ (его просто по-английски bottom'ом называют), если первый аргумент — ⊥, либо иначе возвращает второй аргумент. Его цель — привести ленивое значение в weak head-normal form (то есть, вычислить что-нибудь до первого конструктора).


                                                                                        Теоретически ⊥ — это много чего, от бесконечной рекурсии (поэтому тот же оператор неподвижной точки возвращает наименьшее значение, зависание — это и есть наименьшее значение) до error и undefined, но в данном случае нас интересует только undefined (который тоже ⊥, и ⊥ населяет в хаскеле любой тип, поэтому undefined :: a, и поэтому хаскель неконсистентен как логика).


                                                                                        Поэтому seq undefined () = ⊥, и поэтому же seq (id . undefined) () ≠ ⊥ (т. к. id . undefined функция и не является ⊥), но seq (id undefined) () = ⊥id undefined не является значением, поэтому его надо вычислить.


                                                                                        И поэтому, если вспомнить, что ⊥ — это не только undefined, но и, скажем, бесконечная рекурсия, то становится совсем очевидно, почему первый и третий варианты здесь зависают, а второй — нет.


                                                                                        Prelude> let x = x in seq x ()
                                                                                        ^CInterrupted.
                                                                                        Prelude> let x = x in seq (id . x) ()
                                                                                        ()
                                                                                        Prelude> let x = x in seq (id x) ()
                                                                                        ^CInterrupted.
                                                                                        0

                                                                                        Настоящие хаскелисты притворяются, что Hask is a category, выкидыванием seq.

                                                                                        0
                                                                                        Скажите, пожалуйста, где здесь условность?

                                                                                        Вы эти свойства даже не сможете записать, экстенциональности нет.


                                                                                        Более того, вы их не сможете записать, скажем, даже в идрисе. Максимум, который вам доступен — map id f = f для конкретного f, да и то это доказывается паттерн-матчингом по f. Из этого нельзя сделать вывод, что map id = id, аксиоматика не позволяет.


                                                                                        Написать {f1, f2 : a -> b} -> map f1 $ map f2 f = map (f1 . f2) f (что читается как «для любого f1, f2 тип справа населён выполняется соответствующее равенство») вы вообще не сможете, максимум — доказать это утверждение для каждой данной пары f1, f2.


                                                                                        Но это немножко другое. Хотя и имеет глубокую философскую связь. А, может, и не имеет.

                                                                                          0
                                                                                          Короче, как завещал Гёдель, в реальности мы упираемся в проблему полноты и противоречивости.
                                                                                          Хотя, интуиция подсказывает, что в Хаскеле и с полнотой могут быть проблемы.
                                                                                    0
                                                                                    В программировании кто угодно может назвать что угодно как угодно. В математике не так: мне ничего не известно об альтернативном определении функтора в контексте теории категорий. Шаблоны проектирования в ФП имеют основой математику, в то время как шаблоны в ООП, происходят из фольклора. Данная фишка ФП приводит к тому, что реализацию очень легко проверить — если реализация имеет все свойства математического определения, значит это оно и есть. Если монады в Scala что-то нарушают, то это можно однозначно определить как нарушение, так как есть источник истины. А в ООП за каждой реализацией нужно ещё выяснять, что имелось ввиду. Нету общего словаря, фактически, шаблоны являются рекомендациями, а не законами, что приводит к вечным спорам и различным казусам. Но это тема отдельного разговора.
                                                                                      0
                                                                                      В программировании кто угодно может назвать что угодно как угодно. В математике не так

                                                                                      Но поскольку мы говорим о программировании — нам совершенно неважно, как там в математике. Там может быть как угодно.


                                                                                      Шаблоны проектирования в ФП имеют основой математику, в то время как шаблоны в ООП, происходят из фольклора.

                                                                                      Ну вот в том и ваша ошибка, шаблоны ФП имеют основой в точности тот же фольклор и точно то же самое происхождение.


                                                                                      Если монады в Scala что-то нарушают, то это можно однозначно определить как нарушение, так как есть источник истины.

                                                                                      Как нарушение чего? Ну определили вы, что в математическом смысле Try — не монада. Но все что нужно программисту от монады — все это в ней есть. По-этому тот факт, что математически она не монада — никому не интересен. Ну то есть это просто забавный бесполезный факт.


                                                                                      Понимаете, допустим я дам строгое математическое определение MVC, при этом все существующие реализации будут MVC "приближенно", ну как те же ФП паттерны являются соответствующими математическими объектами лишь в приближении.
                                                                                      И что? Толку от этого? Чем-то лучше станет кому-то? Что-то изменится? MVC сразу приобретет какие-то особенные свойства? Нет, чем было — тем и останется.

                                                                                        0
                                                                                        По-этому тот факт, что математически она не монада — никому не интересен. Ну то есть это просто забавный бесполезный факт.

                                                                                        Теоретически это может быть интересно разработчикам оптимизатора в языке.

                                                                                      0
                                                                                      Могу ошибаться, но я насколько помню у Александреску функторы — это совсем не те функторы, что в ФП, разве нет? Просто название случайно совпало.

                                                                                      Это там произвольные callable.

                                                                                      А почему в окамле функторы, кстати, называются функторами?
                                                                            0
                                                                            Забавно, но F# может быть и интерперетируемым. Погружение в Domain тут, много раз говорили то система типов помогает писать доменную логику, Fable трансплиттер в js — упор на фронт. Fable.React — F# и React = Компоненты, Redux = FSharp.Elmish, SQL — F# Sql Type Providers.
                                                                            F# — это очень широкий взгляд на программирование.
                                                                              0
                                                                              Neftedollar Напишите, пожалуйста, статью об этом. Или развернутый комментарий.
                                                                          +4
                                                                          То есть, возможность написать запрос к google API в 7 строк — это хорошо, но наличие библиотеки googleAPI — лучше.

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


                                                                          У F# есть какие-то «инфраструктурные» преимущества?

                                                                          О каких инфраструктурных преимуществах идет речь? Набор библиотек такой же, как для C#. Среда разработки та же.
                                                                          У F# нет решарпера, но так он и не так нужен. У F# ниже дебагабилити, но и дебажить приходится гораздо реже.


                                                                          Для тех задач, которые может закрыть F# — у разработчика уже есть C#

                                                                          Верно. Но на F# эти задачи можно решить проще, быстрее и надежнее. Если это для вас не аргумент, тогда мне больше нечего предложить.

                                                                            0
                                                                            Замечательно. С библиотеками все ровно. Учитывая отсутствие R# — инструментарий незначительно беднее.

                                                                            Но на F# эти задачи можно решить проще, быстрее и надежнее.
                                                                            Положим, я вам верю. Мой опыт говорит об обратном, но вам я верю. В итоге у C# разработчика ровно тот же выбор: отточить навыки решения тех задач, что он уже умеет решать (через F#), или же посмотреть на инструменты решения других задач.

                                                                              0
                                                                              Все просто: если разработчик позиционирует себя в профессиональном смысле как C# developer, то независимо от того, знает ли он SQL/NoSQL/JS/Azure и тд, он все равно большую часть рабочего дня пишет код на C#, и подавляющее большинство его задач тесно связаны с C#. И если все то, что у него отнимает больше всего рабочего времени, можно решить проще, быстрее и надежнее, то ухватиться за эту возможность в долгосрочной перспективе будет выгодно и ему, и бизнесу.
                                                                              Тем более, что это даже не будет радикальным изменением, как например, переход на хаскель или го. Это та же платформа с той же инфраструктурой. C# и F# можно даже в одном солюшне сочетать, так что плавный переход возможен даже на монолитных приложениях.
                                                                              И освободившееся от багфикса и рефакторинга время можно будет потратить в том числе на изучение других технологий.
                                                                                0
                                                                                Вы предполагаете, что в фирме ровно столько задач, сколько решает программист. На деле же, он либо растягивает задачи на отведенное время, либо начальство подкидывает ему новые задачи по мере выполнения старых. Так что «высвободить время для обучения» F# не поможет. Оно или уже есть, или освобожденное время забьют.

                                                                                По поводу надежности F# кода — а кто его будет поддерживать? Вот есть команда, 5 человек. Лид, 2 дева, QA, аналитик. Один дев говорит лиду «давай на F# красоту забабахаем». А лид думает: «этот перец тут уже 2 года работает. Скоро свалит. Второй дев F# не знает. Фактор автобуса. Ну нафиг этот F#.»

                                                                                И самое главное. F# используется в 10 раз реже, чем C# (крайне грубая статистика годовой давности, смотрел просты на reddit\stackoverlfow). T-SQL используется в 2 раза реже, чем C# (условно). Agile\Scrum используются в 95% командных проектов, ибо хайп. JS используется чаще C# (в каком-то из своих проявлений). В большинстве проектов нужен DevOps (хотя бы единожды за проект). Цифры намекают, что изучать надо JS\SQL, а не F#. Если хочется фунциональщины — Redux.

                                                                                Аргументы выше не говорят, что F# бесполезен. У него есть свои ниши, свое применение. По слухам, F# отлично заходил с Accord.NET. Удобно конвертировать входные данные к нужному виду, и строить всякие классификаторы. F# может зайти одиночкам-фрилансерам (скорость важна, нишевость помогает, надежность не критична). F# может отлично зайти в высокопрофессиональных командах .NET разработчиков, все его выучат за пару недель. Может зайти «под интерес».

                                                                                И вот про эти ниши реально хочется услышать от знающих людей. Которые могут, в отличие от меня, указать эти ниши без «по слухам» и «может». Которые могут по полочкам разложить, почему в этой нише F# зайдет, а в этой — нет.
                                                                              +2
                                                                              У F# нет решарпера, но так он и не так нужен. У F# ниже дебагабилити, но и дебажить приходится гораздо реже.

                                                                              Напоминает старый анекдот про покупки:


                                                                              • покупаем дорогое — ищем недостатки;
                                                                              • покупаем дешёвое — ищем достоинства.

                                                                              Вот и получается, что если чего-то в F# нет — делаем вид, что это и не надо. Называется предвзятое отношение и агитация вместо аргументов

                                                                                0
                                                                                Я не делаю вид, что этого не надо и не говорю, что F# идеален. Да, было бы круто иметь инструменты вроде решарпера (я, кстати, им и в C# не пользуюсь, но все равно), было бы здорово, если бы debug tools были столь же хороши или даже лучше, чем в C#. На данный момент в F# нет оператора `nameof`, к сожалению.
                                                                                Я говорю, что несмотря на отсутствие/отставание этих инструментов эффективность решения бизнес задач на F# все еще выше, чем на C#.
                                                                              +2
                                                                              F# унаследовал всю инфраструктуру C#, именно поэтому и важно, что он дружит с ООП.
                                                                                0
                                                                                То есть, возможность написать запрос к google API в 7 строк — это хорошо, но наличие библиотеки googleAPI — лучше. У F# есть какие-то «инфраструктурные» преимущества?

                                                                                Не знаю конкретно про F#, но у чистой функциональщины преимущества в том, что библиотека даёт больше гарантий о том, что она делает. Тайпчекер может гарантировать вам, что библиотека для парсинга YAML не полезет открывать файлы, и что библиотека для Google API будет только выплёвывать вам урлы/токены/етц, а не отправит её создателю что-то ещё.
                                                                                  0
                                                                                  F#, судя по комменатриям, способен вызывать любуй .NET либу. Значит, функции там вполне могут содержать побочные эффекты.

                                                                                  А как подобная безопасность обеспечивается в «настоящей» функциональщине?
                                                                                    +4

                                                                                    Ну, вы и на хаскеле можете писать код целиком в IO, теряя некоторые гарантии.


                                                                                    В настоящей функциональщине если функция не живёт в IO-монаде, то она гарантированно (с точностью до грепа по unsafePerformIO и ещё паре подобных функций) не имеет IO-сайд-эффектов и поэтому не стучится на сервера и не читает файлов.


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


                                                                                    Там ещё рядом где-то свободные монады и всё такое, я всё хочу про это статеечку написать на прикладном примере, но руки не доходят.

                                                                                      +2
                                                                                      вот прикландых примеров по функциональщине в хабре очень не хватает, с удовольствием почитал бы.
                                                                                0
                                                                                Потому что перспективный.

                                                                                Они вместе с D уже скоро второй десяток лет как в перспективных ходить будут, а воз и ныне там. Единственное его «достоинство», отличающее его от Хаскеля и Скалы — привязка к дотнету. Кому критично, тем, пожалуй, подойдет. На этом его преимущества относительно остальных функциональных языков заканчиваются. А с учетом околонулевой популярности и примерно такого же коммьюнити, проще удариться в те же Хаскель и Скалу. Потому что у первого хотя бы виден прогресс и он от шуточных «8 вакансий на весь мир» дорос до вполне серьезно рассматриваемого языка, а второй еще и привязан к JVM (думаю не стоит сравнивать потребность в JVM и в дотнете на рынке).
                                                                                0
                                                                                Проекты на F# не пишут, потому что программистов на рынке мало, а программисты не учат этот язык, потому что проектов на рынке нет.

                                                                                Справедливо для всей функциональщины и достаточно, чтобы вообще к ней не прикасаться.
                                                                                  +1

                                                                                  Вагиф работает с ФП на работе, Айрат Работает с ФП. Постепенно все меняется.
                                                                                  Кроме того, развиваться стоит всегда, если хотите не трогать это сейчас, кто знает, вдруг потом будете в догоняющих?

                                                                                    +3
                                                                                    Функциональщина в проде не всем нужна, но для расширения горизонтов попробовать ФП всё же стоит, хотя бы как упражнение для ума. Зачем ограничивать себя только тем, что напрямую монетизируется?
                                                                                      0
                                                                                      Полностью согласен. Взять развитый функциональный язык и попробовать его, стоит хотя бы только ради возможности иначе взглянуть на разработку. Это ломает закостенелость. И косвенно помогает осваивать те вещи, которые постоянно перекочёвывают из ФП в другие языки. Типа first class функций, реактивщины, частичного применения…
                                                                                      0
                                                                                      Справедливо для всей функциональщины

                                                                                      Scala вполне имеет свою небольшую нишу. Haskell тоже, но не в наших широтах. Тут он пока выступает в роли 2-3 языка в командах. Т.е. не все так плохо, но и основную ставку на них делать рано.
                                                                                        0

                                                                                        Фейсбук активно использует хаскель для борьбы со спамом и очень этим доволен. Тут уже несколько раз вспоминали про Вагифа, а ведь у них уже было все написано на C# и они все равно пошли на такой риск для бизнеса, как не просто все переписать, а еще и переписать на другом языке, к тому же, менее популярном. И остались довольны. Насколько я знаю, шведская компания Record Union тоже собиралась переписывать то, что у них есть, с C# на F#. Rust на stackoverflow является самым любимым программистами языком.


                                                                                        Если захотите найти аргументы, чтобы не учить F# или ФП в целом, вы их найдете. Только зачем?

                                                                                        0
                                                                                        Странно, что нет никакого сравнения с Хаскел, который тоже функциональный и тоже широко известен в узких кругах.
                                                                                          0
                                                                                          Ребята в разговоре упоминали Хаскел, но без особых подробностей, и в финальный текст просто не влезло. Как-нибудь про него поговорим отдельно, обязательно
                                                                                            0
                                                                                            Интересно было бы рассмотреть вопрос именно в плане изучения функциональной парадигмы. То есть с чего начинать изучать функциональщину человеку который с ней не знаком.
                                                                                              0

                                                                                              Если вы из C#, то F# отличное поможет постепенно двигаться. Хотя если вы из C#, вы уже немного начали)
                                                                                              Пайпы из ФП проникают js, и rust (на макросах) Опциональные типы в тот же Rust, но уже на уровне языка. Чистое ФП это это как полюс, крайность которая сама по себе редко нужна, так же и с чистым ООП, сейчас почти везде сплав ФП + ООП где то одного больше, где-то

                                                                                                0
                                                                                                Изучение функциональной парадигмы в прикладном аспекте лучше всего начать с изучения Хаскеля. Если освоите point-free programming и монады, то функциональнгые элементы в других языках покажутся очень простыми и понятными. Писать на Хаскеле что-то кроме простых примеров из учебника с такими навыками вы не сможете, для Хаскеля это примерно как таблица умножения, но для майнстримовых языков монады и point-free programming почти что высшая математика )
                                                                                                  0
                                                                                                  Раз уж пошла такая пьянка, не подскажете, где можно найти материалы для переформатирования сознания в pointfree и декларативный стиль программирования?
                                                                                                  Начал недавно изучать Haskell и очень не хватает какого то списка best practices. Большинство материалов либо учат основам языка, либо их применению, но переход мышления на функциональные рельсы происходит очень медленно, на мой взгляд.
                                                                                                    0
                                                                                                    Пока еще не интересовался всей этой темой, но по моему для расширения сознания в нужные степи СИКП часто советуют.
                                                                                                      0
                                                                                                      СИКП это, конечно, круто но уж слишком )).
                                                                                                      0
                                                                                                      После всяких Learn You a Haskell for Great Good и других вводных могу посоветовать книгу A. Mena «Beginning Haskell» ( у «Питера» есть перевод). Несмотря на название, там уже более высокий уровень даётся и затрагиваются уже более прикладные вещи, типа профилировщиков, тестирования и прочего. После этого, видимо, развитие только через копание чужих проектов.
                                                                                                        0
                                                                                                        Спасибо. Название действительно какое то простецкое, так бы прошёл мимо ).
                                                                                                        0
                                                                                                        К сожалению, какого-то одного источника (типа книги) для этой цели не существует, по крайней мере, я такого не знаю. Лично мне помогли эти книги

                                                                                                        Kees Doets and Jan van Eijck. The Haskell road to logic, math and programming
                                                                                                        Miran Lipovaca. Learn you a Haskell for great good! A beginner's guide
                                                                                                        Simon Thompson. Haskell: The craft of functional programming
                                                                                                        John Goerzen. Real world Haskell

                                                                                                        При всем моем почитании Хаскеля не думаю что его изучение имеет большую практическую ценность. Я имею в виду изучение в той мере которая позволит писать что-то боле-менее реальное — для этого понадобится очень много сил. А вот в объеме монад и point-free programming самое то. Для этого перечисленных книг вполне достаточно, хотя сдвиг в мышлении не произойдет в одночасье.
                                                                                                          0
                                                                                                          Спасибо. «Learn you a Haskell...» освоен, частично ознакомился с «Real world Haskell».
                                                                                                          Насчёт практической применимости не соглашусь. Уже сейчас пытаюсь использовать его как скриптовый язык для собственных маленьких потребностей.
                                                                                                          В этом качестве нравится тем, что можно скомпилить исполняемый файл под любую десктопную платформу, и не нужно потом на целевой машине что то там устанавливать дополнительно.
                                                                                                          Раньше пользовал для этой цели Питон, но он не нравится по вышеуказанной причине.
                                                                                                            0
                                                                                                            Говоря о практической применимости я не имел в виду использования Хаскеля в качестве хобби. Я имел в виду профессиональную деятельность, в том смысле что вам платят деньги за то что вы пишите именно на Хаскеле. По моему мнению, чтобы дойти до такого уровня существующей литературы (книг) недостаточно. Нужно читать статьи и ковыряться в коде. Вы уверены что это наилучшая ивестиция вашего времени? Поверхностное знание Хаскеля (для себя я обозначил это как point-free programming и монады) позволит мыслить на более абстрактном уровне и видеть неочевидные паттерны там где вы их раньше не видели. Но с прагматической точки зрения применять эти прокачанные скиллы лучше на более мейнстримовом языке, тем более что во многих из них так или иначе присутствует возможность писать код в функциональном стиле.
                                                                                                              0
                                                                                                              Ну если так то да, согласен. Вакансий таких раз два и обчёлся, плюс, знаний для написания чего то покрупнее нужно «чуть» больше чем умение пользоваться монадами.
                                                                                                              0

                                                                                                              Там ещё последнее время рекомендуют Haskell from the First Principles, оно вроде даже действительно неплохое, но хз, как зайдёт.

                                                                                                            +1
                                                                                                            где можно найти материалы для переформатирования сознания в pointfree

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

                                                                                                              0
                                                                                                              А ещё это довольно механическая штука.
                                                                                                                0

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

                                                                                                                  0
                                                                                                                  Видимо, не одному мне приходила такая мысль ).
                                                                                                                  Думаю, такое всё таки тренируется постоянной практикой.
                                                                                                                    0

                                                                                                                    Ну хз, я только иногда из монадического стиля в аппликативный переписываю, если оно так изящнее и семантически понятнее получается. Ну и хинтам hlint'а следую.


                                                                                                                    Вот как бы вы написали функцию с типом Monoid b => (a, (Maybe b, c)) -> (a, (b, c))?

                                                                                                                  0
                                                                                                                  Ну, меня ФП как раз привлекло возможностью «посмотреть на программирование с другой стороны». Проходили их в универе, и даже немного писали на Лиспе, но тогда как то не проникся.
                                                                                                                  Сейчас приобщаюсь потихоньку и ощущения примерно те же что от книги Гради Буча, прочитанной взахлёб ещё в далёком 2003м.
                                                                                                                  Согласен, пихать pointfree куда ни попадя не очень хорошо. Во всём нужна мера )
                                                                                                                  0
                                                                                                                  Когда пройдёте хаскель, потыкайте ещё в идрис по, скажем, книге его создателя «Type-driven development with Idris». От мейнстримного ООП до хаскеля примерно как от хаскеля до вот этого вот.
                                                                                                                    0
                                                                                                                    Вот, за что я люблю Хабр, так это за комментарии. Если задать правильный вопрос, сразу получишь тонну интересного )).
                                                                                                                    Я правильно понял, что, упрощённо говоря, Idris это Хаскель скрещённый с Прологом?
                                                                                                                      +1

                                                                                                                      Я бы скорее сказал, что это хаскель с более мощной и менее костыльной системой типов.

                                                                                                                        0

                                                                                                                        Кстати, хаскель с прологом — это карри. В честь всё того же Хаскелла Карри.

                                                                                                              +2
                                                                                                              И вообще — кто те люди, которые на нем пишут, и зачем они это делают, если язык не нужен бизнесу?

                                                                                                              А вот есть и обратный пример — Cobol, язык бизнесу, по крайней мере западному, нужен, а его никто не изучает, ну или мало кто…
                                                                                                                +2
                                                                                                                Мне кажется, с Cobol ситуация примерно как с гондольерами в Венеции, если верить гидам. Их всего 425 и чтобы стать гондольером, надо дождаться пока кто-то из нынешних уволится или умрет…
                                                                                                                  –1
                                                                                                                  Поехать в Египет, снять пирамиду и повесить перед входом стилизованную под старинные египетские иероглифы табличку «Cobol school», что-то вроде школы орфиков из «Таис Афинской»:-)
                                                                                                                +2
                                                                                                                Интересно, почему в материал не вошли ссылки на русскоязычные материалы для изучения F#? В частности, сайт русскоязычного сообщества F# с онлайн компилятором, подборкой литературы, переводов, видео. Начать изучать можно, например, со статьи "Погружение в F#. Пособие для C#-разработчиков", опубликованной на Хабре, и цикла "Функциональное мышление".
                                                                                                                  +3
                                                                                                                  А зачем изучать F# на русском? Если человек не в состоянии свободно читать материалы по программированию на английском (где английский очень простой, если не сказать примитивный), то такой человек почти наверняка занимается не своим делом.
                                                                                                                    +1
                                                                                                                    Нет, это не так
                                                                                                                      0

                                                                                                                      Согласен с вами, что знания английского — это то, без чего и на рынке, и в целом в отрасли придётся плохо. Но давайте не будем за других людей решать, что им делать и как начинать изучать предмет? :)

                                                                                                                        +3
                                                                                                                        Я не решаю за других людей, я лишь констатирую факт. А уж игнорировать этот факт или пытаться исправить ситацию это каждый решает для себя сам )
                                                                                                                        0
                                                                                                                        Ну вот я сейчас из интереса ковыряю dart и flutter. Все на английском ибо флаттер вообще еще не релизнулся даже. Тем не менее, несмотря на то что особых проблем с чтением/просмотром видео нет — я бы все равно предпочел на русском языке. Успокаиваю себя только тем что эта доп. практика в языке тоже на пользу.
                                                                                                                          +2
                                                                                                                          Материалов на русском в таком количестве и такой же актуальности как на английском никогда не будет, поэтому чем быстрее вы полностью перейдете на англоязычные источники тем лучше будет для вашей дальнейшей программисткой деятельности.
                                                                                                                      0
                                                                                                                      причина отставания от успехов Scala

                                                                                                                      F#, конечно, менее распространен, но и у Scala в последнее время дела идут не очень. Фактически стабильная востребованность есть в одной области (BigData). Надеюсь, выход 3-й версии что-то поменяет.
                                                                                                                        +1
                                                                                                                        Было бы очень интересно писать на F#, но проектов на рынке действительно нет.

                                                                                                                        Предлагать компаниям уже в процессе работы над проектом попробовать F#?
                                                                                                                        — Какое там, если в большинстве случаев нерешаемой «проблемой» является обновление CI для поддержки C# 7 вместо 5 (Карл, 2012-й год!). Какой тут F# (который до недавнего времени еще и свой отдельный рантайм имел).

                                                                                                                        После знакомства с F# действительно начинаешь мыслить и писать на C# по другому.

                                                                                                                        Впрочем, в своем случае «по-другому» я начал еще до изучения F#, самостоятельно доходя до ФП-парадигмы (и речь не только о «лямбдах как стратегиях») — пытаясь действительно эффективно решать задачи и нивелировать недостатки существующих подходов, и уже затем актуализировав выработанные подходы до общепринятой функциональной парадигмы.
                                                                                                                          +2
                                                                                                                          К разделу про информацию можно добавить неплохой блог Марка Симана, в котором за последний год скопилось много постов про идеи из функционального программирования.
                                                                                                                            0

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


                                                                                                                            Или вот сейчас у меня есть мысль разобраться с Xamarin.Forms. Просто так, для эрудиции. Оно мне прямо сейчас не надо, но зато есть примерное представление о том, что я получу в результате. Может быть даже неправильное представление, но оно есть. А с F# его нет, поэтому в процессе выбора, на что потратить свободное время, F# опять со свистом пролетит.


                                                                                                                            Можно тогда о минусах: для каких задач F# (или ФП вообще) плохо подходит или подходит, но решения работают в 10 раз медленнее, чем в процедурщине или ООП?

                                                                                                                              0

                                                                                                                              Сначала все (вообще все) долнжны изучить F# и тогда всё станет магическим образом понятно

                                                                                                                                0

                                                                                                                                В статье четко перечислено, что и как и для чего. И про вебсервера, и про, etl, и про ml и про xamarin. Но не читай @ пиши клиенты.

                                                                                                                                  0

                                                                                                                                  Не поверишь, и читал и специально перечитывал. Все языки сделаны, чтобы абстрагироваться от сложностей, F# не исключительный. Про то что F# хорошо ложится на любые задачи, извините, не верю. При этом хорошо не значит, что лучше других. А если лучше, то лучше кого и чем лучше? Xamarin поддерживает F# ― отлично, а зачем?


                                                                                                                                  Статья типично пустая. Единственная какая-то конкретика только у Романа Мельникова, в небольшом абзаце галопом через запятую. Вот вычеркнуть всё и пусть лучше он расскажет подробнее о своём опыте.

                                                                                                                                  0
                                                                                                                                  С плюсами F# уже стало понятно, что ничего непонятно и объяснить на пальцах никто не может.

                                                                                                                                  Это примерно (но только примерно) как то, когда спрашивают "ну а какие такие плюсы у Kotlin по сравнению с Java? Все это можно же и на Java написать."
                                                                                                                                  Также, как 15 лет назад спрашивали "зачем C#, если есть Delphi и/или C++"


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

                                                                                                                                    0

                                                                                                                                    Как ни странно, представление о Котлине и почему на него может хотеться перейти у меня есть. Примерно такое: Котлин — это то же, что и Ява, только с человеческим лицом; более лаконичное и с бóльшим количеством сахара. Соответственно, позволяет делать всё то же, что и Ява, работает с такой же скоростью, просто удобнее. Ещё более грубо — как если бы перейти с C# 1 на C# 7, а может даже 9.


                                                                                                                                    Причём, в отличие от NET, мир Явы от меня далёк. F# же работает в экосистеме NET, а для меня менее понятен. Не получается думать про про него как про переделанный с нуля и улучшенный вариант C# и что всё, что делается на C#, можно так же легко или даже легче делать на F#. Это ведь не так.


                                                                                                                                    В одной из попыток что-то наконец сделать на F#, пробовал переписать на него с C# кусок кода, который занимался какими-то математическими/геометрическими вычислениями. Исходные данные были в виде типа float/single и в виде структур-векторов и матриц на его основе, результат нужен был во single, всё API использовало single и почему-то это оказалось засадой. Не помню подробностей, давно было, то ли родного типа single в F# тогда не было, то ли вещественных литералов одинарной точности, то ли результаты операций постоянно норовили соскочить из single в double; помню, что постоянно требовалось что-то во что-то кастить и было жутко неудобно и длиннее, чем в исходном C#.


                                                                                                                                    Со скоростью работы непонятно: какие вещи на F# работают быстрее, чем на C#? насколько быстрее, в разы или слегка? какие работают медленнее? (уверен, что такие есть) насколько медленнее, в разы или слегка?


                                                                                                                                    Делал какие-то примитивные тесты для родных для F# коллекций и по времени работы получалось как-то не очень. Может быть, неправильно делал. А чтобы сделать правильно, надо сначала хорошо разобраться в языке. А чтобы разобраться хорошо, сначала надо понять, а зачем? Вдруг конкретно для меня он окажется бесполезен. Т.е. надо послушать людей, которые F# применяют на практике и по опыту расскажут, что в F# хорошо, а что плохо; что делать удобно, что неудобно; что работает быстро, а что медленно. А люди вместо этого рассказывают про какое там классное комьюнити. Да пофиг, какое там комьюнити, вы про сам язык расскажите. Комьюнити будет потом.

                                                                                                                                      0
                                                                                                                                      Примерно такое: F#— это то же, что и C#, только с человеческим лицом; более лаконичное и с бóльшим количеством сахара. Соответственно, позволяет делать всё то же, что и C#, работает с такой же скоростью, просто удобнее. Ещё более грубо — как если бы перейти с Java 1.1 на Java 1.7, а может даже 1.9.

                                                                                                                                      как-то так.
                                                                                                                                      Это верно и здесь.
                                                                                                                                      Да, в F# более сильная типизация и типы надо в литералах явно указывать, но на практике с этим почти не сталкиваешься или пишешь 1f + 0.1 и все ок. )
                                                                                                                                      Спека лучший друг при изучении, а так конечно интуитивно не понятно все новое.
                                                                                                                                      RTFM )
                                                                                                                                        0
                                                                                                                                        Вы хорошо написали про Котлин, но именно по описанным вами причинам на нем есть риск программировать «как на Java», а это неправильно.
                                                                                                                                        У Котлина есть своя парадигма (в основном функциональная), чтобы писать идиоматический код.
                                                                                                                                        Да и ОО-код на нем тоже можно писать «как на Java», и «как на Котлин».
                                                                                                                                        Про это уже не раз писали.

                                                                                                                                        А у F# действительно большие отличия от C#, связанные с тем, что первый — именно функциольны язык, а не мультипарадигменный.

                                                                                                                                        На нем можно писать как на C#, но приходится это делать явно и не очень удобно.
                                                                                                                                        Примерно как на C# можно делать низкоуровневые вещи, но писать для этого fixed (+ синтаксис указателей и их разыменования), (un)checked, требовать для сборки повышенные права, и т.д.

                                                                                                                                        И это хорошо, что F# не позволяет сходу писать как на C#.
                                                                                                                                        Тот же Kotlin, когда/если станет действительно популярным (т.е., когда на нем будут писать не только тесты и вьюшки для Андроида, а нормальный бек), то, вангую, будет проблема — тонны кода в модели Java с синтаксисом Котлин.
                                                                                                                                        Идиоматического Котлин-кода будет исчезающе мало.

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

                                                                                                                                        Ну и возможности общего характера, которых в C# нет и неизвестно, когда завезут.
                                                                                                                                        Те же Discriminated Unions — а в продуктовом коде приходилось много раз встречать код, где разраьботчики что-то велосипедили, хотя Discriminated Unions решили бы вопрос.
                                                                                                                                        В Котлине, к слову, Discriminated Unions нет.

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

                                                                                                                                          Лоу левел вещи (unmanaged и ко) действительно писать не так удобно как на C# (но возможно, и даже stackalloc есть, а недавно и Span завезли), но это даже для C# неидеоматичный код так-то! Для любителей поиграться с поинтерами в менеджд языке сойдёт.


                                                                                                                                          А вот обычный ООП код (интерфейсы, пропертя, классы, абстракные фабрики фабрик синглтонов) писать на нём получается короче чем на C#. Потому что возможностей больше. У меня даже примеры есть)

                                                                                                                                            0
                                                                                                                                            Так было бы очень логично — высокоуровневый ОО- и ФП-код (большинство кода) писать на F#, небольшую часть кода (средний уровень, соответствующий терминам IL) — на идиоматическом C#, а совсем небольшую (unmanaged) — на C# с fixed, указателями, stackalloc и прочим.

                                                                                                                                            Жаль, что такого нет.
                                                                                                                                            Проекты на C# скатываются в легаси с портянками кода, где перемешана предметная логика с техническим бойлерплейт-кодом.
                                                                                                                                      0

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

                                                                                                                                      0
                                                                                                                                      Куклев сильно хвалит F#
                                                                                                                                      akuklev.livejournal.com/1274712.html
                                                                                                                                        0
                                                                                                                                        Тьфу, он хвалит F*
                                                                                                                                          0

                                                                                                                                          Кстати, 0xd34df00d, F* не тыкали?

                                                                                                                                            0
                                                                                                                                            Пока нет, увы. Он у меня в планах, но про него слишком мало хайпа, так что я всё время забываю.
                                                                                                                                        0
                                                                                                                                        F# идеально ложится на разработку ИИ. Этот язык буквально сделан, чтобы абстрагировать меня от сложностей и сосредоточиться на главном. Когда делаешь ИИ, твоя задача отмапить свой образ мышления на поведение машины. В таких кейсах код — ваш промежуточный язык, который не способен выразить слишком сложные вещи. Вот F# способен быть настолько абстрактным, что бы не мешать тебе и твоей машине творить историю.

                                                                                                                                        Примеры написания нейросетей можно глянуть?
                                                                                                                                          +5
                                                                                                                                          Мой опыт: писал на F# когда надо было закодить математические модели, при этом остальной «нематематический» софт компании был на .Net. Математики нам выдавати модели в Matematica, они один к одному ложились на F#, мы даже пытались их научить сразу код писать.
                                                                                                                                          Наша математика на F# выглядела куда логичнее и читаемее, чем на C#, так что смысл был весьма очевиден. Увидел там F# впервые, привык за пару недель, наверное.
                                                                                                                                          Для себя делали формочки для тестирования моделей, куда хуже чем на C#. Логично — не стоит пихать ФП там, где оно не нужно.

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

                                                                                                                                          Самое читаемое