Comments 164
Вот тоже самое и с F#. Он дает полную свободу, которой не хватает взрослым-сформировавшимся и которая может навредить молодым-неокрепшим разработчикам. Единственное нужно понимать, что синтаксис современных ооп языков в большей степени впитал функциональные возможности. Но их недостаток заключается в слишком слабом определении типов. Объявил класс-интерфейс, вот и тип. В фп языках, существует возможность конструировать типы. Это полностью закрывает все проблемы, которые возникают из-за совместимости типов в других языках. Вы можете строить типы так, что уйдет потребность в приведении вообще, программа сама будет все типы выводить.
— immutability by default, т.е. по умолчанию никакие структуры данных нельзя мутировать.
— type inference, автоматический вывод типов. Вообще сильная типизация позволила мне вытаскивать ошибки кода в основном при компиляции, в C# я на все тесты писал.
— discriminated union для доменного моделирования. Компактно и читабельно.
Но я бы не рекомендовал учить F# как первый язык до тех пор, пока общество не удалится от обычных языков также далеко, как от assembly.
Вопрос тут — почему не хаскель?
Мне тоже очень интересно, в 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 работать, просто разные цели ставят перед собой авторы языков.
Например, я до 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. На нём я могу решить абсолютно все свои задачи.
Конечно сравнение очень субъективное и содержит много неточностей, т.к. я многого не знаю.
Скорее всего упускаю много плюсов и минусов у всех языков и их экосистем.
Но смысл моего комментария не в этом.
Смысл в том, что объективно сравнить два языка практически нереально.
Надо брать и пробовать.
Я конечно понимаю, что я не вынес это все отдельным пунктом с выводами. Но вроде и между строк не зашифровывал.
В интервью Вагифа есть ещё упоминание об этом.
https://m.habr.com/post/424461/
Может быть вам просто попробовать написать и будет понятно где код короче?)
Тут ниже привели хорошую ссылку на A class with custom equality — вроде получается читаемее и короче, чем если то же самое реализовывать на C#.
Но дело в том, что если нужно сравнивать по ID, то, возможно, лучше зайдествовать для этого кастомные компараторы — сегодня нужно по ID, завтра по имени-фамилии (да еще с учетом/без учета культуры/регистра) и т.д.
А "структуры" (не struct, а именно структуры/рекорды в широком смысле) пусть по умолчанию сравниваются по полям "как есть".
Даже после чистки всех автосгенеренных аттрибутов и форматирования все равно счет строк идет на сотни
Там все-таки большая часть — это compare и equals (которые практически никогда не нужны). Вместо тагов можно использовать рефлексию (вообще использования тагов — очень странное решение). На шарпе в любом случае код будет больше, конечно же, но все же разница скорее где-то возле 10 -> 20 строк, а не 10 -> 100.
F# для вывода типов использует Алгоритм Хиндли — Милнера, что позволяет в 90% случаев обойтись без явного указания типа, и, в отличие от динамичиских языков сохранить типобезопасность.
Как выше сказано — топ-левел аннотации порядочные люди все равно пишут, а локальный вывод есть уже ну везде, в том числе и в шарпе.
Как выше сказано — топ-левел аннотации порядочные люди все равно пишут, а локальный вывод есть уже ну везде, в том числе и в шарпе.
Ну локального вывода маловато, достаточно заглянуть на сорсы LINQ, кошмар же. Бойлерплейт ради бойлерплейта и читабельности не добавляют все эти описания дженериков.
Ну локального вывода маловато, достаточно заглянуть на сорсы LINQ, кошмар же. Бойлерплейт ради бойлерплейта и читабельности не добавляют все эти описания дженериков.
Написать монаду для LINQ не проблема, при ее использовании типы прекрасно выводятся.
А другие кейзы мне неинтересны, потому что с реальной практикой не связаны.
и читабельности не добавляют все эти описания дженериков.
На мой взгляд как раз соглашения шарпа по именованию генерик-аргументов — очень полезная штука, по сравнению классическим data K a b c d e f = yoba из хаскеля.
Нет, конечно, корректный тип в данном случае алгоритмически невыводим (точнее, можно вывести только object или dynamic, что бесполезно).
Нет, конечно, корректный тип в данном случае алгоритмически невыводим (точнее, можно вывести только object или dynamic, что бесполезно).
Бред. Алгоритмически он как раз выводим. Хиндли-Мильнер такое пережовывает на раз. Литерал инта есть? Есть. Значит это Int32.
Даже F# справляется.
Если написать так (аналог default из C#), но не указать тип, то заинферится object (справа, едва заметным серым цветом) и вывалится value restriction:
Если добавить присваивание от инта, то естественно алгоритм выведет тип за нас:
Хиндли-Мильнер такое пережовывает на раз.
Хиндли-Милнер такое не пережевывает, потому что Хиндли-Милнер работает для вполне конкретных систем типов. Для каких-либо других систем (например, для системы типа шарпа) Хиндли-Милнер уже неприменим.
Литерал инта есть? Есть. Значит это Int32.
С чего бы вдруг? Там точно так же мог бы быть string иди HurrDurr. То, что должен быть Int32 — вообще ниоткуда не следует. Что будет, если ниже я напишу foo = "fdfdsfd"?
Для каких-либо других систем (например, для системы типа шарпа) Хиндли-Милнер уже неприменим.
Я не уверен что до конца понимаю почему нормальный вывод типов нельзя подключить к C#
С чего бы вдруг? Там точно так же мог бы быть string иди HurrDurr. То, что должен быть Int32 — вообще ниоткуда не следует. Что будет, если ниже я напишу foo = "fdfdsfd"?
Ну если мы о C#, то да, никак.
А вот тот же H-M алгоритм же с бектреком. Все ограничения от литералов и функций он применяет взад) В этом например отличие алгоритма вывода в Scala от HM, она не умеет пропагировать типы по коду выше.
Я не уверен что до конца понимаю почему нормальный вывод типов нельзя подключить к C#
Потому что он уже подключен.
А вот тот же H-M алгоритм же с бектреком. Все ограничения от литералов и функций он применяет взад)
Он не взад применяет, он строит цельную систему уравнений на типы, а потом ее решает. То есть ему просто без разницы, взад или вперед.
В этом например отличие алгоритма вывода в Scala от HM, она не умеет пропагировать типы по коду выше.
Допустим. А чем это плохо?
Почему? Алгоритм же в точности тот же, просто для удобства использования некоторые кейсы специально заблокированы.
Эм, алгоритм в точности тот же, как что?
Тот же как и тот, что выводит не только по принципу "посчитать тип справа от = (что и так должен уметь делать тайпчекер) и распознать ключевое слово var/auto/etc слева".
А вообще непонятное мне удобство какое-то, когда некоторые кейсы специально блокируются.
Ну они плохо работают, потому и блокируются. Чем глубже вывод, тем выше вероятность, что вместо корректного типа (т.е. того, о котором думал программист) будет выведена какашка, в результате чего потом в случае ошибки типов эта ошибка будет показана совсем не там, где она по факту есть.
При этом если, например, в случае глобального вывода можно просто аннотации дописать, то проблемы с таким вот локальным выводом никак не фиксятся, кроме как блоком на уровне самого вывода.
Ну можно локальную аннотацию написать, внезапно.
Можно, конечно, но хороший язык — это тот, что не позволяет писать плохо, а не тот, что позволяет писать хорошо. Ну это как со статической типизацией — ее смысл не в том, что вы можете написать программу, которая чекается, а в том, что не можете написать программу, которая не чекается.
Ну, по опыту переписывания, пусть и с х-ля на плюсы, а не с F# на C#, там таки билже к 10 -> 100.
Зависит от того, как писать. Переписанный "в лоб" код будет действительно сильно длинней в силу своей неидеоматичности. Но это тогда сравнение яблок с бегемотами. Порядочный type soundness господин ведь не станет сравнивать яблоки с бегемотами?
Почему перспективный? Можно подробнее? Вы в статье пытаетесь «продать» F# другим программистам, хотелось бы больше selling point увидеть. Например, на вопрос «тяжело ли изучать язык» только один человек на него ответил. Остальное пишут «спасибо за дженерики», «умеет все что c#».
Основная претензия к статье — в ней нет ответов на вопрос «зачем». Похвалить, как и поругать, можно любой язык, но это делает его обязательно желанным для изучения. Приведу к примеру Go. Очень простой синтаксис (люди начинают что-то ковырять после Go Tour), очень быстрая компиляция, статическая типизация, горутины, каналы, пакеты на все случаи жизни на гитхабе, кроссплатформенность.
Что может предложить F#, кроме иммутабельных типов? Ниже уже тоже писали про сравнение Хаскеля и 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 учится за неделю — пример перед глазами), но все еще перспективный, а не популярный.
По поводу же «другого взгладя»: F# — функциональный язык, PowerShell — интерпретируемый, SharePoint — инфраструктурный с типовыми задачами, Axapta — погружение в Domain, JS — упор на фронт, React — компонентность, Redux — ФП, SQL — тоже своеобразен.
Любой из вариантов выше даст другой взгляд на программирование. Почему же именно F#?
Типичный пример это MVC — никто не знает, что такое каноничный MVC
Для вас может быть новостью, но что такое "каноничный функтор" тоже никто не знает, потому что кодировка может быть любая, никаких стандартных реализаций не существует. На самом деле-то самих функторов в программировании нет, есть некоторые штуки, которые можно считать функторами, причем обычно даже можно считать в определенном приближении. Так что разница с MVC на деле-то и невелика :)
Все это просто определенный вокабуляр, некие идиомы, при помощи которых можно мыслить и получать какой-то полезный результат. И MVC или репозитории ничуть не менее полезный термины, чем монады. Вообще, чем лучше человек знает язык, чем с большим количеством понятий он способен комфортно работать — тем лучше.
Ну, если искать определение функтора не в математической энциклопедии, а в книжках Александреску, тогда — да.
Могу ошибаться, но я насколько помню у Александреску функторы — это совсем не те функторы, что в ФП, разве нет? Просто название случайно совпало.
Идея в том, что современные шаблоны проектирования никак научно не обоснованы — это как алхимия против таблицы Менделеева.
А в каком смысле они должны быть обоснованы? Это просто некоторые решения некоторых проблем, которые часто применяются, и потому "достойны" отдельного названия.
Функторы или монады из теорката обоснованы не в большей мере (и если функторы еще достаточно базовая вещь то монада — это просто интересный объект, то есть мотивация выделения такого объекта в точности соответствует мотивации введения паттернов вроде mvc).
Реализация их нигде и никак не регламентируется (и регламентироваться не может), то есть функтор в хаскеле (или в каком-то другом языке) и функтор в теоркате — это совершенно разные объекты, функторы в хаскеле являются лишь одним из вариантов кодировки теоркатовых да и то условно. И если в том же хаскеле эта условность совсем где-то глубоко зарыта, то в какой-нибудь скале монада Try нарушает монадические законы вполне конкретно. Но все равно монада.
То есть, если объект имеет определённые чётко заданные свойства — мы можем назвать его функтором, из чего следуют всякие полезности, свойственные этим самым функторам.
У того же паттерна MVC нет чётко заданных свойств и нельзя тупо взять, проделать с двумя разными реализациями паттернов одинаковые действия и получить одинаковый результат.
Но я в этих вещах нуб, могу ошибаться.
Насколько понимаю, реализация действительно не регламентируется, зато чётко заданы свойства, из которых следуют различные следствия.
Так я же вам говорю, что:
- эти свойства на практике выполняются весьма условно (с разной степенью условности)
- с-но это объясняет первый пункт — эти свойства в программировании не важны, они там попросту бесполезны. Так уж вышло, что те причины, по которым те же монады интересны в математике — они не интересны в программировании, а те причины, по которым они интересны в программировании — они не интересны в математике.
У того же паттерна MVC нет чётко заданных свойств и нельзя тупо взять, проделать с двумя разными реализациями паттернов одинаковые действия и получить одинаковый результат.
Смотрите, с точки зрения программирования монада (я говорю о монадах, а не о функторах, потмоу что функторы — слишком бессодержательная вещь) — это интерфейс построенный в вокабуляре из пары понятий bind/return, причем семантика bind/return неформализуема.
Если ваши bind/return или какое-то изоморфное представление соответствует такому внутреннему неформалзованному понимаю, то перед вами, с точки зрения программирования, монада, пусть она и не является монадой с точки зрения формально-математической, как Try в скале.
Потому что программисту от монады не нужны монадические свойства, программисту от монады нужен специфический способ композиции, некие принципы, по которым он может построить интерфейс к НЕХ и потом с этой НЕХ работать.
И в этом плане это ничем не отличается от MVC.
Все паттерны (и ФП паттерны и ООП) — это просто некие общие принципы построения интерфейсов, не более и не менее. Просто абстракции, за которые удобно скрывать НЕХ того или иного вида для того, чтобы работать с этой НЕХ тем или иным способом.
Рассмотрим для простоты функтор.
Функтор имеет всего один метод:
fmap :: (a -> b) -> f a -> f b
— то есть, берёт функцию и параметр, обёрнутый во что либо, достаёт параметр, применяет к нему функцию и оборачивает обратно.Также, функтор имеет два свойства:
- если применить fmap к функции id и функтору, то получим тоже самое значение, что получили бы просто применив id к функтору
- если к результату композиции двух функций применить 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. А оно не возвращает.
В программировании кто угодно может назвать что угодно как угодно. В математике не так
Но поскольку мы говорим о программировании — нам совершенно неважно, как там в математике. Там может быть как угодно.
Шаблоны проектирования в ФП имеют основой математику, в то время как шаблоны в ООП, происходят из фольклора.
Ну вот в том и ваша ошибка, шаблоны ФП имеют основой в точности тот же фольклор и точно то же самое происхождение.
Если монады в Scala что-то нарушают, то это можно однозначно определить как нарушение, так как есть источник истины.
Как нарушение чего? Ну определили вы, что в математическом смысле Try — не монада. Но все что нужно программисту от монады — все это в ней есть. По-этому тот факт, что математически она не монада — никому не интересен. Ну то есть это просто забавный бесполезный факт.
Понимаете, допустим я дам строгое математическое определение MVC, при этом все существующие реализации будут MVC "приближенно", ну как те же ФП паттерны являются соответствующими математическими объектами лишь в приближении.
И что? Толку от этого? Чем-то лучше станет кому-то? Что-то изменится? MVC сразу приобретет какие-то особенные свойства? Нет, чем было — тем и останется.
F# — это очень широкий взгляд на программирование.
То есть, возможность написать запрос к google API в 7 строк — это хорошо, но наличие библиотеки googleAPI — лучше.
Спорное утверждение. Использование библиотек помимо очевидных плюсов имеет и ряд минусов. Во-первых, в большинстве случаев библиотеки содержат гораздо больше функционала, чем требуется в конкретном проекте, а это значит, что размер бинарей увеличивается, и кому-то это важно. Во-вторых, изучение библиотеки тоже требует времени, в редких случаях в совокупности больше, чем написание нужного кода своими силами.
В-третьих, библиотека контролируется другой стороной, так что если там есть какой-то баг, который сильно мешает жить — придется подождать.
Если вместо всего этого можно обойтись 7 строчками своего кода — я бы выбрал этот вариант.
У F# есть какие-то «инфраструктурные» преимущества?
О каких инфраструктурных преимуществах идет речь? Набор библиотек такой же, как для C#. Среда разработки та же.
У F# нет решарпера, но так он и не так нужен. У F# ниже дебагабилити, но и дебажить приходится гораздо реже.
Для тех задач, которые может закрыть F# — у разработчика уже есть C#
Верно. Но на F# эти задачи можно решить проще, быстрее и надежнее. Если это для вас не аргумент, тогда мне больше нечего предложить.
Но на F# эти задачи можно решить проще, быстрее и надежнее.Положим, я вам верю. Мой опыт говорит об обратном, но вам я верю. В итоге у C# разработчика ровно тот же выбор: отточить навыки решения тех задач, что он уже умеет решать (через F#), или же посмотреть на инструменты решения других задач.
Тем более, что это даже не будет радикальным изменением, как например, переход на хаскель или го. Это та же платформа с той же инфраструктурой. C# и 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#.
А как подобная безопасность обеспечивается в «настоящей» функциональщине?
Потому что перспективный.
Они вместе с D уже скоро второй десяток лет как в перспективных ходить будут, а воз и ныне там. Единственное его «достоинство», отличающее его от Хаскеля и Скалы — привязка к дотнету. Кому критично, тем, пожалуй, подойдет. На этом его преимущества относительно остальных функциональных языков заканчиваются. А с учетом околонулевой популярности и примерно такого же коммьюнити, проще удариться в те же Хаскель и Скалу. Потому что у первого хотя бы виден прогресс и он от шуточных «8 вакансий на весь мир» дорос до вполне серьезно рассматриваемого языка, а второй еще и привязан к JVM (думаю не стоит сравнивать потребность в JVM и в дотнете на рынке).
Проекты на F# не пишут, потому что программистов на рынке мало, а программисты не учат этот язык, потому что проектов на рынке нет.
Справедливо для всей функциональщины и достаточно, чтобы вообще к ней не прикасаться.
Вагиф работает с ФП на работе, Айрат Работает с ФП. Постепенно все меняется.
Кроме того, развиваться стоит всегда, если хотите не трогать это сейчас, кто знает, вдруг потом будете в догоняющих?
Справедливо для всей функциональщины
Scala вполне имеет свою небольшую нишу. Haskell тоже, но не в наших широтах. Тут он пока выступает в роли 2-3 языка в командах. Т.е. не все так плохо, но и основную ставку на них делать рано.
Фейсбук активно использует хаскель для борьбы со спамом и очень этим доволен. Тут уже несколько раз вспоминали про Вагифа, а ведь у них уже было все написано на C# и они все равно пошли на такой риск для бизнеса, как не просто все переписать, а еще и переписать на другом языке, к тому же, менее популярном. И остались довольны. Насколько я знаю, шведская компания Record Union тоже собиралась переписывать то, что у них есть, с C# на F#. Rust на stackoverflow является самым любимым программистами языком.
Если захотите найти аргументы, чтобы не учить F# или ФП в целом, вы их найдете. Только зачем?
Если вы из C#, то F# отличное поможет постепенно двигаться. Хотя если вы из C#, вы уже немного начали)
Пайпы из ФП проникают js, и rust (на макросах) Опциональные типы в тот же Rust, но уже на уровне языка. Чистое ФП это это как полюс, крайность которая сама по себе редко нужна, так же и с чистым ООП, сейчас почти везде сплав ФП + ООП где то одного больше, где-то
Начал недавно изучать Haskell и очень не хватает какого то списка best practices. Большинство материалов либо учат основам языка, либо их применению, но переход мышления на функциональные рельсы происходит очень медленно, на мой взгляд.
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 самое то. Для этого перечисленных книг вполне достаточно, хотя сдвиг в мышлении не произойдет в одночасье.
Насчёт практической применимости не соглашусь. Уже сейчас пытаюсь использовать его как скриптовый язык для собственных маленьких потребностей.
В этом качестве нравится тем, что можно скомпилить исполняемый файл под любую десктопную платформу, и не нужно потом на целевой машине что то там устанавливать дополнительно.
Раньше пользовал для этой цели Питон, но он не нравится по вышеуказанной причине.
где можно найти материалы для переформатирования сознания в pointfree
Не надо ничего переформатировать. Сложные поинтфри примеры — это цирковая дисциплина, там же, где бесточечная нотация удобна — она и выглядит просто для любого сознания.
Ага, вкурсе про эту штуку.
Мне вообще иногда кажется, что на самом деле хаскелисты пишут сперва нормальный код, понятный, с хорошими неймингами, некоторой долей избиточности (для понимания), вот это вот все. Потом прогоняют такими вот обфускаторами, минификаторами, чтобы выглядело trueъ, и дальше уже коммитят.
Сейчас приобщаюсь потихоньку и ощущения примерно те же что от книги Гради Буча, прочитанной взахлёб ещё в далёком 2003м.
Согласен, пихать pointfree куда ни попадя не очень хорошо. Во всём нужна мера )
Я правильно понял, что, упрощённо говоря, Idris это Хаскель скрещённый с Прологом?
И вообще — кто те люди, которые на нем пишут, и зачем они это делают, если язык не нужен бизнесу?
А вот есть и обратный пример — Cobol, язык бизнесу, по крайней мере западному, нужен, а его никто не изучает, ну или мало кто…
Согласен с вами, что знания английского — это то, без чего и на рынке, и в целом в отрасли придётся плохо. Но давайте не будем за других людей решать, что им делать и как начинать изучать предмет? :)
Если вы забыли уже то время, когда читали со словарём и не знали толком грамматику, я вам подскажу способ вспомнить — попробуйте почитать что-нибудь на примитивном немецком, например, и, возможно, расстанетесь со своим снобизмом.
Скажем, www.python-kurs.eu
причина отставания от успехов Scala
F#, конечно, менее распространен, но и у Scala в последнее время дела идут не очень. Фактически стабильная востребованность есть в одной области (BigData). Надеюсь, выход 3-й версии что-то поменяет.
Предлагать компаниям уже в процессе работы над проектом попробовать 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# более сильная типизация и типы надо в литералах явно указывать, но на практике с этим почти не сталкиваешься или пишешь 1f + 0.1 и все ок. )
Спека лучший друг при изучении, а так конечно интуитивно не понятно все новое.
RTFM )
У Котлина есть своя парадигма (в основном функциональная), чтобы писать идиоматический код.
Да и ОО-код на нем тоже можно писать «как на 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#. Потому что возможностей больше. У меня даже примеры есть)
Жаль, что такого нет.
Проекты на C# скатываются в легаси с портянками кода, где перемешана предметная логика с техническим бойлерплейт-кодом.
Но и критика ваша понятна.
Ограничением F# является то, что это язык, заточенный под инфраструктуру .NET — т.е., на нем писать можно/есть смысл, если по каким-то причинам вы пишите именно под .NET и хотите функциональщины и прочих улучшений в языке и практике работы с платформой.
akuklev.livejournal.com/1274712.html
Кстати, 0xd34df00d, F* не тыкали?
F# идеально ложится на разработку ИИ. Этот язык буквально сделан, чтобы абстрагировать меня от сложностей и сосредоточиться на главном. Когда делаешь ИИ, твоя задача отмапить свой образ мышления на поведение машины. В таких кейсах код — ваш промежуточный язык, который не способен выразить слишком сложные вещи. Вот F# способен быть настолько абстрактным, что бы не мешать тебе и твоей машине творить историю.
Примеры написания нейросетей можно глянуть?
Наша математика на F# выглядела куда логичнее и читаемее, чем на C#, так что смысл был весьма очевиден. Увидел там F# впервые, привык за пару недель, наверное.
Для себя делали формочки для тестирования моделей, куда хуже чем на C#. Логично — не стоит пихать ФП там, где оно не нужно.
Зачем изучать непопулярные языки. Пример сообщества F#