Pull to refresh

Comments 164

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

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

Но я бы не рекомендовал учить F# как первый язык до тех пор, пока общество не удалится от обычных языков также далеко, как от assembly.
Ну, при прочих равных, у F# система типов таки не новейшая и не продвинутейшая.
UFO landed and left these words here
Нет, они есть не для этого. Вернее они увеличивают свободу, но оплачиваешь ты её багами, которые мог бы поймать компайл-тайм. Вот F# — увеличивает свободу, а платишь ты за это — ничем. Вот серьёзно, просто ничем. Это бесплатная свобода!

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

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

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

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


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 работать, просто разные цели ставят перед собой авторы языков.

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

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

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

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

Например, я до 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. На нём я могу решить абсолютно все свои задачи.

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

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

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

Как малый пример «Компилятор сам генерирует кучу бойлерплейта за вас, например, structural equality». Но да, будет круто, если ребята расскажут здесь еще.
UFO landed and left these words here
Это получается, что фшарп все сам генерирует за кулисами? А если мне надо сравнить объекты только по Id?
UFO landed and left these words here

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


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


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

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

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

UFO landed and left these words here
Для Х-М всё же лучше топ-левел-аннотации типов писать, чтобы немножко помочь тайпчекеру помочь вам, когда вы сделали ошибку.
F# для вывода типов использует Алгоритм Хиндли — Милнера, что позволяет в 90% случаев обойтись без явного указания типа, и, в отличие от динамичиских языков сохранить типобезопасность.

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

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

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

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

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


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

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

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

I took a s t a b at lenses.

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

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


var foo;
foo = 10;

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

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

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

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


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


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


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

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

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


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

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

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

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


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

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


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

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

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


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

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


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

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

С чего бы вдруг? Там точно так же мог бы быть 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’

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

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

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

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

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


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

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


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

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


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


  where
    foo :: T
    foo = ...

или даже


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

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

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

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

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

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

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

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

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

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

Порядочные господа определяют отношение порядка отдельно. Можно сравнить их по пищевой ценности, например.
Мир не ограничивается шарпом. Если, скажем, я пишу на Go или Rust?
Почему перспективный? Можно подробнее? Вы в статье пытаетесь «продать» F# другим программистам, хотелось бы больше selling point увидеть. Например, на вопрос «тяжело ли изучать язык» только один человек на него ответил. Остальное пишут «спасибо за дженерики», «умеет все что c#».
UFO landed and left these words here
Если вас абсолютно все устраивает в том языке, на котором вы пишете (C#?), то нет ничего зазорного на нем же и продолжать. Большинство переходящих на F# делают это после многих лет работы на C#, будучи неудовлетворены эффективностью написания на нем кода. Надо просто как-то созреть если не для перехода, то по крайней мере, чтобы попробовать писать код по-другому. К этом прийти никогда не поздно, если у вас для этого сейчас нет причин, то в этом нет ничего страшного.
Не очень понимаю, зачем вы меня успокаиваете, будто я что-то стыдное мог сказать. :)
Основная претензия к статье — в ней нет ответов на вопрос «зачем». Похвалить, как и поругать, можно любой язык, но это делает его обязательно желанным для изучения. Приведу к примеру Go. Очень простой синтаксис (люди начинают что-то ковырять после Go Tour), очень быстрая компиляция, статическая типизация, горутины, каналы, пакеты на все случаи жизни на гитхабе, кроссплатформенность.
Что может предложить F#, кроме иммутабельных типов? Ниже уже тоже писали про сравнение Хаскеля и F#.
Ну я выше привел некоторые мои аргументы «зачем», в частности о том, что еще F# может предложить кроме иммутабельных типов. Плюс в статье есть ссылка на хабровское интервью, где более подробно говорю о причинах. А «успокаиваю» я вас потому, что аргументы у каждого могут быть свои и для других они могут быть неубедительны. Первичным должно быть осознание неффективнсти текущего метода написания кода, желание что-то с этим сделать.
Если вам не понравились или показались неубедительными ответы, которые там дали, это не значит, что их нет.
Очевивидно, есть проблемы с ответами. Если F# так хорош, как вы его описываете, почему его никто не хочет знать? Почему за время его существования другие языки появились из ниоткуда и стали мейнстримом?
UFO landed and left these words here
Хм, в той таблице C# хотят изучать 8%, а F# — 4%. Ruby где-то посередине. По этим цифрам невозможно сделать какой-то фатальный вывод. Да и вообще, если обращаться к цифрам, имеет смысл обращать внимание не на то, что привлекает массовый интерес, а на то, как обстоит с работой и проектами в том, чем хотелось бы заниматься. Если нет вокруг проектов на языке, на котором хотелось бы писать, то это разумный аргумент, чтобы все не бросать и ждать, пока появится. Но и здесь преимущество нашей профессии — что можно что-то изучать в свободное время, дожидаясь возможности это применить. У меня лично года четыре прошло с момента, когда я понял, что мне хочется программировать на F# и стал его потихоньку осваивать, до того, как я смог на нем программировать за деньги. Сейчас, думаю, ситуация значительно улучшилась.
Как-то раз я попросил гуру Джавы и гуру .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 учится за неделю — пример перед глазами), но все еще перспективный, а не популярный.
UFO landed and left these words here
Вы в целом правы, вычеркнул «java» из списка.

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

Любой из вариантов выше даст другой взгляд на программирование. Почему же именно F#?
UFO landed and left these words here
Давайте немного проясним. Почему именно функциональный язык? Почему не низкоуровневый, например? И что такого сакрального в теории групп, что нужно выяснять её точку зрения?
Группы — первый шаг к алгебре, а алгебра — это про структуры, а структуры — это про всё.

Правда, непосредственно теория групп к ФП отношение имеет весьма малое.
UFO landed and left these words here
Полиморфизм нужен, но не тот.
По поводу «никто не знает, что такое каноничный MVC» вспомнился мне коллега, который пытался объяснить что его понимание паттерна — самое верное и view с контроллером обязан взаимодействовать вот так, и никак иначе!
Типичный пример это MVC — никто не знает, что такое каноничный MVC

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

UFO landed and left these words here
Ну, если искать определение функтора не в математической энциклопедии, а в книжках Александреску, тогда — да.

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


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

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

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

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


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

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

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


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

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

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


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

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


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 в хаскеле нет.

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

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

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


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

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


Prelude> :t undefined
undefined :: a
Prelude> 

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

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

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


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

Нет. Дело в том, что у 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.

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

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

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


Более того, вы их не сможете записать, скажем, даже в идрисе. Максимум, который вам доступен — 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.


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

Короче, как завещал Гёдель, в реальности мы упираемся в проблему полноты и противоречивости.
Хотя, интуиция подсказывает, что в Хаскеле и с полнотой могут быть проблемы.
UFO landed and left these words here
В программировании кто угодно может назвать что угодно как угодно. В математике не так

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


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

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


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

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


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

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

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

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

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

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

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


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

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


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

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

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

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

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

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


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

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

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

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

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

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


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


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


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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

Если вы забыли уже то время, когда читали со словарём и не знали толком грамматику, я вам подскажу способ вспомнить — попробуйте почитать что-нибудь на примитивном немецком, например, и, возможно, расстанетесь со своим снобизмом.
Скажем, www.python-kurs.eu
причина отставания от успехов Scala

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

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

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

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

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


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


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

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

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

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


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

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

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


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

Как ни странно, представление о Котлине и почему на него может хотеться перейти у меня есть. Примерно такое: Котлин — это то же, что и Ява, только с человеческим лицом; более лаконичное и с бóльшим количеством сахара. Соответственно, позволяет делать всё то же, что и Ява, работает с такой же скоростью, просто удобнее. Ещё более грубо — как если бы перейти с 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# хорошо, а что плохо; что делать удобно, что неудобно; что работает быстро, а что медленно. А люди вместо этого рассказывают про какое там классное комьюнити. Да пофиг, какое там комьюнити, вы про сам язык расскажите. Комьюнити будет потом.

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

как-то так.
Это верно и здесь.
Да, в F# более сильная типизация и типы надо в литералах явно указывать, но на практике с этим почти не сталкиваешься или пишешь 1f + 0.1 и все ок. )
Спека лучший друг при изучении, а так конечно интуитивно не понятно все новое.
RTFM )
Вы хорошо написали про Котлин, но именно по описанным вами причинам на нем есть риск программировать «как на 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-проектах.
На нем можно писать как на C#, но приходится это делать явно и не очень удобно.

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


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

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

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

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

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

Примеры написания нейросетей можно глянуть?
Мой опыт: писал на F# когда надо было закодить математические модели, при этом остальной «нематематический» софт компании был на .Net. Математики нам выдавати модели в Matematica, они один к одному ложились на F#, мы даже пытались их научить сразу код писать.
Наша математика на F# выглядела куда логичнее и читаемее, чем на C#, так что смысл был весьма очевиден. Увидел там F# впервые, привык за пару недель, наверное.
Для себя делали формочки для тестирования моделей, куда хуже чем на C#. Логично — не стоит пихать ФП там, где оно не нужно.
Only those users with full accounts are able to leave comments. Log in, please.